diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index cb5c8a1b6f3..00000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: "[Feature]" -labels: enhancement -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** - - -**Describe the Feature** - - - -**Additional context** - diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000000..1543236ff37 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,39 @@ +name: Feature Request +description: Suggest an idea for this project +title: "[Feature] " +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this feature request! + - type: textarea + id: relation + attributes: + label: Is your feature request related to a problem? Please describe. + description: Clear and concise description of what the problem is. + placeholder: E.g. "I'm always frustrated when [...]" + validations: + required: true + - type: markdown + attributes: + value: | + --- + - type: textarea + id: description + attributes: + label: Describe the Feature + description: A clear and concise description of what you want to happen. Add a link to the feature if it is an existing move/ability/etc. + validations: + required: true + - type: markdown + attributes: + value: | + --- + - type: textarea + id: additional-context + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here. + validations: + required: true diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index e4f1fa5ebf5..acfe341c075 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -5,12 +5,12 @@ ## What are the changes? -## Why am I doing these changes? +## Why am I doing these changes the user will see? -## What did change? +## What are the changes from a developer perspective? @@ -30,6 +30,7 @@ - [ ] The PR is self-contained and cannot be split into smaller PRs? - [ ] Have I provided a clear explanation of the changes? - [ ] Have I considered writing automated tests for the issue? +- [ ] If I have text, did I add placeholders for them in locales? - [ ] Have I tested the changes (manually)? - [ ] Are all unit tests still passing? (`npm run test`) - [ ] Are the changes visual? diff --git a/docs/enemy-ai.md b/docs/enemy-ai.md new file mode 100644 index 00000000000..f53a8511893 --- /dev/null +++ b/docs/enemy-ai.md @@ -0,0 +1,224 @@ +# EnemyCommandPhase: How Enemy Pokémon Decide What to Do + +## Step 1: Should the Enemy Pokémon Switch? + +When battling an enemy Trainer, the first decision the enemy needs to make is whether or not to switch an active Pokémon with another Pokémon in their party. This decision is primarily made by comparing **matchup scores** between each Pokémon in the enemy's party. + +### Calculating Matchup Scores + +The core function for matchup score calculation can be found in `src/field/pokemon.ts`, within the `Pokemon` class: + +```ts +getMatchupScore(pokemon: Pokemon): number; +``` + +This computes the source Pokémon's matchup score against the Pokémon passed by argument using the formula + +$$\text{MUScore} = (\text{atkScore}+\text{defScore}) * \text{hpDiffRatio} $$ + +where +- $\text{atkScore}$ is the combined effectiveness of the source Pokémon's types against the opposing Pokémon's defensive typing: $\prod_{\text{types}} \text{typeEffectiveness}(\text{type}, \text{oppPokemon})$. $\text{typeEffectiveness}$ is 1 when the type deals neutral damage to the opposing Pokémon's defensive typing, 2 when the type deals super effective damage, and so on. $atkScore$ is also increased by 25 percent if the source Pokémon has a higher Speed stat than the opposing Pokémon. +- $\text{defScore}$ is the inverse of the opposing Pokémon's $\text{atkScore}$ against the source Pokémon's defensive typing, or $(\prod_{\text{types}} \text{typeEffectiveness}(\text{type}, \text{sourcePokemon}))^{-1}$. Unlike $\text{atkScore}$, $\text{defScore}$ is capped at a maximum score of 4. +- $\text{hpDiffRatio}= \text{sourceHpRatio}-\text{oppHpRatio}+1$. This is further multiplied by 1.5 if the source Pokémon has a higher Speed stat than the opposing Pokémon; however, $\text{hpDiffRatio}$ cannot be higher than 1. + +The maximum possible matchup score a Pokémon could have against a single opponent is $(16+16)\times 2=64$, which occurs when +- the Pokémon hits its opponent for 4x super effective damage with both of its types. +- the Pokémon is immune to or resists both of the opponent's types by 4x. +- the Pokémon is at max HP while the opponent's HP ratio is near zero. + +In most situations, though, a Pokémon's matchup score against an opponent will be at most 16, which is equivalent to having two super effective types and resisting both of the opponent's types with the same HP ratios as before. + +The minimum possible matchup score a Pokémon could have against a single opponent is near zero, which occurs when the Pokémon's HP ratio is near zero while the opponent is at max HP. However, a Pokémon's matchup score can also be very low when its type(s) are 4x weak to and/or resisted by its opponent's types. + +### Determining Switches in EnemyCommandPhase + +The `EnemyCommandPhase` follows this process to determine whether or not an enemy Pokémon should switch on each turn during a Trainer battle. + +1. If the Pokémon has a move already queued (e.g. they are recharging after using Hyper Beam), or they are trapped (e.g. by Bind or Arena Trap), skip to resolving a `FIGHT` command (see next section). +2. For each Pokémon in the enemy's party, [compute their matchup scores](#calculating-matchup-scores) against the active player Pokémon. If there are two active player Pokémon in the battle, add their matchup scores together. +3. Take the party member with the highest matchup score and apply a multiplier to the score that reduces the score based on how frequently the enemy trainer has switched Pokémon in the current battle. + - The multiplier scales off of a counter that increments when the enemy trainer chooses to switch a Pokémon and decrements when they choose to use a move. +4. Compare the result of Step 3 with the active enemy Pokémon's matchup score. If the party member's matchup score is at least three times that of the active Pokémon, switch to that party member. + - "Boss" trainers only require the party member's matchup score to be at least two times that of the active Pokémon, so they are more likely to switch than other trainers. The full list of boss trainers in the game is as follows: + - All gym leaders, Elite 4 members, and Champions + - All Evil Team leaders + - The last three Rival Fights (on waves 95, 145, and 195) +5. If the enemy decided to switch, send a switch `turnCommand` and end this `EnemyCommandPhase`; otherwise, move on to resolving a `FIGHT` enemy command. + +## Step 2: Selecting a Move + +At this point, the enemy (a wild or trainer Pokémon) has decided against switching and instead will use a move from its moveset. However, it still needs to figure out which move to use and, if applicable, which target to use the move against. The logic for determining an enemy's next move and target is contained within two methods: `EnemyPokemon.getNextMove()` and `EnemyPokemon.getNextTargets()` in `src/field/pokemon.ts`. + +### Choosing a Move with `getNextMove()` + +In `getNextMove()`, the enemy Pokémon chooses a move to use in the following steps: +1. If the Pokémon has a move in its Move Queue (e.g. the second turn of a charging move), and the queued move is still usable, use that move against the given target. +2. Filter out any moves it can't use within its moveset. The remaining moves make up the enemy's **move pool** for the turn. + 1. A move can be unusable if it has no PP left or it has been disabled by another move or effect + 2. If the enemy's move pool is empty, use Struggle. +3. Calculate the **move score** of each move in the enemy's move pool. + 1. A move's move score is equivalent to the move's maximum **target score** among all of the move's possible targets on the field ([more on this later](#calculating-move-and-target-scores)). + 2. A move's move score is set to -20 if at least one of these conditions are met: + - The move is unimplemented (or, more precisely, the move's name ends with " (N)"). + - Conditions for the move to succeed are not met (unless the move is Sucker Punch, Upper Hand, or Thunderclap, as those moves' conditions can't be resolved before the turn starts). + - The move's target scores are 0 or `NaN` for each target. In this case, the game assumes the target score calculation for that move is unimplemented. +4. Sort the move pool in descending order of move scores. +5. From here, the enemy's move selection varies based on its `aiType`. If the enemy is a Boss Pokémon or has a Trainer, it uses the `SMART` AI type; otherwise, it uses the `SMART_RANDOM` AI type. + 1. Let $m_i$ be the *i*-th move in the sorted move pool $M$: + - If `aiType === SMART_RANDOM`, the enemy has a 5/8 chance of selecting $m_0$ and a 3/8 chance of advancing to the next best move $m_1$, where it then repeats this roll. This process stops when a move is selected or the last move in the move pool is reached. + - If `aiType === SMART`, a similar loop is used to decide between selecting the move $m_i$ and advancing to the next iteration with the move $m_{i+1}$. However, instead of using a flat probability, the following conditions need to be met to advance from selecting $m_i$ to $m_{i+1}$: + - $\text{sign}(s_i) = \text{sign}(s_{i+1})$, where $s_i$ is the move score of $m_i$. + - $\text{randInt}(0, 100) < \text{round}(\frac{s_{i+1}}{s_i}\times 50)$. In other words: if the scores of $m_i$ and $m_{i+1}$ have the same sign, the chance to advance to the next iteration with $m_{i+1}$ is proportional to how close the scores are to each other. The probability to advance to the next iteration is at most 50 percent (when $s_i$ and $s_{i+1}$ are equal). +6. The enemy will use the move selected in Step 5 against the target(s) with the highest [**target selection score (TSS)**](#choosing-targets-with-getnexttargets) + +### Calculating Move and Target Scores + +As part of the move selection process, the enemy Pokémon must compute a **target score (TS)** for each legal target for each move in its move pool. The base target score for all moves is a combination of the move's **user benefit score (UBS)** and **target benefit score (TBS)**. + +![equation](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BTS%7D=%5Ctext%7BUBS%7D+%5Ctext%7BTBS%7D%5Ctimes%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D-1&%5Ctext%7Bif%20target%20is%20an%20opponent%7D%5C%5C1&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) + +A move's UBS and TBS are computed with the respective functions in the `Move` class: + +```ts +getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer; +getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer; +``` + +Logically, these functions are very similar – they add up their respective benefit scores from each of the move's attributes (as determined by `attr.getUserBenefitScore`, and `attr.getTargetBenefitScore`, respectively) and return the total benefit score. However, there are two key functional differences in how the UBS and TBS of a move are handled: +1. In addition to influencing move selection, a move's TBS also influences target selection for that move, whereas UBS has no influence. +2. When evaluating the target score of a move against an opposing Pokémon, the move's TBS is multiplied by -1, whereas the move's UBS does not change. For this reason, move attributes return negative values for their TBS to reward using the move against an enemy. + +#### Calculating Target Benefit Score (TBS) for Attack Moves + +In addition to the base score from `Move.getTargetBenefitScore()`, attack moves calculate an `attackScore` which influences the move's TBS based on the following properties: +- The move's power (after the move's `VariablePowerAttrs` are applied) +- The move's type effectiveness against the target (note that this also accounts for type immunities from abilities such as Levitate and field effects such as Strong Winds). +- The move's category (Physical/Special), and whether the user has a higher Attack or Special Attack stat. + +More specifically, the following steps are taken to compute the move's `attackScore`: +1. Compute a multiplier based on the move's type effectiveness: + + ![typeMultEqn](https://latex.codecogs.com/png.image?%5Cdpi%7B110%7D%5Cbg%7Bwhite%7D%5Ctext%7BtypeMult%7D=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D2&&%5Ctext%7Bif%20move%20is%20super%20effective(or%20better)%7D%5C%5C-2&&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) +2. Compute a multiplier based on the move's category and the user's offensive stats: + 1. Compute the user's offensive stat ratio: + + ![statRatioEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BstatRatio%7D=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D%5Cfrac%7B%5Ctext%7BuserSpAtk%7D%7D%7B%5Ctext%7BuserAtk%7D%7D&%5Ctext%7Bif%20move%20is%20physical%7D%5C%5C%5Cfrac%7B%5Ctext%7BuserAtk%7D%7D%7B%5Ctext%7BuserSpAtk%7D%7D&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) + 2. Compute the stat-based multiplier: + + ![statMultEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BstatMult%7D=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D2&%5Ctext%7Bif%20statRatio%7D%5Cle%200.75%5C%5C1.5&%5Ctext%7Bif%5C;%7D0.75%5Cle%5Ctext%7BstatRatio%7D%5Cle%200.875%5C%5C1&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) +3. Calculate the move's `attackScore`: + + $\text{attackScore} = (\text{typeMult}\times \text{statMult})+\lfloor \frac{\text{power}}{5} \rfloor$ + +The maximum total multiplier in `attackScore` ($\text{typeMult}\times \text{statMult}$) is 4, which occurs for attacks that are super effective against the target and are categorically aligned with the user's offensive stats (e.g. the move is physical, and the user has much higher Attack than Sp. Atk). The minimum total multiplier of -4 occurs (somewhat confusingly) for attacks that are not super effective but are categorically aligned with the user's offensive stats. + +The attack move's total TBS, then, is $\text{TBS}=\text{baseScore}-\text{attackScore}$, where $\text{baseScore}$ is the result of `Move.getTargetBenefitScore()`. + +#### Calculating Target Score (TS) for Attack Moves + +The final step to calculate an attack move's target score (TS) is to multiply the base target score by the move's type effectiveness and STAB (if it applies): +- If the target is an enemy, the corresponding TS is multiplied by the move's type effectiveness against the enemy (e.g. 2 if the move is super effective), then by 1.5 if the move shares a type with the user. +- If the target is an ally, the TS is divided by these factors instead. +- If $\text{TS}=0$ after these multipliers are applied, the TS is set to -20 for the current target. + +### Choosing Targets with `getNextTargets()` + +The enemy's target selection for single-target moves works in a very similar way to its move selection. Each potential target is given a **target selection score (TSS)** which is based on the move's [target benefit score](#calculating-move-and-target-scores) for that target: + +![TSSEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BTSS%7D=%5Ctext%7BTBS%7D%5Ctimes%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D-1&%5Ctext%7Bif%20target%20is%20an%20opponent%7D%5C%5C1&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) + +Once the TSS is calculated for each target, the target is selected as follows: +1. Sort the targets (indexes) in decreasing order of their target selection scores (or weights). Let $t_i$ be the index of the *i*-th target in the sorted list, and let $w_i$ be that target's corresponding TSS. +2. Normalize the weights. Let $w_n$ be the lowest-weighted target in the sorted list, then: + + ![normWeightEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7DW_i=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7Dw_i+%7Cw_n%7C&%5Ctext%7Bif%5C;%7Dw_n%5C;%5Ctext%7Bis%20negative%7D%5C%5Cw_i&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.) +3. Remove all weights from the list such that $W_i < \frac{W_0}{2}$ +4. Generate a random integer $R=\text{rand}(0, W_{\text{total}})$ where $W_{\text{total}}$ is the sum of all the remaining weights after Step 3. +5. For each target $(t_i, W_i)$, + 1. if $R \le \sum_{j=0}^{i} W_i$, or if $t_i$ is the last target in the list, **return** $t_i$ + 2. otherwise, advance to the next target $t_{i+1}$ and repeat this check. + +Once the target is selected, the enemy has successfully determined its next action for the turn, and its corresponding `EnemyCommandPhase` ends. From here, the `TurnStartPhase` processes the enemy's commands alongside the player's commands and begins to resolve the turn. + +## An Example in Battle + +Suppose you enter a single battle against an enemy trainer with the following Pokémon in their party: + +1. An [Excadrill](https://bulbapedia.bulbagarden.net/wiki/Excadrill_(Pok%C3%A9mon)) with the Ability Sand Force and the following moveset + 1. Earthquake + 2. Iron Head + 3. Crush Claw + 4. Swords Dance +2. A [Heatmor](https://bulbapedia.bulbagarden.net/wiki/Heatmor_(Pok%C3%A9mon)) with the Ability Flash Fire and the following moveset + 1. Fire Lash + 2. Inferno + 3. Hone Claws + 4. Shadow Claw + +The enemy trainer leads with their Heatmor, and you lead with a [Dachsbun](https://bulbapedia.bulbagarden.net/wiki/Dachsbun_(Pok%C3%A9mon)) with the Ability Well-Baked Body. We'll cover the enemy's behavior over the next two turns. + +### Turn 1 + +To determine whether the enemy should switch Pokémon, it first calculates each party member's matchup scores against the player's Dachsbun: + +$$\text{MUScore} = (\text{atkScore}+\text{defScore}) * \text{hpDiffRatio} $$ +- Defensively, Heatmor's Fire typing resists Dachsbun's Fairy typing, so its `defScore` is 2. However, because of Dachsbun's Fire immunity granted by Well-Baked Body, Heatmor's `atkScore` against Dachsbun is 0. With both Pokémon at maximum HP, Heatmor's total matchup score is 2. +- Excadrill's Steel typing also resists Fairy, so its `defScore` is also 2. In this case, though, Steel is also super effective against Fairy, so Excadrill's base `atkScore` is 2. If Excadrill outspeeds Dachsbun (possibly due to it having a +Spd nature or holding a Carbos), its `atkScore` is further increased to 2.5. Since both Pokémon are at maximum HP, Excadrill's total matchup score is 4 (or 4.5 if it outspeeds). + +Based on the enemy party's matchup scores, whether or not the trainer switches out Heatmor for Excadrill depends on the trainer's type. The difference in matchup scores is enough to cause a switch to Excadrill for boss trainers (e.g. gym leaders) but not for regular trainers. For this example, we'll assume the trainer is a boss and, therefore, decides to switch to Excadrill on this turn. + +### Turn 2 + +Now that the enemy Pokémon with the best matchup score is on the field (assuming it survives Dachsbun's attack on the last turn), the enemy will now decide to have Excadrill use one of its moves. Assuming all of its moves are usable, we'll go through the target score calculations for each move: + +- **Earthquake**: In a single battle, this move is just a 100-power Ground-type physical attack with no additional effects. With no additional benefit score from attributes, the move's base target score against the player's Dachsbun is just the `attackScore` from `AttackMove.getTargetBenefitScore()`. In this case, Earthquake's `attackScore` is given by + + $\text{attackScore}=(\text{typeMult}\times \text{statMult}) + \lfloor \frac{\text{power}}{5} \rfloor = -2\times 2 + 20 = 16$ + + Here, `typeMult` is -2 because the move is not super effective, and `statMult` is 2 because Excadrill's Attack is significantly higher than its Sp. Atk. Accounting for STAB thanks to Excadrill's typing, the final target score for this move is **24** + +- **Iron Head**: This move is an 80-power Steel-type physical attack with an additional chance to cause the target to flinch. With these properties, Iron Head has a user benefit score of 0 and a target benefit score given by + + $\text{TBS}=\text{getTargetBenefitScore(FlinchAttr)}-\text{attackScore}$ + + Under its current implementation, the target benefit score of `FlinchAttr` is -5. Calculating the move's `attackScore`, we get: + + $\text{attackScore}=(\text{typeMult}\times \text{statMult}) + \lfloor \frac{\text{power}}{5} \rfloor = 2\times 2 + 16 = 20$ + + Note that `typeMult` in this case is 2 because Iron Head is super effective (or better) against Dachsbun. With the move's UBS at 0, the base target score calculation against Dachsbun simplifies to + + $\text{TS}=-\text{TBS}=-(-5-20)=25$ + + We then need to apply a 2x multiplier for the move's type effectiveness and a 1.5x multiplier since STAB applies. After applying these multipliers, the final score for this move is **75**. + +- **Swords Dance**: As a non-attacking move, this move's benefit score is derived entirely from the sum of its attributes' benefit scores. Swords Dance's `StatChangeAttr` has a user benefit score of 0 and a target benefit score that, in this case, simplifies to + + $\text{TBS}=4\times \text{levels} + (-2\times \text{sign(levels)})$ + + where `levels` is the number of stat stages added by the attribute (in this case, +2). The final score for this move is **6** (Note: because this move is self-targeted, we don't flip the sign of TBS when computing the target score). + +- **Crush Claw**: This move is a 75-power Normal-type physical attack with a 50 percent chance to lower the target's Defense by one stage. The additional effect is implemented by the same `StatChangeAttr` as Swords Dance, so we can use the same formulas from before to compute the total TBS and base target score. + + $\text{TBS}=\text{getTargetBenefitScore(StatChangeAttr)}-\text{attackScore}$ + + $\text{TBS}=(-4 + 2)-(-2\times 2 + \lfloor \frac{75}{5} \rfloor)=-2-11=-13$ + + $\text{TS}=-\text{TBS}=13$ + + This move is neutral against Dachsbun and isn't boosted by STAB from Excadrill, so we don't need to apply any extra multipliers. The final score for this move is **13**. + +We now have a sorted move pool in decreasing order of move scores: +1. Iron Head (**75**) +2. Earthquake (**24**) +3. Crush Claw (**13**) +4. Swords Dance (**6**) + +Since no other score is at least half that of Iron Head's score, the enemy AI automatically chooses to use Iron Head against Dachsbun at this point. + +## Guidelines for Implementing Benefit Scores + +When implementing a new move attribute, it's important to override `MoveAttr`'s `getUserBenefitScore` and `getTargetBenefitScore` functions to ensure that the enemy AI can accurately determine when and how to use moves with that attribute. Here are a few basic specifications you should adhere to when implementing benefit scores for a new attribute: +- A move's **user benefit score (UBS)** incentivizes (or discourages) the move's usage in general. A positive UBS gives the move more incentive to be used, while a negative UBS gives the move less incentive. +- A move's **target benefit score (TBS)** incentivizes (or discourages) the move's usage on a specific target. A positive TBS indicates the move is better used on the user or its allies, while a negative TBS indicates the move is better used on enemies. +- **The total benefit score (UBS + TBS) of a move should never be 0.** The move selection algorithm assumes the move's benefit score is unimplemented if the total score is 0 and penalizes the move's usage as a result. With status moves especially, it's important to have some form of implementation among the move's attributes to avoid this scenario. +- **Score functions that use formulas should include comments.** If your attribute requires complex logic or formulas to calculate benefit scores, please add comments to explain how the logic works and its intended effect on the enemy's decision making. \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js index d04b7a7176d..de63fbac82e 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,6 +1,7 @@ import tseslint from '@typescript-eslint/eslint-plugin'; +import stylisticTs from '@stylistic/eslint-plugin-ts' import parser from '@typescript-eslint/parser'; -import imports from 'eslint-plugin-import'; +// import imports from 'eslint-plugin-import'; // Disabled due to not being compatible with eslint v9 export default [ { @@ -10,7 +11,8 @@ export default [ parser: parser }, plugins: { - imports: imports.configs.recommended, + // imports: imports.configs.recommended // Disabled due to not being compatible with eslint v9 + '@stylistic/ts': stylisticTs, '@typescript-eslint': tseslint }, rules: { @@ -25,12 +27,12 @@ export default [ "ignoreRestSiblings": true // Allows unused variables that are part of a rest property in object destructuring. Useful for excluding certain properties from an object while using the rest. }], "eol-last": ["error", "always"], // Enforces at least one newline at the end of files - "@typescript-eslint/semi": ["error", "always"], // Requires semicolons for TypeScript-specific syntax + "@stylistic/ts/semi": ["error", "always"], // Requires semicolons for TypeScript-specific syntax "semi": "off", // Disables the general semi rule for TypeScript files "no-extra-semi": ["error"], // Disallows unnecessary semicolons for TypeScript-specific syntax "brace-style": "off", // Note: you must disable the base rule as it can report incorrect errors "curly": ["error", "all"], // Enforces the use of curly braces for all control statements - "@typescript-eslint/brace-style": ["error", "1tbs"], + "@stylistic/ts/brace-style": ["error", "1tbs"], "no-trailing-spaces": ["error", { // Disallows trailing whitespace at the end of lines "skipBlankLines": false, // Enforces the rule even on blank lines "ignoreComments": false // Enforces the rule on lines containing comments diff --git a/index.css b/index.css index 28c991c29b4..be480ab6c78 100644 --- a/index.css +++ b/index.css @@ -33,6 +33,7 @@ body { display: flex; justify-content: space-around; } + #app { display: flex; justify-content: center; @@ -206,6 +207,17 @@ input:-internal-autofill-selected { } } +#tnc-links { + font-size: xx-small; + position: relative; +} + +a { + color: #328cea; + margin-right: 4px; + margin-left: 4px; +} + /* Firefox old*/ @-moz-keyframes blink { 0% { diff --git a/index.html b/index.html index d567eba0866..ebe5b063c52 100644 --- a/index.html +++ b/index.html @@ -114,15 +114,15 @@ + - \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 71de51abb35..0605b299dab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,8 @@ "name": "pokemon-rogue-battle", "version": "1.0.4", "dependencies": { - "@hpcc-js/wasm": "^2.16.2", "@material/material-color-utilities": "^0.2.7", - "@types/jsdom": "^21.1.7", "crypto-js": "^4.2.0", - "dependency-cruiser": "^16.3.3", "i18next": "^23.11.1", "i18next-browser-languagedetector": "^7.2.1", "i18next-korean-postposition-processor": "^1.0.0", @@ -22,26 +19,24 @@ }, "devDependencies": { "@eslint/js": "^9.3.0", + "@hpcc-js/wasm": "^2.18.0", + "@stylistic/eslint-plugin-ts": "^2.6.0-beta.0", + "@types/jsdom": "^21.1.7", "@types/node": "^20.12.13", - "@typescript-eslint/eslint-plugin": "^7.10.0", - "@typescript-eslint/parser": "^7.10.0", - "@vitest/coverage-istanbul": "^1.4.0", - "axios": "^1.6.2", - "axios-cache-interceptor": "^1.3.2", - "eslint": "^8.57.0", - "eslint-plugin-import": "^2.29.1", + "@typescript-eslint/eslint-plugin": "^8.0.0-alpha.54", + "@typescript-eslint/parser": "^8.0.0-alpha.54", + "@vitest/coverage-istanbul": "^2.0.4", + "dependency-cruiser": "^16.3.10", + "eslint": "^9.7.0", "jsdom": "^24.0.0", - "json-beautify": "^1.1.1", "lefthook": "^1.6.12", "phaser3spectorjs": "^0.0.8", - "pokenode-ts": "^1.20.0", "typedoc": "^0.26.4", "typescript": "^5.5.3", - "typescript-eslint": "^7.10.0", - "vite": "^4.5.0", - "vite-plugin-fs": "^0.4.4", + "typescript-eslint": "^8.0.0-alpha.54", + "vite": "^5.3.5", "vite-tsconfig-paths": "^4.3.2", - "vitest": "^1.4.0", + "vitest": "^2.0.4", "vitest-canvas-mock": "^0.3.3" }, "engines": { @@ -53,6 +48,7 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -62,12 +58,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.2", + "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" }, "engines": { @@ -75,30 +72,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", - "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", + "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", - "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", + "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.4", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.4", - "@babel/parser": "^7.24.4", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.9", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-module-transforms": "^7.24.9", + "@babel/helpers": "^7.24.8", + "@babel/parser": "^7.24.8", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.9", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -118,17 +117,19 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz", - "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==", + "version": "7.24.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", + "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.0", + "@babel/types": "^7.24.9", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -138,14 +139,15 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", + "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -158,67 +160,74 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dev": true, "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.0" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", + "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -228,77 +237,83 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz", - "integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", + "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -307,11 +322,89 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/parser": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", - "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.0.tgz", + "integrity": "sha512-CzdIU9jdP0dg7HdyB+bHvDJGagUv+qtzZt5rYCWwW6tITNqV9odjp6Qu41gkG0ca5UfdDUWrKkiAnHHdGRnOrA==", + "dev": true, + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -320,9 +413,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", - "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -331,33 +424,35 @@ } }, "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", + "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.8", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.8", + "@babel/types": "^7.24.8", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -365,14 +460,24 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.0.tgz", + "integrity": "sha512-LcnxQSsd9aXOIgmmSpvZ/1yo46ra2ESYyqLcryaBZOghxy5qqOBjvCWP5JfkI8yl9rlxRgdLTTMCQQRcN2hdCg==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -380,13 +485,14 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" @@ -396,13 +502,14 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -412,13 +519,14 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -428,13 +536,14 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -444,13 +553,14 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -460,13 +570,14 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -476,13 +587,14 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -492,13 +604,14 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -508,13 +621,14 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -524,13 +638,14 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -540,13 +655,14 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -556,13 +672,14 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -572,13 +689,14 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -588,13 +706,14 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -604,13 +723,14 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -620,13 +740,14 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -636,13 +757,14 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -652,13 +774,14 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -668,13 +791,14 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -684,13 +808,14 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" @@ -700,13 +825,14 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -716,13 +842,14 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -732,13 +859,14 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -752,6 +880,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -763,24 +892,65 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "node_modules/@eslint/config-array": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -788,40 +958,82 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, "node_modules/@eslint/js": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.3.0.tgz", - "integrity": "sha512-niBqk8iwv96+yuTwjM6bWg8ovzAPF9qkICsGtcoa5/dmqcEMfdwNAX7+/OHcJHc7wj7XqPxH98oAHytFYlw6Sw==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", + "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@hpcc-js/wasm": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.16.2.tgz", - "integrity": "sha512-THiidUMYR8/cIfFT3MVcWuRE7bQKh295nrFBxGvUNc4Nq8e2uU1LtiplHs7AUkJ0GxgvZoR+8TQ1/E3Qb/uE2g==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.18.0.tgz", + "integrity": "sha512-M9XVIvAXGH4Xcyb5UoiohWcn6fil89pcos/gClNdBZG2v+W48xSf2bjcA8BW131X/AFHUerVY28n1P1Jw81/9A==", + "dev": true, "dependencies": { "yargs": "17.7.2" }, @@ -829,25 +1041,12 @@ "dot-wasm": "bin/dot-wasm.js" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -856,38 +1055,83 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -902,6 +1146,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -911,14 +1156,15 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { @@ -926,6 +1172,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -934,13 +1181,15 @@ "node_modules/@material/material-color-utilities": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/@material/material-color-utilities/-/material-color-utilities-0.2.7.tgz", - "integrity": "sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==" + "integrity": "sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==", + "license": "Apache-2.0" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -954,6 +1203,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -963,6 +1213,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -971,242 +1222,323 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.4.tgz", - "integrity": "sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", + "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.4.tgz", - "integrity": "sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", + "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz", - "integrity": "sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", + "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.4.tgz", - "integrity": "sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", + "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.4.tgz", - "integrity": "sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", + "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.4.tgz", - "integrity": "sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", + "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.4.tgz", - "integrity": "sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", + "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.4.tgz", - "integrity": "sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", + "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.4.tgz", - "integrity": "sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", + "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.4.tgz", - "integrity": "sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", + "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.4.tgz", - "integrity": "sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", + "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz", - "integrity": "sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", + "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.4.tgz", - "integrity": "sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", + "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.4.tgz", - "integrity": "sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", + "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.4.tgz", - "integrity": "sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", + "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.4.tgz", - "integrity": "sha512-YunpoOAyGLDseanENHmbFvQSfVL5BxW3k7hhy0eN4rb3gS/ct75dVD0EXOWIqFT/nE8XYW6LP6vz6ctKRi0k9A==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", + "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@shikijs/core": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.10.3.tgz", - "integrity": "sha512-D45PMaBaeDHxww+EkcDQtDAtzv00Gcsp72ukBtaLSmqRvh0WgGMq3Al0rl1QQBZfuneO75NXMIzEZGFitThWbg==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.12.0.tgz", + "integrity": "sha512-mc1cLbm6UQ8RxLc0dZES7v5rkH+99LxQp/ZvTqV3NLyYsO/fD6JhEflP1H5b2SDq9gI0+0G36AVZWxvounfR9w==", "dev": true, - "license": "MIT", "dependencies": { "@types/hast": "^3.0.4" } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true + "node_modules/@stylistic/eslint-plugin-js": { + "version": "2.6.0-beta.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.6.0-beta.0.tgz", + "integrity": "sha512-KQiNvzNzvl9AmMs1MiIBszLIy/Xy1bTExnyaVy5dSzOF9c+yT64JQfH0p0jP6XpGwoCnZsrPUNflwP30G42QBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "^8.56.10", + "acorn": "^8.12.0", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-js/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@stylistic/eslint-plugin-ts": { + "version": "2.6.0-beta.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.6.0-beta.0.tgz", + "integrity": "sha512-WMz1zgmMC3bvg1L/tiYt5ygvDbTDKlbezoHoX2lV9MnUCAEQZUP4xJ9Wj3jmIKxb4mUuK5+vFZJVcOygvbbqow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@stylistic/eslint-plugin-js": "2.6.0-beta.0", + "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^8.0.0-alpha.34" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.11", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.11.tgz", + "integrity": "sha512-sVBpJMf7UPo/wGecYOpk2aQya2VUGeHhe38WG7/mN5FufNSubf5VT9Uh9Uyp8/eLJpu1/tuhJ/qTo4mhSB4V4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/hast": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/unist": "*" } @@ -1215,22 +1547,26 @@ "version": "21.1.7", "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==", + "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "@types/tough-cookie": "*", "parse5": "^7.0.0" } }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "20.12.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.13.tgz", - "integrity": "sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA==", + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -1238,41 +1574,43 @@ "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/unist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.10.0.tgz", - "integrity": "sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==", + "version": "8.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.0-alpha.58.tgz", + "integrity": "sha512-5G9oIj8jvosj8RTa0VDFXvRmUg1U6FxXJu7ZEfyJYMvFkdMJoY5YnzFvgAvHbYsXOj+YgXZu81fNOTRWQzwk5A==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/type-utils": "7.10.0", - "@typescript-eslint/utils": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/scope-manager": "8.0.0-alpha.58", + "@typescript-eslint/type-utils": "8.0.0-alpha.58", + "@typescript-eslint/utils": "8.0.0-alpha.58", + "@typescript-eslint/visitor-keys": "8.0.0-alpha.58", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1281,26 +1619,27 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.10.0.tgz", - "integrity": "sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==", + "version": "8.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.0-alpha.58.tgz", + "integrity": "sha512-/RpgxIejBui6WXJgV9ukwzxmvbZt5TlfHUGGLB/BsNLj+NRZEbXVtWT9rKuxVOqsGb1Dn9c5gxvBI/XzyuIsMQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/scope-manager": "8.0.0-alpha.58", + "@typescript-eslint/types": "8.0.0-alpha.58", + "@typescript-eslint/typescript-estree": "8.0.0-alpha.58", + "@typescript-eslint/visitor-keys": "8.0.0-alpha.58", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1309,16 +1648,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz", - "integrity": "sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==", + "version": "8.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.0-alpha.58.tgz", + "integrity": "sha512-bGgJXn8B3Pf3mzEOUQTPxEqhux54MOJSqw4HcgBReuP7dudz/hsN4TH9GqHbMXkFv8N4Ed1iqVRfgGeC8b1mGw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0" + "@typescript-eslint/types": "8.0.0-alpha.58", + "@typescript-eslint/visitor-keys": "8.0.0-alpha.58" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1326,26 +1666,24 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.10.0.tgz", - "integrity": "sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==", + "version": "8.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.0-alpha.58.tgz", + "integrity": "sha512-spW/I/UAY6HM0lKj+/333Zb9arOvUoi8+H0cVNYHELPhOti9re9NjyyJFhck84PNiwi8WmpkEf3GXe7/h+Cquw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.10.0", - "@typescript-eslint/utils": "7.10.0", + "@typescript-eslint/typescript-estree": "8.0.0-alpha.58", + "@typescript-eslint/utils": "8.0.0-alpha.58", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -1353,12 +1691,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.10.0.tgz", - "integrity": "sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==", + "version": "8.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.0-alpha.58.tgz", + "integrity": "sha512-6+jM4y31a6pwKeV3MVQuVXPZl6d3I1ySMvP5WjZdZ+n57uovMvasZ3ZJstXngoRpa7JtkjVZ7NrMhQ1J8dxKCQ==", "dev": true, + "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1366,13 +1705,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.10.0.tgz", - "integrity": "sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==", + "version": "8.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0-alpha.58.tgz", + "integrity": "sha512-hm4nsoJnQcA7axMopUJrH7CD0MJhAMtE2zQt65uMFCy+U2YDdKPwE0g6qEAUBoKn6UBLQJWthJgUmwDbWrnwZg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/types": "8.0.0-alpha.58", + "@typescript-eslint/visitor-keys": "8.0.0-alpha.58", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1381,7 +1721,7 @@ "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1393,271 +1733,164 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/utils": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.10.0.tgz", - "integrity": "sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==", + "version": "8.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.0-alpha.58.tgz", + "integrity": "sha512-lZuGnpK23jr3huebgY4/qqrOKsWJ8dX0Q1Fo4oVYcyAy+sK6p+6nObK4VEPJG098gUmrriiavRiDKIhPDFm4Ig==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0" + "@typescript-eslint/scope-manager": "8.0.0-alpha.58", + "@typescript-eslint/types": "8.0.0-alpha.58", + "@typescript-eslint/typescript-estree": "8.0.0-alpha.58" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.10.0.tgz", - "integrity": "sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==", + "version": "8.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0-alpha.58.tgz", + "integrity": "sha512-V//E9PRY2216kh9fN/ihRvTtjpobAXEtmrsr3utlVUwHa2iklcofq1J12yl3KOjx9QBRfBrtfQnYaeruF7L0Fw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/types": "8.0.0-alpha.58", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "node_modules/@vitest/coverage-istanbul": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-1.5.2.tgz", - "integrity": "sha512-YGC+QSWOL8cQ2HQaTEFttmG9v3DGLy7lMZIGdqjtTgaW6omW17/uZPxuh6m2t69T0rFLqImduVthm5o/gYYWTQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-2.0.4.tgz", + "integrity": "sha512-6VibYMkXh8cJm5Bg8JYeOoR4oURlPf4YKP9kuVRE/NKasfYrXPnzSwuxrpgMbgOfPj13KUJXgMB3VAGukECtlQ==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "^4.3.4", + "@istanbuljs/schema": "^0.1.3", + "debug": "^4.3.5", "istanbul-lib-coverage": "^3.2.2", - "istanbul-lib-instrument": "^6.0.1", + "istanbul-lib-instrument": "^6.0.3", "istanbul-lib-report": "^3.0.1", - "istanbul-lib-source-maps": "^5.0.4", - "istanbul-reports": "^3.1.6", - "magicast": "^0.3.3", - "picocolors": "^1.0.0", - "test-exclude": "^6.0.0" + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magicast": "^0.3.4", + "test-exclude": "^7.0.1", + "tinyrainbow": "^1.2.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "1.5.2" + "vitest": "2.0.4" } }, "node_modules/@vitest/expect": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.2.tgz", - "integrity": "sha512-rf7MTD1WCoDlN3FfYJ9Llfp0PbdtOMZ3FIF0AVkDnKbp3oiMW1c8AmvRZBcqbAhDUAvF52e9zx4WQM1r3oraVA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.4.tgz", + "integrity": "sha512-39jr5EguIoanChvBqe34I8m1hJFI4+jxvdOpD7gslZrVQBKhh8H9eD7J/LJX4zakrw23W+dITQTDqdt43xVcJw==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/spy": "1.5.2", - "@vitest/utils": "1.5.2", - "chai": "^4.3.10" + "@vitest/spy": "2.0.4", + "@vitest/utils": "2.0.4", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/expect/node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/@vitest/expect/node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "node_modules/@vitest/pretty-format": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.4.tgz", + "integrity": "sha512-RYZl31STbNGqf4l2eQM1nvKPXE0NhC6Eq0suTTePc4mtMQ1Fn8qZmjV4emZdEdG2NOWGKSCrHZjmTqDCDoeFBw==", "dev": true, + "license": "MIT", "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@vitest/expect/node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@vitest/expect/node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@vitest/expect/node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" + "funding": { + "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.5.2.tgz", - "integrity": "sha512-7IJ7sJhMZrqx7HIEpv3WrMYcq8ZNz9L6alo81Y6f8hV5mIE6yVZsFoivLZmr0D777klm1ReqonE9LyChdcmw6g==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.4.tgz", + "integrity": "sha512-Gk+9Su/2H2zNfNdeJR124gZckd5st4YoSuhF1Rebi37qTXKnqYyFCd9KP4vl2cQHbtuVKjfEKrNJxHHCW8thbQ==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/utils": "1.5.2", - "p-limit": "^5.0.0", - "pathe": "^1.1.1" + "@vitest/utils": "2.0.4", + "pathe": "^1.1.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/runner/node_modules/p-limit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vitest/runner/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@vitest/snapshot": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.5.2.tgz", - "integrity": "sha512-CTEp/lTYos8fuCc9+Z55Ga5NVPKUgExritjF5VY7heRFUfheoAqBneUlvXSUJHUZPjnPmyZA96yLRJDP1QATFQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.4.tgz", + "integrity": "sha512-or6Mzoz/pD7xTvuJMFYEtso1vJo1S5u6zBTinfl+7smGUhqybn6VjzCDMhmTyVOFWwkCMuNjmNNxnyXPgKDoPw==", "dev": true, + "license": "MIT", "dependencies": { - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "pretty-format": "^29.7.0" + "@vitest/pretty-format": "2.0.4", + "magic-string": "^0.30.10", + "pathe": "^1.1.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.2.tgz", - "integrity": "sha512-xCcPvI8JpCtgikT9nLpHPL1/81AYqZy1GCy4+MCHBE7xi8jgsYkULpW5hrx5PGLgOQjUpb6fd15lqcriJ40tfQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.4.tgz", + "integrity": "sha512-uTXU56TNoYrTohb+6CseP8IqNwlNdtPwEO0AWl+5j7NelS6x0xZZtP0bDWaLvOfUbaYwhhWp1guzXUxkC7mW7Q==", "dev": true, + "license": "MIT", "dependencies": { - "tinyspy": "^2.2.0" + "tinyspy": "^3.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.2.tgz", - "integrity": "sha512-sWOmyofuXLJ85VvXNsroZur7mOJGiQeM0JN3/0D1uU8U9bGFM69X1iqHaRXl6R8BwaLY6yPCogP257zxTzkUdA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.4.tgz", + "integrity": "sha512-Zc75QuuoJhOBnlo99ZVUkJIuq4Oj0zAkrQ2VzCqNCx6wAwViHEh5Fnp4fiJTE9rA+sAoXRf00Z9xGgfEzV6fzQ==", "dev": true, + "license": "MIT", "dependencies": { - "diff-sequences": "^29.6.3", + "@vitest/pretty-format": "2.0.4", "estree-walker": "^3.0.3", - "loupe": "^2.3.7", - "pretty-format": "^29.7.0" + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -1669,6 +1902,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1676,12 +1911,16 @@ "node_modules/acorn-jsx-walk": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/acorn-jsx-walk/-/acorn-jsx-walk-2.0.0.tgz", - "integrity": "sha512-uuo6iJj4D4ygkdzd6jPtcxs8vZgDX9YFIkqczGImoypX2fQ4dVImmu3UzA4ynixCIMTrEOWW+95M2HuBaCEOVA==" + "integrity": "sha512-uuo6iJj4D4ygkdzd6jPtcxs8vZgDX9YFIkqczGImoypX2fQ4dVImmu3UzA4ynixCIMTrEOWW+95M2HuBaCEOVA==", + "dev": true, + "license": "MIT" }, "node_modules/acorn-loose": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.4.0.tgz", "integrity": "sha512-M0EUka6rb+QC4l9Z3T0nJEzNOO7JcoJlYMrBlyBCiFSXRyxjLKayd4TbQs2FDRWQU1h9FR7QVNHt+PEaoNL5rQ==", + "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.11.0" }, @@ -1690,9 +1929,13 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -1702,6 +1945,7 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -1710,15 +1954,15 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -1729,160 +1973,57 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -1894,51 +2035,21 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/axios-cache-interceptor": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.5.2.tgz", - "integrity": "sha512-zrJZ9DZo5hKfrU+SEN/qhXxGD7GWRzwoqJ7sSvxikizUvDhWy/U9BoAbWLZZdyjbHHsfmS1OlQZCDW6o69r4DA==", - "dev": true, - "dependencies": { - "cache-parser": "1.2.4", - "fast-defer": "1.1.8", - "object-code": "1.3.3" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/arthurfiorette/axios-cache-interceptor?sponsor=1" - }, - "peerDependencies": { - "axios": "^1" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -1946,6 +2057,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -1954,9 +2066,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", "dev": true, "funding": [ { @@ -1972,11 +2084,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -1985,47 +2098,21 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/cache-content-type": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", - "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", - "dev": true, - "dependencies": { - "mime-types": "^2.1.18", - "ylru": "^1.2.0" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/cache-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.4.tgz", - "integrity": "sha512-O0KwuHuJnbHUrghHi2kGp0SxnWSIBXTYt7M8WVhW0kbPRUNUKoE/Of6e1rRD6AAxmfxFunKnt90yEK09D+sc5g==", - "dev": true - }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -2045,14 +2132,15 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "version": "1.0.30001642", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz", + "integrity": "sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==", "dev": true, "funding": [ { @@ -2067,26 +2155,58 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=12" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" } }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -2096,41 +2216,62 @@ "node": ">=12" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "node": ">=8" } }, - "node_modules/co-body": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/co-body/-/co-body-6.1.0.tgz", - "integrity": "sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==", + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { - "inflation": "^2.0.0", - "qs": "^6.5.2", - "raw-body": "^2.3.3", - "type-is": "^1.6.16" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/combined-stream": { @@ -2138,6 +2279,7 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2149,6 +2291,8 @@ "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", "engines": { "node": ">=18" } @@ -2157,64 +2301,21 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/confbox": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", - "dev": true - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } + "license": "MIT" }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/cookies": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", - "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", "dev": true, - "dependencies": { - "depd": "~2.0.0", - "keygrip": "~1.1.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/copy-to": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz", - "integrity": "sha512-3DdaFaU/Zf1AnpLiFDeNCD4TOWe3Zl2RZaTzUvWiIk5ERzcCodOE20Vqq4fzCbNoHURFHT4/us/Lfq+S2zyY4w==", - "dev": true + "license": "MIT" }, "node_modules/cross-fetch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "license": "MIT", "dependencies": { "node-fetch": "^2.6.12" } @@ -2224,6 +2325,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2236,19 +2338,22 @@ "node_modules/crypto-js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" }, "node_modules/cssfontparser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", "integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cssstyle": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", "dev": true, + "license": "MIT", "dependencies": { "rrweb-cssom": "^0.6.0" }, @@ -2256,11 +2361,18 @@ "node": ">=18" } }, + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, "node_modules/data-urls": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0" @@ -2269,96 +2381,12 @@ "node": ">=18" } }, - "node_modules/data-urls/node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", - "dev": true, - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/data-urls/node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/data-urls/node_modules/whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", - "dev": true, - "dependencies": { - "tr46": "^5.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -2375,24 +2403,31 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", - "dev": true + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -2405,79 +2440,45 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/dependency-cruiser": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-16.3.3.tgz", - "integrity": "sha512-+YHPbd6RqM1nLUUbRVkbYO6mVeeq+VEL+bBkR+KFkYVU20vs1D0TalZ9z/hDLxiYiYCSTctUaoWWaUrRc1I+mw==", + "version": "16.3.10", + "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-16.3.10.tgz", + "integrity": "sha512-WkCnibHBfvaiaQ+S46LZ6h4AR6oj42Vsf5/0Vgtrwdwn7ZekMJdZ/ALoTwNp/RaGlKW+MbV/fhSZOvmhAWVWzQ==", + "dev": true, + "license": "MIT", "dependencies": { - "acorn": "8.11.3", + "acorn": "8.12.1", "acorn-jsx": "5.3.2", "acorn-jsx-walk": "2.0.0", "acorn-loose": "8.4.0", - "acorn-walk": "8.3.2", - "ajv": "8.16.0", - "chalk": "5.3.0", + "acorn-walk": "8.3.3", + "ajv": "8.17.1", "commander": "12.1.0", - "enhanced-resolve": "5.17.0", - "figures": "6.1.0", + "enhanced-resolve": "5.17.1", "ignore": "5.3.1", - "indent-string": "5.0.0", "interpret": "^3.1.1", "is-installed-globally": "1.0.0", "json5": "2.2.3", - "lodash": "4.17.21", "memoize": "10.0.0", + "picocolors": "1.0.1", "picomatch": "4.0.2", "prompts": "2.4.2", "rechoir": "^0.8.0", "safe-regex": "2.1.1", - "semver": "^7.6.2", - "semver-try-require": "7.0.0", + "semver": "^7.6.3", "teamcity-service-messages": "0.1.14", "tsconfig-paths-webpack-plugin": "4.1.0", - "watskeburt": "4.0.2", - "wrap-ansi": "9.0.0" + "watskeburt": "4.1.0" }, "bin": { "depcruise": "bin/dependency-cruise.mjs", @@ -2491,134 +2492,12 @@ "node": "^18.17||>=20" } }, - "node_modules/dependency-cruiser/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/dependency-cruiser/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/dependency-cruiser/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/dependency-cruiser/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/dependency-cruiser/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" - }, - "node_modules/dependency-cruiser/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/dependency-cruiser/node_modules/string-width": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", - "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dependency-cruiser/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/dependency-cruiser/node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -2626,48 +2505,32 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.749", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.749.tgz", - "integrity": "sha512-LRMMrM9ITOvue0PoBrvNIraVmuDbJV5QC9ierz/z5VilMdPOVMjOtpICNld3PuXuTZ3CHH/UPxX9gHhAPwi+0Q==", + "version": "1.4.830", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.830.tgz", + "integrity": "sha512-TrPKKH20HeN0J1LHzsYLs2qwXrp8TF4nHdu4sq61ozGbzMpWhI7iIOPYPPkxeq1azMT9PZ8enPFcftbs/Npcjg==", "dev": true }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, - "engines": { - "node": ">= 0.8" - } + "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -2680,6 +2543,8 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -2687,70 +2552,11 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -2762,68 +2568,18 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -2831,89 +2587,87 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.7.0.tgz", + "integrity": "sha512-FzJ9D/0nGiCGBf8UXO/IGLTgLVzIxze1zpfA8Ton2mjLovXdAPlYDv+MQDcqj3TmrhAGYfOpz9RfR+ent0AgAw==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.17.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.7.0", "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", @@ -2927,130 +2681,24 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -3061,6 +2709,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -3068,134 +2717,103 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { - "type-fest": "^0.20.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": "*" } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -3208,6 +2826,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -3220,6 +2839,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -3229,6 +2849,7 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } @@ -3238,6 +2859,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -3245,13 +2867,15 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -3273,19 +2897,16 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-defer": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.8.tgz", - "integrity": "sha512-lEJeOH5VL5R09j6AA0D4Uvq7AgsHw0dAImQQ+F3iSyHZuAxyQfWobsagGpTcOPvJr3urmKRHrs+Gs9hV+/Qm/Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -3302,6 +2923,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -3313,12 +2935,20 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", "dev": true }, "node_modules/fastq": { @@ -3326,34 +2956,22 @@ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, - "node_modules/figures": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", - "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", - "dependencies": { - "is-unicode-supported": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { @@ -3361,6 +2979,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3373,6 +2992,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -3385,52 +3005,41 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } + "license": "ISC" }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", "dev": true, + "license": "ISC", "dependencies": { - "is-callable": "^1.1.3" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/form-data": { @@ -3438,6 +3047,7 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -3447,27 +3057,13 @@ "node": ">= 6" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3480,33 +3076,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3516,6 +3086,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -3524,26 +3095,18 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-func-name": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -3552,6 +3115,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -3571,6 +3135,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -3578,48 +3143,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -3631,6 +3160,8 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "license": "MIT", "dependencies": { "ini": "4.1.1" }, @@ -3642,28 +3173,16 @@ } }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby": { @@ -3671,6 +3190,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -3690,12 +3210,14 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -3706,36 +3228,31 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -3747,6 +3264,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3758,21 +3276,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3784,6 +3288,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -3796,6 +3301,7 @@ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-encoding": "^3.1.1" }, @@ -3807,51 +3313,15 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", - "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", "dev": true, - "dependencies": { - "deep-equal": "~1.0.1", - "http-errors": "~1.8.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-errors/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } + "license": "MIT" }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -3861,10 +3331,11 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -3878,14 +3349,15 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=16.17.0" } }, "node_modules/i18next": { - "version": "23.11.2", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.2.tgz", - "integrity": "sha512-qMBm7+qT8jdpmmDw/kQD16VpmkL9BdL+XNAK5MNbNFaf1iQQq35ZbPrSlqmnNPOSUY4m342+c0t0evinF5l7sA==", + "version": "23.12.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.12.2.tgz", + "integrity": "sha512-XIeh5V+bi8SJSWGL3jqbTEBW5oD6rbP5L+E7dVQh1MNTxxYef0x15rhJVcRb7oiuq4jLtgy2SD8eFlf6P2cmqg==", "funding": [ { "type": "individual", @@ -3900,6 +3372,7 @@ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" } ], + "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.2" } @@ -3908,14 +3381,15 @@ "version": "7.2.1", "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.2.1.tgz", "integrity": "sha512-h/pM34bcH6tbz8WgGXcmWauNpQupCGr25XPp9cZwZInR9XHSjIFDYp1SIok7zSPsTOMxdvuLyu86V+g2Kycnfw==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.2" } }, "node_modules/i18next-http-backend": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.1.tgz", - "integrity": "sha512-+rNX1tghdVxdfjfPt0bI1sNg5ahGW9kA7OboG7b4t03Fp69NdDlRIze6yXhIbN8rbHxJ8IP4dzRm/okZ15lkQg==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.2.tgz", + "integrity": "sha512-+K8HbDfrvc1/2X8jpb7RLhI9ZxBDpx3xogYkQwGKlWAUXLSEGXzgdt3EcUjLlBCdMwdQY+K+EUF6oh8oB6rwHw==", "dependencies": { "cross-fetch": "4.0.0" } @@ -3924,26 +3398,17 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/i18next-korean-postposition-processor/-/i18next-korean-postposition-processor-1.0.0.tgz", "integrity": "sha512-ruNXjI9awsFK6Ie+F9gYaMW8ciLMuCkeRjH9QkSv2Wb8xI0mnm773v3M9eua8dtvAXudIUk4p6Ho7hNkEASXDg==", + "license": "MIT", "peerDependencies": { "i18next": ">=8.4.0" } }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -3953,6 +3418,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3969,166 +3435,38 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inflation": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.1.0.tgz", - "integrity": "sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "node_modules/ini": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", "dev": true, "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -4142,6 +3480,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4150,30 +3489,18 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -4185,6 +3512,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-1.0.0.tgz", "integrity": "sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==", + "dev": true, + "license": "MIT", "dependencies": { "global-directory": "^4.0.1", "is-path-inside": "^4.0.0" @@ -4200,6 +3529,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4207,47 +3538,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4256,44 +3562,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "node_modules/is-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -4301,99 +3578,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-unicode-supported": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", - "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", - "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -4410,6 +3623,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -4419,32 +3633,12 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-source-maps": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.4.tgz", - "integrity": "sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", @@ -4459,6 +3653,7 @@ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -4467,11 +3662,28 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jest-canvas-mock": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.5.2.tgz", "integrity": "sha512-vgnpPupjOL6+L5oJXzxTxFrlGEIbHdZqFU+LFNdtLxZ3lRDCl17FlTMM7IatoRQkrcyOTMlDinjUguqmQ6bR2A==", "dev": true, + "license": "MIT", "dependencies": { "cssfontparser": "^1.2.1", "moo-color": "^1.0.2" @@ -4481,12 +3693,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -4495,31 +3709,32 @@ } }, "node_modules/jsdom": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.0.0.tgz", - "integrity": "sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz", + "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==", "dev": true, + "license": "MIT", "dependencies": { "cssstyle": "^4.0.1", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.4", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.7", + "nwsapi": "^2.2.10", "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", + "rrweb-cssom": "^0.7.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.3", + "tough-cookie": "^4.1.4", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.16.0", + "ws": "^8.17.0", "xml-name-validator": "^5.0.0" }, "engines": { @@ -4534,45 +3749,12 @@ } } }, - "node_modules/jsdom/node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", - "dev": true, - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/jsdom/node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/jsdom/node_modules/whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", - "dev": true, - "dependencies": { - "tr46": "^5.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -4580,31 +3762,24 @@ "node": ">=4" } }, - "node_modules/json-beautify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/json-beautify/-/json-beautify-1.1.1.tgz", - "integrity": "sha512-17j+Hk2lado0xqKtUcyAjK0AtoHnPSIgktWRsEXgdFQFG9UnaGw6CHa0J7xsvulxRpFl6CrkDFHght1p5ZJc4A==", - "dev": true, - "bin": { - "json-beautify": "bin/json-beautify" - } - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "node_modules/json-stable-stringify": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "isarray": "^2.0.5", @@ -4622,12 +3797,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -4639,27 +3817,17 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "license": "Public Domain", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/keygrip": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", - "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", - "dev": true, - "dependencies": { - "tsscmp": "1.0.6" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -4668,219 +3836,140 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/koa": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", - "integrity": "sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==", - "dev": true, - "dependencies": { - "accepts": "^1.3.5", - "cache-content-type": "^1.0.0", - "content-disposition": "~0.5.2", - "content-type": "^1.0.4", - "cookies": "~0.9.0", - "debug": "^4.3.2", - "delegates": "^1.0.0", - "depd": "^2.0.0", - "destroy": "^1.0.4", - "encodeurl": "^1.0.2", - "escape-html": "^1.0.3", - "fresh": "~0.5.2", - "http-assert": "^1.3.0", - "http-errors": "^1.6.3", - "is-generator-function": "^1.0.7", - "koa-compose": "^4.1.0", - "koa-convert": "^2.0.0", - "on-finished": "^2.3.0", - "only": "~0.0.2", - "parseurl": "^1.3.2", - "statuses": "^1.5.0", - "type-is": "^1.6.16", - "vary": "^1.1.2" - }, - "engines": { - "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" - } - }, - "node_modules/koa-bodyparser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/koa-bodyparser/-/koa-bodyparser-4.4.1.tgz", - "integrity": "sha512-kBH3IYPMb+iAXnrxIhXnW+gXV8OTzCu8VPDqvcDHW9SQrbkHmqPQtiZwrltNmSq6/lpipHnT7k7PsjlVD7kK0w==", - "dev": true, - "dependencies": { - "co-body": "^6.0.0", - "copy-to": "^2.0.1", - "type-is": "^1.6.18" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/koa-compose": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", - "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", - "dev": true - }, - "node_modules/koa-convert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", - "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", - "dev": true, - "dependencies": { - "co": "^4.6.0", - "koa-compose": "^4.1.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/koa-cors": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/koa-cors/-/koa-cors-0.0.16.tgz", - "integrity": "sha512-s15knPxe3AJBi2I/ZMPL0pSqU+PLYLO6k5tI0AqClkzavowvocPlSdFUwaHNqtjHMhsGmiq2tiX/25iILJx9YA==", - "dev": true - }, - "node_modules/koa-router": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-10.1.1.tgz", - "integrity": "sha512-z/OzxVjf5NyuNO3t9nJpx7e1oR3FSBAauiwXtMQu4ppcnuNZzTaQ4p21P8A6r2Es8uJJM339oc4oVW+qX7SqnQ==", - "deprecated": "**IMPORTANT 10x+ PERFORMANCE UPGRADE**: Please upgrade to v12.0.1+ as we have fixed an issue with debuglog causing 10x slower router benchmark performance, see https://github.com/koajs/router/pull/173", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "http-errors": "^1.7.3", - "koa-compose": "^4.1.0", - "methods": "^1.1.2", - "path-to-regexp": "^6.1.0" - }, - "engines": { - "node": ">= 8.0.0" - } - }, "node_modules/lefthook": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/lefthook/-/lefthook-1.6.12.tgz", - "integrity": "sha512-SoHhB0L1D5twH5KKsGAT1h4qF+RhGfPo/JC5z60H0RDuFWtSwFNOeFpT4Qa7XwM6J9c1fvqZzOH9/4XF7dG9Uw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/lefthook/-/lefthook-1.7.4.tgz", + "integrity": "sha512-lVv3nKH9l3KMDS3bySROvWJSw1+AsBHUO7xaA0rg1IEBZrj3+ePmM+a8elX+GU3Go1OzsZEYjo5AOOeLoZ7FQg==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "lefthook": "bin/index.js" }, "optionalDependencies": { - "lefthook-darwin-arm64": "1.6.12", - "lefthook-darwin-x64": "1.6.12", - "lefthook-freebsd-arm64": "1.6.12", - "lefthook-freebsd-x64": "1.6.12", - "lefthook-linux-arm64": "1.6.12", - "lefthook-linux-x64": "1.6.12", - "lefthook-windows-arm64": "1.6.12", - "lefthook-windows-x64": "1.6.12" + "lefthook-darwin-arm64": "1.7.4", + "lefthook-darwin-x64": "1.7.4", + "lefthook-freebsd-arm64": "1.7.4", + "lefthook-freebsd-x64": "1.7.4", + "lefthook-linux-arm64": "1.7.4", + "lefthook-linux-x64": "1.7.4", + "lefthook-windows-arm64": "1.7.4", + "lefthook-windows-x64": "1.7.4" } }, "node_modules/lefthook-darwin-arm64": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-1.6.12.tgz", - "integrity": "sha512-IJa50i+78nGxtSvnxLSDfSjBjjM7Ixl03V4+yl3Kdn+S+FwzEZet3LYTLbnKFUVy9Bg23obI3yXgwUx+tJjFXg==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-1.7.4.tgz", + "integrity": "sha512-6XpenaP0W7ZYA3lhHey/C1U+KmYz6eCq2cGswQsrTX+xdtHdWW3NbbOKngxATRTF8+CtF6m9UB2afP7qqkCghQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/lefthook-darwin-x64": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-1.6.12.tgz", - "integrity": "sha512-h11ByUtwM78FShgWgSUyyZtwKW6pjYfYvTygw24c/lZXKjupfowK5Ps5A73hCsjr0AEJNVpgW1S5Jd22gIJJCA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-1.7.4.tgz", + "integrity": "sha512-lpQXbPMHiaWE7+9fV+spjuMKiZ3J/+oI6hY1/l48MO3LmSpIv6DNy0VHho1fZVQnHdBU4bDh5c1G0r1f5T0irg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/lefthook-freebsd-arm64": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-1.6.12.tgz", - "integrity": "sha512-Aw1+AosL8r/LFSVKG7i8GI1FpHnWFG66/6DBDUgCwNAwhNCXt7tERAM8dj9S6EqmqHCQCC0nI/6qKNBsFPk7Ow==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-1.7.4.tgz", + "integrity": "sha512-wv+JZgkD1/wi4X5aKKNodvxNcFcYmvL7uyzKkbtd/LgX5ssh9r5pO9J/71ULGtEuTXH4kqORRtez7u/ygqMEew==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ] }, "node_modules/lefthook-freebsd-x64": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-1.6.12.tgz", - "integrity": "sha512-G8Dg7UuRstXrqaEA8MSOZikz6PpjPUQu3QmiihzcyGdzI76jFsmjJb2vkrnvMsH9u2gWb3J4sp3TULhbMHXwSw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-1.7.4.tgz", + "integrity": "sha512-xoYR0Ay8pbyY9W9mI+iI9VDkkCVYSXhMf9XyOChSlu2XmjKiqi23hjCXvSOpvHQ7jphGvAVpE3Byijr6Xjuihw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ] }, "node_modules/lefthook-linux-arm64": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-1.6.12.tgz", - "integrity": "sha512-fwO0i6x5EPelL66EwaySzGzvVbN2vLFZDUWuTi8nZzEgBsCBuG0mORxZg91cNCGLRPT3sgzWPraTkyzIJa7kHg==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-1.7.4.tgz", + "integrity": "sha512-WvXWzSM/e08n2f5lcC8j+pUMS0RzZftJK4zuBQ36TstSYXfBjWiw+FMnKCVZk6Q8Zc0icyF8sTmKQAyKCgX+UA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/lefthook-linux-x64": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/lefthook-linux-x64/-/lefthook-linux-x64-1.6.12.tgz", - "integrity": "sha512-pRAZKZhSoirjRwDF0TrqxgkeXtUmJqaUi0kGmMJmutToqo9IXQcnpueVmyV9Z1m6lLJn4PpKoFydY6tFXqvyNQ==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/lefthook-linux-x64/-/lefthook-linux-x64-1.7.4.tgz", + "integrity": "sha512-eR5NxGzqPJm3wDTm4HStwGxOZ8Omb0ooodyuQdEOxtYidLrd4U18N14huwCEFd3BAOrjIWYV8plH+ReTZE56eg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/lefthook-windows-arm64": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-1.6.12.tgz", - "integrity": "sha512-jMMIoqNKtiqGrwyWeN3JXGXi7H7iAXsGB5v4DkcUbdw9y50qhruxWz84I2PoxwYmZVeMxRR+VpYvS7nOvBmzWA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-1.7.4.tgz", + "integrity": "sha512-C+MdHH+0ylermetMHwfHsYYNI5HI6QEOx7N4Iw4Ea6c3Yuj3eG3LsAzrhsup7KLSSBmDgIHOCJUx/Mfh2z+ATw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/lefthook-windows-x64": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-1.6.12.tgz", - "integrity": "sha512-XqEBVIhp/Fd1Fs+VBlPhrSJlUkyXEJuxQmiYSYow3C18RNpQQrJFVFpz0wE/IDTn2jOXx+p5+hcdlJb+s6bnpA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-1.7.4.tgz", + "integrity": "sha512-BDQhiRzmMYPFQFtVtkRfUfeZuSlemG1oJfGKYXlCGFskvK9Jm1nGFnG0Ig63FAQaFdW33DFoLdr9ZKFTUQeSwQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -4891,6 +3980,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -4904,32 +3994,16 @@ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, - "license": "MIT", "dependencies": { "uc.micro": "^2.0.0" } }, - "node_modules/local-pkg": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", - "dev": true, - "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -4940,22 +4014,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", "dev": true, + "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" } @@ -4965,6 +4036,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } @@ -4973,15 +4045,17 @@ "version": "2.3.9", "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/magicast": { @@ -4989,6 +4063,7 @@ "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.4.tgz", "integrity": "sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.24.4", "@babel/types": "^7.24.0", @@ -5000,6 +4075,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -5015,7 +4091,6 @@ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -5032,22 +4107,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true, - "license": "MIT" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } + "dev": true }, "node_modules/memoize": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/memoize/-/memoize-10.0.0.tgz", "integrity": "sha512-H6cBLgsi6vMWOcCpvVCdFFnl3kerEXbrYh9q+lY6VXvQSmM6CkmV08VOwT+WE2tzIEqRPFfAq3fm4v/UIW6mSA==", + "dev": true, + "license": "MIT", "dependencies": { "mimic-function": "^5.0.0" }, @@ -5062,44 +4129,52 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.6.tgz", - "integrity": "sha512-Y4Ypn3oujJYxJcMacVgcs92wofTHxp9FzfDpQON4msDefoC0lb3ETvQLOdLcbhSwU1bz8HrL/1sygfBIHudrkQ==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", - "picomatch": "^4.0.2" + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -5109,6 +4184,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -5121,6 +4197,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5132,6 +4209,8 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -5140,35 +4219,39 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mlly": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", - "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.0.3", - "ufo": "^1.3.2" + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/moo-color": { @@ -5176,26 +4259,23 @@ "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz", "integrity": "sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "^1.1.4" } }, - "node_modules/moo-color/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/mustache": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", "bin": { "mustache": "bin/mustache" } @@ -5211,6 +4291,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -5222,21 +4303,14 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, - "engines": { - "node": ">= 0.6" - } + "license": "MIT" }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -5252,10 +4326,29 @@ } } }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.17.tgz", + "integrity": "sha512-Ww6ZlOiEQfPfXM45v17oabk77Z7mg5bOt7AjDyzy7RjK9OrLrLC8dyZQoAPEOtFX9SaNf1Tdvr5gRJWdTJj7GA==", "dev": true }, "node_modules/npm-run-path": { @@ -5263,6 +4356,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -5278,6 +4372,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5286,127 +4381,26 @@ } }, "node_modules/nwsapi": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", - "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", + "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", "dev": true }, - "node_modules/object-code": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/object-code/-/object-code-1.3.3.tgz", - "integrity": "sha512-/Ds4Xd5xzrtUOJ+xJQ57iAy0BZsZltOHssnDgcZ8DOhgh41q1YJCnTPnWdWSLkNGNnxYzhYChjc5dgC9mEERCA==", - "dev": true - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, "node_modules/onetime": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^4.0.0" }, @@ -5417,17 +4411,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/only": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", - "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==", - "dev": true - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -5445,6 +4434,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -5460,6 +4450,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -5470,16 +4461,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/papaparse": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz", - "integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw==" + "integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw==", + "license": "MIT" }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -5491,6 +4491,8 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "license": "MIT", "dependencies": { "entities": "^4.4.0" }, @@ -5498,38 +4500,22 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5537,19 +4523,40 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" }, - "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5558,24 +4565,36 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } }, "node_modules/phaser": { "version": "3.80.1", "resolved": "https://registry.npmjs.org/phaser/-/phaser-3.80.1.tgz", "integrity": "sha512-VQGAWoDOkEpAWYkI+PUADv5Ql+SM0xpLuAMBJHz9tBcOLqjJ2wd8bUhxJgOqclQlLTg97NmMd9MhS75w16x1Cw==", + "license": "MIT", "dependencies": { "eventemitter3": "^5.0.1" } }, "node_modules/phaser3-rex-plugins": { - "version": "1.80.2", - "resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.80.2.tgz", - "integrity": "sha512-ZPA4c47WQRU6rqLdlOFizGU+ljtP4C2blhcpbYSsNMqNRHD7o8vRBEzEhl8w6CMGvcy+eVoA6v10cyL4eIZARw==", + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.80.5.tgz", + "integrity": "sha512-hdL3Cm6dK72w6phQdGnEiqqntlwT8SvjU0yit7DkdqiPy/Io1g3KnsRFqndtY+Hu69zaMEuckpIVeQK6yVwx4A==", "dependencies": { "eventemitter3": "^3.1.2", "i18next": "^22.5.1", - "i18next-http-backend": "^2.5.0", + "i18next-http-backend": "^2.5.2", "js-yaml": "^4.1.0", "mustache": "^4.2.0", "papaparse": "^5.4.1", @@ -5585,7 +4604,8 @@ "node_modules/phaser3-rex-plugins/node_modules/eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "license": "MIT" }, "node_modules/phaser3-rex-plugins/node_modules/i18next": { "version": "22.5.1", @@ -5605,6 +4625,7 @@ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" } ], + "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.6" } @@ -5613,18 +4634,21 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/phaser3spectorjs/-/phaser3spectorjs-0.0.8.tgz", "integrity": "sha512-0dSO7/aMjEUPrp5EcjRvRRsEf+jXDbmzalPeJ6VtTB2Pn1PeaKc+qlL/DmO3l1Dvc5lkzc+Sil1Ta+Hkyi5cbA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "node_modules/picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5632,33 +4656,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pkg-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz", - "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==", - "dev": true, - "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.6.1", - "pathe": "^1.1.2" - } - }, - "node_modules/pokenode-ts": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/pokenode-ts/-/pokenode-ts-1.20.0.tgz", - "integrity": "sha512-6MekrbiQc9nmaZJ5xpyhRSEMFo4xEsMuB7RR3EqfPvuXo/3StnH1p4brfIiIWDCcZvu7t9a0vjodiR4TnRdLEw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/Gabb-c/pokenode-ts?sponsor=1" - }, - "peerDependencies": { - "axios": "^1.4.0", - "axios-cache-interceptor": "^1.2.0" - } - }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -5669,9 +4666,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "dev": true, "funding": [ { @@ -5687,9 +4684,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -5701,40 +4699,17 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -5743,22 +4718,18 @@ "node": ">= 6" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { "node": ">=6" } @@ -5768,31 +4739,16 @@ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/qs": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", - "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -5814,68 +4770,12 @@ } ] }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/raw-body/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/react-is": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.0.tgz", - "integrity": "sha512-wRiUsea88TjKDc4FBEn+sLvIDesp6brMbGWnJGjew2waAc9evdhja/2LvePc898HJbHw0L+MTWy7NhpnELAvLQ==", - "dev": true - }, "node_modules/rechoir": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", "dependencies": { "resolve": "^1.20.0" }, @@ -5886,38 +4786,25 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/regexp-tree": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "license": "MIT", "bin": { "regexp-tree": "bin/regexp-tree" } }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5926,6 +4813,8 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5934,12 +4823,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -5957,6 +4849,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5966,46 +4859,51 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/rollup": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", + "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "@types/estree": "1.0.5" }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", - "dev": true, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.1", + "@rollup/rollup-android-arm64": "4.18.1", + "@rollup/rollup-darwin-arm64": "4.18.1", + "@rollup/rollup-darwin-x64": "4.18.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", + "@rollup/rollup-linux-arm-musleabihf": "4.18.1", + "@rollup/rollup-linux-arm64-gnu": "4.18.1", + "@rollup/rollup-linux-arm64-musl": "4.18.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", + "@rollup/rollup-linux-riscv64-gnu": "4.18.1", + "@rollup/rollup-linux-s390x-gnu": "4.18.1", + "@rollup/rollup-linux-x64-gnu": "4.18.1", + "@rollup/rollup-linux-x64-musl": "4.18.1", + "@rollup/rollup-win32-arm64-msvc": "4.18.1", + "@rollup/rollup-win32-ia32-msvc": "4.18.1", + "@rollup/rollup-win32-x64-msvc": "4.18.1", "fsevents": "~2.3.2" } }, "node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", "dev": true }, "node_modules/run-parallel": { @@ -6027,84 +4925,34 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/safe-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "license": "MIT", "dependencies": { "regexp-tree": "~0.1.1" } }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, + "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" }, @@ -6113,9 +4961,10 @@ } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -6123,21 +4972,11 @@ "node": ">=10" } }, - "node_modules/semver-try-require": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver-try-require/-/semver-try-require-7.0.0.tgz", - "integrity": "sha512-LI7GzDuAZmNKOY0/LY4nB3ifh6kYMvBimFTHVpA6wNEl3gw59QrLbTAnJb7vQzPd1qXPz+BtKJZaYORXWMerrA==", - "dependencies": { - "semver": "^7.6.0" - }, - "engines": { - "node": "^18.17||>=20" - } - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -6150,32 +4989,12 @@ "node": ">= 0.4" } }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -6188,50 +5007,34 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shiki": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.10.3.tgz", - "integrity": "sha512-eneCLncGuvPdTutJuLyUGS8QNPAVFO5Trvld2wgEq1e002mwctAhJKeMGWtWVXOIEzmlcLRqcgPSorR6AVzOmQ==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.12.0.tgz", + "integrity": "sha512-BuAxWOm5JhRcbSOl7XCei8wGjgJJonnV0oipUupPY58iULxUGyHhW5CF+9FRMuM1pcJ5cGEJGll1LusX6FwpPA==", "dev": true, - "license": "MIT", "dependencies": { - "@shikijs/core": "1.10.3", + "@shikijs/core": "1.12.0", "@types/hast": "^3.0.4" } }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -6242,13 +5045,16 @@ "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6258,6 +5064,7 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -6266,27 +5073,41 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, - "engines": { - "node": ">= 0.6" - } + "license": "MIT" }, "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -6296,59 +5117,62 @@ "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, + "license": "MIT" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -6360,6 +5184,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -6369,6 +5195,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6381,6 +5208,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -6388,40 +5216,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", - "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", - "dev": true, - "dependencies": { - "js-tokens": "^9.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", - "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", - "dev": true - }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6433,12 +5245,15 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -6446,48 +5261,86 @@ "node_modules/teamcity-service-messages": { "version": "0.1.14", "resolved": "https://registry.npmjs.org/teamcity-service-messages/-/teamcity-service-messages-0.1.14.tgz", - "integrity": "sha512-29aQwaHqm8RMX74u2o/h1KbMLP89FjNiMxD9wbF2BbWOnbM+q+d1sCEC+MqCc4QW3NJykn77OMpTFw/xTHIc0w==" + "integrity": "sha512-29aQwaHqm8RMX74u2o/h1KbMLP89FjNiMxD9wbF2BbWOnbM+q+d1sCEC+MqCc4QW3NJykn77OMpTFw/xTHIc0w==", + "dev": true, + "license": "MIT" }, "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "glob": "^10.4.1", + "minimatch": "^9.0.4" }, "engines": { - "node": ">=8" + "node": ">=18" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tinybench": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tinypool": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", - "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.0.tgz", + "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==", "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } }, "node_modules/tinyspy": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", + "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -6497,6 +5350,7 @@ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -6506,6 +5360,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -6513,20 +5368,12 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -6538,15 +5385,23 @@ } }, "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -6555,10 +5410,11 @@ } }, "node_modules/tsconfck": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.0.tgz", - "integrity": "sha512-CMjc5zMnyAjcS9sPLytrbFmj89st2g+JYtY/c02ug4Q+CZaAtCgbyviI0n1YvjZE/pzoc6FbNsINS13DOL1B9w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.1.tgz", + "integrity": "sha512-00eoI6WY57SvZEVjm13stEVE90VkEdJAFGgpFLTsZbJyW/LwFQ7uQxJHWpZ2hzSWgCPKc9AnBnNP+0X7o3hAmQ==", "dev": true, + "license": "MIT", "bin": { "tsconfck": "bin/tsconfck.js" }, @@ -6574,22 +5430,12 @@ } } }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, "node_modules/tsconfig-paths-webpack-plugin": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz", "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==", + "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.7.0", @@ -6599,74 +5445,12 @@ "node": ">=10.13.0" } }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/tsconfig-paths-webpack-plugin/node_modules/tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -6676,32 +5460,12 @@ "node": ">=6" } }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsscmp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", - "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", - "dev": true, - "engines": { - "node": ">=0.6.x" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -6709,119 +5473,11 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typedoc": { - "version": "0.26.4", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.4.tgz", - "integrity": "sha512-FlW6HpvULDKgc3rK04V+nbFyXogPV88hurarDPOjuuB5HAwuAlrCMQ5NeH7Zt68a/ikOKu6Z/0hFXAeC9xPccQ==", + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.5.tgz", + "integrity": "sha512-Vn9YKdjKtDZqSk+by7beZ+xzkkr8T8CYoiasqyt4TTRFy5+UHzL/mF/o4wGBjRF+rlWQHDb0t6xCpA3JNL5phg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "lunr": "^2.3.9", "markdown-it": "^14.1.0", @@ -6839,38 +5495,11 @@ "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x" } }, - "node_modules/typedoc/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/typedoc/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6880,25 +5509,23 @@ } }, "node_modules/typescript-eslint": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.10.0.tgz", - "integrity": "sha512-thO8nyqptXdfWHQrMJJiJyftpW8aLmwRNs11xA8pSrXneoclFPstQZqXvDWuH1WNL4CHffqHvYUeCHTit6yfhQ==", + "version": "8.0.0-alpha.58", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.0.0-alpha.58.tgz", + "integrity": "sha512-0mvrodNhExpkWns+5RaZP8YqsAfPyjmPVVM1p+kaJkvApMH58/VFcQ0iSQuun0bFRNCMvW0ZUdulS9AsHqVXkg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "7.10.0", - "@typescript-eslint/parser": "7.10.0", - "@typescript-eslint/utils": "7.10.0" + "@typescript-eslint/eslint-plugin": "8.0.0-alpha.58", + "@typescript-eslint/parser": "8.0.0-alpha.58", + "@typescript-eslint/utils": "8.0.0-alpha.58" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -6909,57 +5536,29 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true, - "license": "MIT" - }, - "node_modules/ufo": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", - "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", "dev": true }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "license": "MIT" }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -6975,9 +5574,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -6990,6 +5590,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -6999,44 +5600,37 @@ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dev": true, + "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/vite": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", - "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", + "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "esbuild": "^0.21.3", + "postcss": "^8.4.39", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", @@ -7069,15 +5663,16 @@ } }, "node_modules/vite-node": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.5.2.tgz", - "integrity": "sha512-Y8p91kz9zU+bWtF7HGt6DVw2JbhyuB2RlZix3FPYAYmUyZ3n7iTp8eSyLyY6sxtPegvxQtmlTMhfPhUfCUF93A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.4.tgz", + "integrity": "sha512-ZpJVkxcakYtig5iakNeL7N3trufe3M6vGuzYAr4GsbCTwobDeyPJpE4cjDhhPluv8OvQCFzu2LWp6GkoKRITXA==", "dev": true, + "license": "MIT", "dependencies": { "cac": "^6.7.14", - "debug": "^4.3.4", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", + "debug": "^4.3.5", + "pathe": "^1.1.2", + "tinyrainbow": "^1.2.0", "vite": "^5.0.0" }, "bin": { @@ -7090,506 +5685,12 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/vite-node/node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "node_modules/vite-node/node_modules/rollup": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.16.4.tgz", - "integrity": "sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.16.4", - "@rollup/rollup-android-arm64": "4.16.4", - "@rollup/rollup-darwin-arm64": "4.16.4", - "@rollup/rollup-darwin-x64": "4.16.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.16.4", - "@rollup/rollup-linux-arm-musleabihf": "4.16.4", - "@rollup/rollup-linux-arm64-gnu": "4.16.4", - "@rollup/rollup-linux-arm64-musl": "4.16.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.16.4", - "@rollup/rollup-linux-riscv64-gnu": "4.16.4", - "@rollup/rollup-linux-s390x-gnu": "4.16.4", - "@rollup/rollup-linux-x64-gnu": "4.16.4", - "@rollup/rollup-linux-x64-musl": "4.16.4", - "@rollup/rollup-win32-arm64-msvc": "4.16.4", - "@rollup/rollup-win32-ia32-msvc": "4.16.4", - "@rollup/rollup-win32-x64-msvc": "4.16.4", - "fsevents": "~2.3.2" - } - }, - "node_modules/vite-node/node_modules/vite": { - "version": "5.2.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz", - "integrity": "sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==", - "dev": true, - "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-plugin-fs": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/vite-plugin-fs/-/vite-plugin-fs-0.4.4.tgz", - "integrity": "sha512-TT9kEU2LX3musejDL99nLdjDl7P74AdTnK3yozehswg0FhKSGlNstkHVUgcswKSk6vH/Uzqgz+df7WT0sEA/IA==", - "dev": true, - "dependencies": { - "koa": "^2.13.4", - "koa-bodyparser": "^4.3.0", - "koa-cors": "^0.0.16", - "koa-router": "^10.1.1" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/vite-tsconfig-paths": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz", "integrity": "sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", @@ -7605,31 +5706,31 @@ } }, "node_modules/vitest": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.5.2.tgz", - "integrity": "sha512-l9gwIkq16ug3xY7BxHwcBQovLZG75zZL0PlsiYQbf76Rz6QGs54416UWMtC0jXeihvHvcHrf2ROEjkQRVpoZYw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.4.tgz", + "integrity": "sha512-luNLDpfsnxw5QSW4bISPe6tkxVvv5wn2BBs/PuDRkhXZ319doZyLOBr1sjfB5yCEpTiU7xCAdViM8TNVGPwoog==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/expect": "1.5.2", - "@vitest/runner": "1.5.2", - "@vitest/snapshot": "1.5.2", - "@vitest/spy": "1.5.2", - "@vitest/utils": "1.5.2", - "acorn-walk": "^8.3.2", - "chai": "^4.3.10", - "debug": "^4.3.4", + "@ampproject/remapping": "^2.3.0", + "@vitest/expect": "2.0.4", + "@vitest/pretty-format": "^2.0.4", + "@vitest/runner": "2.0.4", + "@vitest/snapshot": "2.0.4", + "@vitest/spy": "2.0.4", + "@vitest/utils": "2.0.4", + "chai": "^5.1.1", + "debug": "^4.3.5", "execa": "^8.0.1", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.5.0", - "strip-literal": "^2.0.0", - "tinybench": "^2.5.1", - "tinypool": "^0.8.3", + "magic-string": "^0.30.10", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "tinybench": "^2.8.0", + "tinypool": "^1.0.0", + "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "1.5.2", - "why-is-node-running": "^2.2.2" + "vite-node": "2.0.4", + "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" @@ -7643,8 +5744,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.5.2", - "@vitest/ui": "1.5.2", + "@vitest/browser": "2.0.4", + "@vitest/ui": "2.0.4", "happy-dom": "*", "jsdom": "*" }, @@ -7674,6 +5775,7 @@ "resolved": "https://registry.npmjs.org/vitest-canvas-mock/-/vitest-canvas-mock-0.3.3.tgz", "integrity": "sha512-3P968tYBpqYyzzOaVtqnmYjqbe13576/fkjbDEJSfQAkHtC5/UjuRHOhFEN/ZV5HVZIkaROBUWgazDKJ+Ibw+Q==", "dev": true, + "license": "MIT", "dependencies": { "jest-canvas-mock": "~2.5.2" }, @@ -7681,551 +5783,12 @@ "vitest": "*" } }, - "node_modules/vitest/node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/vitest/node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/vitest/node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/vitest/node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/vitest/node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "node_modules/vitest/node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/vitest/node_modules/rollup": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.16.4.tgz", - "integrity": "sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.16.4", - "@rollup/rollup-android-arm64": "4.16.4", - "@rollup/rollup-darwin-arm64": "4.16.4", - "@rollup/rollup-darwin-x64": "4.16.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.16.4", - "@rollup/rollup-linux-arm-musleabihf": "4.16.4", - "@rollup/rollup-linux-arm64-gnu": "4.16.4", - "@rollup/rollup-linux-arm64-musl": "4.16.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.16.4", - "@rollup/rollup-linux-riscv64-gnu": "4.16.4", - "@rollup/rollup-linux-s390x-gnu": "4.16.4", - "@rollup/rollup-linux-x64-gnu": "4.16.4", - "@rollup/rollup-linux-x64-musl": "4.16.4", - "@rollup/rollup-win32-arm64-msvc": "4.16.4", - "@rollup/rollup-win32-ia32-msvc": "4.16.4", - "@rollup/rollup-win32-x64-msvc": "4.16.4", - "fsevents": "~2.3.2" - } - }, - "node_modules/vitest/node_modules/vite": { - "version": "5.2.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz", - "integrity": "sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==", - "dev": true, - "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, + "license": "MIT", "dependencies": { "xml-name-validator": "^5.0.0" }, @@ -8234,9 +5797,10 @@ } }, "node_modules/watskeburt": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/watskeburt/-/watskeburt-4.0.2.tgz", - "integrity": "sha512-w7X8AGrBZExP5/3e3c1X/CUY8Yod/aiAazQCvrg7n8Un6piD+NFFK926G15zRq4+wu0XAEWpSsZ4C+fEfVOCYw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/watskeburt/-/watskeburt-4.1.0.tgz", + "integrity": "sha512-KkY5H51ajqy9HYYI+u9SIURcWnqeVVhdH0I+ab6aXPGHfZYxgRCwnR6Lm3+TYB6jJVt5jFqw4GAKmwf1zHmGQw==", + "dev": true, "bin": { "watskeburt": "dist/run-cli.js" }, @@ -8247,18 +5811,24 @@ "node_modules/webfontloader": { "version": "1.6.28", "resolved": "https://registry.npmjs.org/webfontloader/-/webfontloader-1.6.28.tgz", - "integrity": "sha512-Egb0oFEga6f+nSgasH3E0M405Pzn6y3/9tOVanv/DLfa1YBIgcv90L18YyWnvXkRbIM17v5Kv6IT2N6g1x5tvQ==" + "integrity": "sha512-Egb0oFEga6f+nSgasH3E0M405Pzn6y3/9tOVanv/DLfa1YBIgcv90L18YyWnvXkRbIM17v5Kv6IT2N6g1x5tvQ==", + "license": "Apache-2.0" }, "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } }, "node_modules/whatwg-encoding": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "dev": true, + "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" }, @@ -8266,22 +5836,39 @@ "node": ">=18" } }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/whatwg-mimetype": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dev": true, "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" } }, "node_modules/which": { @@ -8289,6 +5876,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -8299,46 +5887,12 @@ "node": ">= 8" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/why-is-node-running": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, + "license": "MIT", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" @@ -8355,14 +5909,36 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8375,47 +5951,76 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=7.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -8437,6 +6042,7 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18" } @@ -8445,12 +6051,15 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -8459,14 +6068,14 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", + "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", "dev": true, - "license": "ISC", "bin": { "yaml": "bin.mjs" }, @@ -8478,6 +6087,8 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -8495,17 +6106,32 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, - "node_modules/ylru": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.4.0.tgz", - "integrity": "sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==", + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">= 4.0.0" + "node": ">=8" } }, "node_modules/yocto-queue": { @@ -8513,6 +6139,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 612321906eb..dc851e05c92 100644 --- a/package.json +++ b/package.json @@ -21,34 +21,29 @@ }, "devDependencies": { "@eslint/js": "^9.3.0", + "@hpcc-js/wasm": "^2.18.0", + "@stylistic/eslint-plugin-ts": "^2.6.0-beta.0", + "@types/jsdom": "^21.1.7", "@types/node": "^20.12.13", - "@typescript-eslint/eslint-plugin": "^7.10.0", - "@typescript-eslint/parser": "^7.10.0", - "@vitest/coverage-istanbul": "^1.4.0", - "axios": "^1.6.2", - "axios-cache-interceptor": "^1.3.2", - "eslint": "^8.57.0", - "eslint-plugin-import": "^2.29.1", + "@typescript-eslint/eslint-plugin": "^8.0.0-alpha.54", + "@typescript-eslint/parser": "^8.0.0-alpha.54", + "@vitest/coverage-istanbul": "^2.0.4", + "dependency-cruiser": "^16.3.10", + "eslint": "^9.7.0", "jsdom": "^24.0.0", - "json-beautify": "^1.1.1", "lefthook": "^1.6.12", "phaser3spectorjs": "^0.0.8", - "pokenode-ts": "^1.20.0", "typedoc": "^0.26.4", "typescript": "^5.5.3", - "typescript-eslint": "^7.10.0", - "vite": "^4.5.0", - "vite-plugin-fs": "^0.4.4", + "typescript-eslint": "^8.0.0-alpha.54", + "vite": "^5.3.5", "vite-tsconfig-paths": "^4.3.2", - "vitest": "^1.4.0", + "vitest": "^2.0.4", "vitest-canvas-mock": "^0.3.3" }, "dependencies": { - "@hpcc-js/wasm": "^2.16.2", "@material/material-color-utilities": "^0.2.7", - "@types/jsdom": "^21.1.7", "crypto-js": "^4.2.0", - "dependency-cruiser": "^16.3.3", "i18next": "^23.11.1", "i18next-browser-languagedetector": "^7.2.1", "i18next-korean-postposition-processor": "^1.0.0", diff --git a/public/audio/bgm/battle_hoenn_champion.mp3 b/public/audio/bgm/battle_hoenn_champion_g5.mp3 similarity index 100% rename from public/audio/bgm/battle_hoenn_champion.mp3 rename to public/audio/bgm/battle_hoenn_champion_g5.mp3 diff --git a/public/audio/bgm/battle_hoenn_champion_g6.mp3 b/public/audio/bgm/battle_hoenn_champion_g6.mp3 new file mode 100644 index 00000000000..16ef20a5bea Binary files /dev/null and b/public/audio/bgm/battle_hoenn_champion_g6.mp3 differ diff --git a/public/images/pokemon/back/71.json b/public/images/pokemon/back/71.json index b3f5a0792db..195188d13e7 100644 --- a/public/images/pokemon/back/71.json +++ b/public/images/pokemon/back/71.json @@ -1,1532 +1,306 @@ { - "textures": [ - { - "image": "71.png", - "format": "RGBA8888", - "size": { - "w": 333, - "h": 333 - }, - "scale": 1, - "frames": [ - { - "filename": "0015.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 69, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 69, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 69, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 69, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 138, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 138, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 138, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 138, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 205, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 205, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 205, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 205, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 0, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 0, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 0, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 0, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 69, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 69, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 69, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 69, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 138, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 138, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 138, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 138, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 206, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 206, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 206, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 206, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 0, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 0, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 0, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 0, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 68, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 68, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 68, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 68, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 67, - "h": 68 - }, - "frame": { - "x": 136, - "y": 139, - "w": 67, - "h": 68 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 67, - "h": 68 - }, - "frame": { - "x": 136, - "y": 139, - "w": 67, - "h": 68 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 67, - "h": 68 - }, - "frame": { - "x": 136, - "y": 139, - "w": 67, - "h": 68 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 67, - "h": 68 - }, - "frame": { - "x": 136, - "y": 139, - "w": 67, - "h": 68 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 203, - "y": 139, - "w": 66, - "h": 69 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 203, - "y": 139, - "w": 66, - "h": 69 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 203, - "y": 139, - "w": 66, - "h": 69 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 203, - "y": 139, - "w": 66, - "h": 69 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 136, - "y": 207, - "w": 66, - "h": 69 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 136, - "y": 207, - "w": 66, - "h": 69 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 136, - "y": 207, - "w": 66, - "h": 69 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 136, - "y": 207, - "w": 66, - "h": 69 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 202, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 202, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 202, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 202, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 268, - "y": 208, - "w": 64, - "h": 67 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 268, - "y": 208, - "w": 64, - "h": 67 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 268, - "y": 208, - "w": 64, - "h": 67 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 268, - "y": 208, - "w": 64, - "h": 67 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 269, - "y": 139, - "w": 64, - "h": 67 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 269, - "y": 139, - "w": 64, - "h": 67 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 269, - "y": 139, - "w": 64, - "h": 67 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 269, - "y": 139, - "w": 64, - "h": 67 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 0, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 0, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 0, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 0, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 66, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 66, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 66, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 66, - "y": 208, - "w": 66, - "h": 68 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:751712009fd74222715d70b43a4283e8:5955b5b390b7b5ccf4dce1abfcc58af2:699363ed1732140836e97f90bcfd26b2$" - } + "textures": + [ + { + "image": "71.png", + "format": "RGB8888", + "size": { "w": 338, + "h": 269 }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 66, "h": 68 }, + "frame": { "x": 272, "y": 0, "w": 66, "h": 68 } + }, + { + "filename": "0002.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 66, "h": 68 }, + "frame": { "x": 272, "y": 0, "w": 66, "h": 68 } + }, + { + "filename": "0003.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 66, "h": 68 }, + "frame": { "x": 0, "y": 68, "w": 66, "h": 68 } + }, + { + "filename": "0004.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 66, "h": 68 }, + "frame": { "x": 0, "y": 68, "w": 66, "h": 68 } + }, + { + "filename": "0005.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 64, "h": 67 }, + "frame": { "x": 128, "y": 136, "w": 64, "h": 67 } + }, + { + "filename": "0006.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 64, "h": 67 }, + "frame": { "x": 128, "y": 136, "w": 64, "h": 67 } + }, + { + "filename": "0007.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 263, "y": 135, "w": 64, "h": 68 } + }, + { + "filename": "0008.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 263, "y": 135, "w": 64, "h": 68 } + }, + { + "filename": "0009.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 4, "w": 62, "h": 66 }, + "frame": { "x": 128, "y": 203, "w": 62, "h": 66 } + }, + { + "filename": "0010.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 4, "w": 62, "h": 66 }, + "frame": { "x": 128, "y": 203, "w": 62, "h": 66 } + }, + { + "filename": "0011.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 3, "w": 65, "h": 67 }, + "frame": { "x": 198, "y": 135, "w": 65, "h": 67 } + }, + { + "filename": "0012.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 3, "w": 65, "h": 67 }, + "frame": { "x": 198, "y": 135, "w": 65, "h": 67 } + }, + { + "filename": "0013.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 2, "w": 66, "h": 67 }, + "frame": { "x": 198, "y": 68, "w": 66, "h": 67 } + }, + { + "filename": "0014.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 2, "w": 66, "h": 67 }, + "frame": { "x": 198, "y": 68, "w": 66, "h": 67 } + }, + { + "filename": "0015.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 68, "h": 68 }, + "frame": { "x": 0, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0016.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 68, "h": 68 }, + "frame": { "x": 0, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0017.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 0, "w": 68, "h": 68 }, + "frame": { "x": 68, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0018.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 0, "w": 68, "h": 68 }, + "frame": { "x": 68, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0019.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 0, "w": 68, "h": 68 }, + "frame": { "x": 136, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0020.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 0, "w": 68, "h": 68 }, + "frame": { "x": 136, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0021.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 68, "h": 68 }, + "frame": { "x": 204, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0022.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 68, "h": 68 }, + "frame": { "x": 204, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0023.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 2, "w": 66, "h": 67 }, + "frame": { "x": 264, "y": 68, "w": 66, "h": 67 } + }, + { + "filename": "0024.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 2, "w": 66, "h": 67 }, + "frame": { "x": 264, "y": 68, "w": 66, "h": 67 } + }, + { + "filename": "0025.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 0, "y": 136, "w": 64, "h": 68 } + }, + { + "filename": "0026.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 0, "y": 136, "w": 64, "h": 68 } + }, + { + "filename": "0027.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 4, "w": 62, "h": 66 }, + "frame": { "x": 256, "y": 203, "w": 62, "h": 66 } + }, + { + "filename": "0028.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 4, "w": 62, "h": 66 }, + "frame": { "x": 256, "y": 203, "w": 62, "h": 66 } + }, + { + "filename": "0029.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 64, "y": 136, "w": 64, "h": 68 } + }, + { + "filename": "0030.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 64, "y": 136, "w": 64, "h": 68 } + }, + { + "filename": "0031.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 64, "h": 67 }, + "frame": { "x": 192, "y": 202, "w": 64, "h": 67 } + }, + { + "filename": "0032.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 64, "h": 67 }, + "frame": { "x": 192, "y": 202, "w": 64, "h": 67 } + }, + { + "filename": "0033.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 66, "h": 68 }, + "frame": { "x": 66, "y": 68, "w": 66, "h": 68 } + }, + { + "filename": "0034.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 66, "h": 68 }, + "frame": { "x": 66, "y": 68, "w": 66, "h": 68 } + }, + { + "filename": "0035.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 66, "h": 68 }, + "frame": { "x": 132, "y": 68, "w": 66, "h": 68 } + }, + { + "filename": "0036.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 66, "h": 68 }, + "frame": { "x": 132, "y": 68, "w": 66, "h": 68 }} + ], + + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64" + } } +] +} \ No newline at end of file diff --git a/public/images/pokemon/back/71.png b/public/images/pokemon/back/71.png index 3e3424c865e..24a546f6166 100644 Binary files a/public/images/pokemon/back/71.png and b/public/images/pokemon/back/71.png differ diff --git a/public/images/pokemon/back/shiny/71.json b/public/images/pokemon/back/shiny/71.json index d40924360b0..7407c0befe1 100644 --- a/public/images/pokemon/back/shiny/71.json +++ b/public/images/pokemon/back/shiny/71.json @@ -1,1532 +1,306 @@ { - "textures": [ - { - "image": "71.png", - "format": "RGBA8888", - "size": { - "w": 333, - "h": 333 - }, - "scale": 1, - "frames": [ - { - "filename": "0015.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 69, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 69, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 69, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 70 - }, - "frame": { - "x": 69, - "y": 0, - "w": 69, - "h": 70 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 138, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 138, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 138, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 138, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 205, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 205, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 205, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 70 - }, - "frame": { - "x": 205, - "y": 0, - "w": 67, - "h": 70 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 0, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 0, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 0, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 0, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 69, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 69, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 69, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 69, - "h": 69 - }, - "frame": { - "x": 69, - "y": 70, - "w": 69, - "h": 69 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 138, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 138, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 138, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 138, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 206, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 206, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 206, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 206, - "y": 70, - "w": 68, - "h": 69 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 0, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 0, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 0, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 68, - "h": 69 - }, - "frame": { - "x": 0, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 68, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 68, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 68, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 68, - "h": 69 - }, - "frame": { - "x": 68, - "y": 139, - "w": 68, - "h": 69 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 67, - "h": 68 - }, - "frame": { - "x": 136, - "y": 139, - "w": 67, - "h": 68 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 67, - "h": 68 - }, - "frame": { - "x": 136, - "y": 139, - "w": 67, - "h": 68 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 67, - "h": 68 - }, - "frame": { - "x": 136, - "y": 139, - "w": 67, - "h": 68 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 67, - "h": 68 - }, - "frame": { - "x": 136, - "y": 139, - "w": 67, - "h": 68 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 203, - "y": 139, - "w": 66, - "h": 69 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 203, - "y": 139, - "w": 66, - "h": 69 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 203, - "y": 139, - "w": 66, - "h": 69 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 203, - "y": 139, - "w": 66, - "h": 69 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 136, - "y": 207, - "w": 66, - "h": 69 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 136, - "y": 207, - "w": 66, - "h": 69 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 136, - "y": 207, - "w": 66, - "h": 69 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 66, - "h": 69 - }, - "frame": { - "x": 136, - "y": 207, - "w": 66, - "h": 69 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 202, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 202, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 202, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 202, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 268, - "y": 208, - "w": 64, - "h": 67 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 268, - "y": 208, - "w": 64, - "h": 67 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 268, - "y": 208, - "w": 64, - "h": 67 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 268, - "y": 208, - "w": 64, - "h": 67 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 269, - "y": 139, - "w": 64, - "h": 67 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 269, - "y": 139, - "w": 64, - "h": 67 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 269, - "y": 139, - "w": 64, - "h": 67 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 64, - "h": 67 - }, - "frame": { - "x": 269, - "y": 139, - "w": 64, - "h": 67 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 0, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 0, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 0, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 0, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 66, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 66, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 66, - "y": 208, - "w": 66, - "h": 68 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 69, - "h": 70 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 66, - "h": 68 - }, - "frame": { - "x": 66, - "y": 208, - "w": 66, - "h": 68 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:f8d42fbc7e4634a1aafab7a9441fe58f:13cd2160ec05982d017bab80e7a8b69a:699363ed1732140836e97f90bcfd26b2$" - } -} + "textures": + [ + { + "image": "71.png", + "format": "RGB8888", + "size": { "w": 338, + "h": 269 }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 66, "h": 68 }, + "frame": { "x": 272, "y": 0, "w": 66, "h": 68 } + }, + { + "filename": "0002.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 66, "h": 68 }, + "frame": { "x": 272, "y": 0, "w": 66, "h": 68 } + }, + { + "filename": "0003.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 66, "h": 68 }, + "frame": { "x": 0, "y": 68, "w": 66, "h": 68 } + }, + { + "filename": "0004.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 66, "h": 68 }, + "frame": { "x": 0, "y": 68, "w": 66, "h": 68 } + }, + { + "filename": "0005.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 64, "h": 67 }, + "frame": { "x": 128, "y": 136, "w": 64, "h": 67 } + }, + { + "filename": "0006.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 64, "h": 67 }, + "frame": { "x": 128, "y": 136, "w": 64, "h": 67 } + }, + { + "filename": "0007.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 263, "y": 135, "w": 64, "h": 68 } + }, + { + "filename": "0008.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 263, "y": 135, "w": 64, "h": 68 } + }, + { + "filename": "0009.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 4, "w": 62, "h": 66 }, + "frame": { "x": 128, "y": 203, "w": 62, "h": 66 } + }, + { + "filename": "0010.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 4, "w": 62, "h": 66 }, + "frame": { "x": 128, "y": 203, "w": 62, "h": 66 } + }, + { + "filename": "0011.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 3, "w": 65, "h": 67 }, + "frame": { "x": 198, "y": 135, "w": 65, "h": 67 } + }, + { + "filename": "0012.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 3, "w": 65, "h": 67 }, + "frame": { "x": 198, "y": 135, "w": 65, "h": 67 } + }, + { + "filename": "0013.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 2, "w": 66, "h": 67 }, + "frame": { "x": 198, "y": 68, "w": 66, "h": 67 } + }, + { + "filename": "0014.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 2, "w": 66, "h": 67 }, + "frame": { "x": 198, "y": 68, "w": 66, "h": 67 } + }, + { + "filename": "0015.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 68, "h": 68 }, + "frame": { "x": 0, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0016.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 68, "h": 68 }, + "frame": { "x": 0, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0017.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 0, "w": 68, "h": 68 }, + "frame": { "x": 68, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0018.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 0, "w": 68, "h": 68 }, + "frame": { "x": 68, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0019.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 0, "w": 68, "h": 68 }, + "frame": { "x": 136, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0020.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 0, "y": 0, "w": 68, "h": 68 }, + "frame": { "x": 136, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0021.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 68, "h": 68 }, + "frame": { "x": 204, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0022.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 1, "y": 1, "w": 68, "h": 68 }, + "frame": { "x": 204, "y": 0, "w": 68, "h": 68 } + }, + { + "filename": "0023.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 2, "w": 66, "h": 67 }, + "frame": { "x": 264, "y": 68, "w": 66, "h": 67 } + }, + { + "filename": "0024.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 2, "w": 66, "h": 67 }, + "frame": { "x": 264, "y": 68, "w": 66, "h": 67 } + }, + { + "filename": "0025.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 0, "y": 136, "w": 64, "h": 68 } + }, + { + "filename": "0026.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 0, "y": 136, "w": 64, "h": 68 } + }, + { + "filename": "0027.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 4, "w": 62, "h": 66 }, + "frame": { "x": 256, "y": 203, "w": 62, "h": 66 } + }, + { + "filename": "0028.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 4, "w": 62, "h": 66 }, + "frame": { "x": 256, "y": 203, "w": 62, "h": 66 } + }, + { + "filename": "0029.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 64, "y": 136, "w": 64, "h": 68 } + }, + { + "filename": "0030.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 2, "w": 64, "h": 68 }, + "frame": { "x": 64, "y": 136, "w": 64, "h": 68 } + }, + { + "filename": "0031.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 64, "h": 67 }, + "frame": { "x": 192, "y": 202, "w": 64, "h": 67 } + }, + { + "filename": "0032.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 2, "w": 64, "h": 67 }, + "frame": { "x": 192, "y": 202, "w": 64, "h": 67 } + }, + { + "filename": "0033.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 66, "h": 68 }, + "frame": { "x": 66, "y": 68, "w": 66, "h": 68 } + }, + { + "filename": "0034.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 3, "y": 1, "w": 66, "h": 68 }, + "frame": { "x": 66, "y": 68, "w": 66, "h": 68 } + }, + { + "filename": "0035.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 66, "h": 68 }, + "frame": { "x": 132, "y": 68, "w": 66, "h": 68 } + }, + { + "filename": "0036.png", + "sourceSize": { "w": 69, "h": 70 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 2, "y": 0, "w": 66, "h": 68 }, + "frame": { "x": 132, "y": 68, "w": 66, "h": 68 }} + ], + + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64" + } + } + ] + } \ No newline at end of file diff --git a/public/images/pokemon/back/shiny/71.png b/public/images/pokemon/back/shiny/71.png index 03244865da7..99663f744ac 100644 Binary files a/public/images/pokemon/back/shiny/71.png and b/public/images/pokemon/back/shiny/71.png differ diff --git a/public/images/pokemon/exp/4083.json b/public/images/pokemon/exp/4083.json index 8a5bae6080a..26ced14739b 100644 --- a/public/images/pokemon/exp/4083.json +++ b/public/images/pokemon/exp/4083.json @@ -1,1595 +1,616 @@ { - "textures": [ - { - "image": "4083.png", - "format": "RGBA8888", - "size": { - "w": 276, - "h": 276 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 48 - }, - "frame": { - "x": 0, - "y": 0, - "w": 81, - "h": 48 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 48 - }, - "frame": { - "x": 0, - "y": 0, - "w": 81, - "h": 48 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 0, - "y": 48, - "w": 88, - "h": 46 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 0, - "y": 48, - "w": 88, - "h": 46 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 81, - "y": 0, - "w": 88, - "h": 46 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 88, - "y": 46, - "w": 88, - "h": 46 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 169, - "y": 0, - "w": 88, - "h": 46 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 169, - "y": 0, - "w": 88, - "h": 46 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 88, - "y": 92, - "w": 86, - "h": 46 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 0, - "y": 94, - "w": 86, - "h": 46 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 0, - "y": 94, - "w": 86, - "h": 46 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 86, - "y": 138, - "w": 86, - "h": 46 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 0, - "y": 140, - "w": 86, - "h": 46 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 0, - "y": 140, - "w": 86, - "h": 46 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 85, - "h": 46 - }, - "frame": { - "x": 172, - "y": 138, - "w": 85, - "h": 46 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 85, - "h": 46 - }, - "frame": { - "x": 172, - "y": 138, - "w": 85, - "h": 46 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 0, - "y": 186, - "w": 83, - "h": 46 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 0, - "y": 186, - "w": 83, - "h": 46 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 0, - "y": 186, - "w": 83, - "h": 46 - } - }, - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 0, - "y": 186, - "w": 83, - "h": 46 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 169, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 169, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 169, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 169, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 83, - "y": 230, - "w": 83, - "h": 46 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 83, - "y": 230, - "w": 83, - "h": 46 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:1de2d6bd2e4f26446b2c6f55de0f7b9b:e56909341ef6baa38f2c9dc5a42c7808:c8e39c2aa3816f24d9e5ee92c7ddf6b0$" - } + "textures": [ + { + "image": "4083.png", + "format": "RGBA8888", + "size": { "w": 264, "h": 240 }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0019.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0024.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0025.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0026.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0027.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0028.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0029.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0030.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0031.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0032.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0033.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0034.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0035.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0036.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0037.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0038.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0039.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0040.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0041.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0042.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0043.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0044.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0045.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0046.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0047.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0048.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0049.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0050.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0051.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0052.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0053.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0054.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0055.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 96, "w": 88, "h": 48 } + }, + { + "filename": "0056.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 96, "w": 88, "h": 48 } + }, + { + "filename": "0057.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 96, "w": 88, "h": 48 } + }, + { + "filename": "0058.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0059.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0060.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0061.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0062.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0063.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0064.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 192, "w": 88, "h": 48 } + }, + { + "filename": "0065.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 192, "w": 88, "h": 48 } + }, + { + "filename": "0066.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 192, "w": 88, "h": 48 } + }, + { + "filename": "0067.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 192, "w": 88, "h": 48 } + }, + { + "filename": "0068.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 192, "w": 88, "h": 48 } + }, + { + "filename": "0069.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 96, "w": 88, "h": 48 } + }, + { + "filename": "0070.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 96, "w": 88, "h": 48 } + }, + { + "filename": "0071.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0072.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0073.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0074.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0075.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + } + ] + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64" + } } diff --git a/public/images/pokemon/exp/4083.png b/public/images/pokemon/exp/4083.png index 0ce1b804a79..d0fd23c248d 100644 Binary files a/public/images/pokemon/exp/4083.png and b/public/images/pokemon/exp/4083.png differ diff --git a/public/images/pokemon/exp/back/1001.json b/public/images/pokemon/exp/back/1001.json index 7547fbd93bd..e8b2776127c 100644 --- a/public/images/pokemon/exp/back/1001.json +++ b/public/images/pokemon/exp/back/1001.json @@ -1,272 +1,140 @@ { - "textures": [ - { - "image": "1001.png", - "format": "RGBA8888", - "size": { - "w": 237, - "h": 237 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 79 - }, - "frame": { - "x": 0, - "y": 0, - "w": 79, - "h": 79 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 79, - "h": 78 - }, - "frame": { - "x": 79, - "y": 0, - "w": 79, - "h": 78 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 79, - "h": 78 - }, - "frame": { - "x": 79, - "y": 0, - "w": 79, - "h": 78 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 79, - "h": 76 - }, - "frame": { - "x": 158, - "y": 0, - "w": 79, - "h": 76 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 79, - "h": 76 - }, - "frame": { - "x": 158, - "y": 0, - "w": 79, - "h": 76 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 79, - "h": 75 - }, - "frame": { - "x": 158, - "y": 76, - "w": 79, - "h": 75 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 79, - "h": 75 - }, - "frame": { - "x": 158, - "y": 76, - "w": 79, - "h": 75 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 79, - "h": 74 - }, - "frame": { - "x": 79, - "y": 78, - "w": 79, - "h": 74 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 79, - "h": 74 - }, - "frame": { - "x": 79, - "y": 78, - "w": 79, - "h": 74 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 79, - "h": 73 - }, - "frame": { - "x": 0, - "y": 79, - "w": 79, - "h": 73 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 79, - "h": 73 - }, - "frame": { - "x": 0, - "y": 79, - "w": 79, - "h": 73 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 7, - "w": 79, - "h": 72 - }, - "frame": { - "x": 158, - "y": 151, - "w": 79, - "h": 72 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:2873276355a5ff8fe57d616764a11cb5:5516cfd39964108d480df461b020785f:c8a3fc07f857e38a4f887e43523aab92$" + "textures":[ + { + "image": "1001.png", + "format": "RGBA8888", + "size": { "w": 161, "h": 157 }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 }, + "frame": { "x": 80, "y": 78, "w": 79, "h": 79 } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 }, + "frame": { "x": 80, "y": 78, "w": 79, "h": 79 } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 }, + "frame": { "x": 80, "y": 78, "w": 79, "h": 79 } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 }, + "frame": { "x": 80, "y": 78, "w": 79, "h": 79 } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 }, + "frame": { "x": 0, "y": 79, "w": 80, "h": 78 } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 }, + "frame": { "x": 0, "y": 79, "w": 80, "h": 78 } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 }, + "frame": { "x": 0, "y": 79, "w": 80, "h": 78 } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 }, + "frame": { "x": 0, "y": 79, "w": 80, "h": 78 } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 }, + "frame": { "x": 80, "y": 0, "w": 81, "h": 78 } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 }, + "frame": { "x": 80, "y": 0, "w": 81, "h": 78 } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 }, + "frame": { "x": 80, "y": 0, "w": 81, "h": 78 } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 }, + "frame": { "x": 80, "y": 0, "w": 81, "h": 78 } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 }, + "frame": { "x": 0, "y": 0, "w": 80, "h": 79 } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 }, + "frame": { "x": 0, "y": 0, "w": 80, "h": 79 } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 }, + "frame": { "x": 0, "y": 0, "w": 80, "h": 79 } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 }, + "frame": { "x": 0, "y": 0, "w": 80, "h": 79 } + } + ]}], + "meta": {"app": "https://www.aseprite.org/","version": "1.3.7-x64" } } diff --git a/public/images/pokemon/exp/back/1001.png b/public/images/pokemon/exp/back/1001.png index 606028b4d16..7eead83b578 100644 Binary files a/public/images/pokemon/exp/back/1001.png and b/public/images/pokemon/exp/back/1001.png differ diff --git a/public/images/pokemon/exp/back/380-mega.png b/public/images/pokemon/exp/back/380-mega.png index d865e64c373..b6941fc2611 100644 Binary files a/public/images/pokemon/exp/back/380-mega.png and b/public/images/pokemon/exp/back/380-mega.png differ diff --git a/public/images/pokemon/exp/back/381-mega.png b/public/images/pokemon/exp/back/381-mega.png index d865e64c373..b6941fc2611 100644 Binary files a/public/images/pokemon/exp/back/381-mega.png and b/public/images/pokemon/exp/back/381-mega.png differ diff --git a/public/images/pokemon/exp/back/911.png b/public/images/pokemon/exp/back/911.png index 04010c67444..a15676954fc 100644 Binary files a/public/images/pokemon/exp/back/911.png and b/public/images/pokemon/exp/back/911.png differ diff --git a/public/images/pokemon/exp/back/shiny/1001.json b/public/images/pokemon/exp/back/shiny/1001.json index 1ea21ec6995..cf2dd09815d 100644 --- a/public/images/pokemon/exp/back/shiny/1001.json +++ b/public/images/pokemon/exp/back/shiny/1001.json @@ -1,272 +1,140 @@ { - "textures": [ - { - "image": "1001.png", - "format": "RGBA8888", - "size": { - "w": 237, - "h": 237 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 79 - }, - "frame": { - "x": 0, - "y": 0, - "w": 79, - "h": 79 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 79, - "h": 78 - }, - "frame": { - "x": 79, - "y": 0, - "w": 79, - "h": 78 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 79, - "h": 78 - }, - "frame": { - "x": 79, - "y": 0, - "w": 79, - "h": 78 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 79, - "h": 76 - }, - "frame": { - "x": 158, - "y": 0, - "w": 79, - "h": 76 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 79, - "h": 76 - }, - "frame": { - "x": 158, - "y": 0, - "w": 79, - "h": 76 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 79, - "h": 75 - }, - "frame": { - "x": 158, - "y": 76, - "w": 79, - "h": 75 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 79, - "h": 75 - }, - "frame": { - "x": 158, - "y": 76, - "w": 79, - "h": 75 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 79, - "h": 74 - }, - "frame": { - "x": 79, - "y": 78, - "w": 79, - "h": 74 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 79, - "h": 74 - }, - "frame": { - "x": 79, - "y": 78, - "w": 79, - "h": 74 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 79, - "h": 73 - }, - "frame": { - "x": 0, - "y": 79, - "w": 79, - "h": 73 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 6, - "w": 79, - "h": 73 - }, - "frame": { - "x": 0, - "y": 79, - "w": 79, - "h": 73 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 79, - "h": 79 - }, - "spriteSourceSize": { - "x": 0, - "y": 7, - "w": 79, - "h": 72 - }, - "frame": { - "x": 158, - "y": 151, - "w": 79, - "h": 72 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:83b74b0673ef1ae8346efab60ae89872:f76c930177bf7a296d3f47eb6294ae4f:c8a3fc07f857e38a4f887e43523aab92$" + "textures":[ + { + "image": "1001.png", + "format": "RGBA8888", + "size": { "w": 161, "h": 157 }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 }, + "frame": { "x": 80, "y": 78, "w": 79, "h": 79 } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 }, + "frame": { "x": 80, "y": 78, "w": 79, "h": 79 } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 }, + "frame": { "x": 80, "y": 78, "w": 79, "h": 79 } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 }, + "frame": { "x": 80, "y": 78, "w": 79, "h": 79 } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 }, + "frame": { "x": 0, "y": 79, "w": 80, "h": 78 } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 }, + "frame": { "x": 0, "y": 79, "w": 80, "h": 78 } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 }, + "frame": { "x": 0, "y": 79, "w": 80, "h": 78 } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 }, + "frame": { "x": 0, "y": 79, "w": 80, "h": 78 } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 }, + "frame": { "x": 80, "y": 0, "w": 81, "h": 78 } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 }, + "frame": { "x": 80, "y": 0, "w": 81, "h": 78 } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 }, + "frame": { "x": 80, "y": 0, "w": 81, "h": 78 } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 }, + "frame": { "x": 80, "y": 0, "w": 81, "h": 78 } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 }, + "frame": { "x": 0, "y": 0, "w": 80, "h": 79 } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 }, + "frame": { "x": 0, "y": 0, "w": 80, "h": 79 } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 }, + "frame": { "x": 0, "y": 0, "w": 80, "h": 79 } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 81, "h": 79 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 }, + "frame": { "x": 0, "y": 0, "w": 80, "h": 79 } + } + ]}], + "meta": {"app": "https://www.aseprite.org/","version": "1.3.7-x64" } } diff --git a/public/images/pokemon/exp/back/shiny/1001.png b/public/images/pokemon/exp/back/shiny/1001.png index 6d04c70dbb8..2fd3e5fecd9 100644 Binary files a/public/images/pokemon/exp/back/shiny/1001.png and b/public/images/pokemon/exp/back/shiny/1001.png differ diff --git a/public/images/pokemon/exp/back/shiny/380-mega.png b/public/images/pokemon/exp/back/shiny/380-mega.png index b2450dd0b9e..6efdf36e4cb 100644 Binary files a/public/images/pokemon/exp/back/shiny/380-mega.png and b/public/images/pokemon/exp/back/shiny/380-mega.png differ diff --git a/public/images/pokemon/exp/back/shiny/381-mega.png b/public/images/pokemon/exp/back/shiny/381-mega.png index 2625284e972..9c0c182235b 100644 Binary files a/public/images/pokemon/exp/back/shiny/381-mega.png and b/public/images/pokemon/exp/back/shiny/381-mega.png differ diff --git a/public/images/pokemon/exp/back/shiny/911.png b/public/images/pokemon/exp/back/shiny/911.png index 46b513ba014..948f8a3ae12 100644 Binary files a/public/images/pokemon/exp/back/shiny/911.png and b/public/images/pokemon/exp/back/shiny/911.png differ diff --git a/public/images/pokemon/exp/shiny/4083.json b/public/images/pokemon/exp/shiny/4083.json index 3b08d82cc72..26ced14739b 100644 --- a/public/images/pokemon/exp/shiny/4083.json +++ b/public/images/pokemon/exp/shiny/4083.json @@ -1,1595 +1,616 @@ { - "textures": [ - { - "image": "4083.png", - "format": "RGBA8888", - "size": { - "w": 276, - "h": 276 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 48 - }, - "frame": { - "x": 0, - "y": 0, - "w": 81, - "h": 48 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 48 - }, - "frame": { - "x": 0, - "y": 0, - "w": 81, - "h": 48 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 0, - "y": 48, - "w": 88, - "h": 46 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 0, - "y": 48, - "w": 88, - "h": 46 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 81, - "y": 0, - "w": 88, - "h": 46 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 88, - "y": 46, - "w": 88, - "h": 46 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 169, - "y": 0, - "w": 88, - "h": 46 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 46 - }, - "frame": { - "x": 169, - "y": 0, - "w": 88, - "h": 46 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 88, - "y": 92, - "w": 86, - "h": 46 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 0, - "y": 94, - "w": 86, - "h": 46 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 0, - "y": 94, - "w": 86, - "h": 46 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 86, - "y": 138, - "w": 86, - "h": 46 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 0, - "y": 140, - "w": 86, - "h": 46 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 86, - "h": 46 - }, - "frame": { - "x": 0, - "y": 140, - "w": 86, - "h": 46 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 85, - "h": 46 - }, - "frame": { - "x": 172, - "y": 138, - "w": 85, - "h": 46 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 85, - "h": 46 - }, - "frame": { - "x": 172, - "y": 138, - "w": 85, - "h": 46 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 84, - "h": 45 - }, - "frame": { - "x": 174, - "y": 92, - "w": 84, - "h": 45 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 176, - "y": 46, - "w": 83, - "h": 46 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 86, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 0, - "y": 186, - "w": 83, - "h": 46 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 0, - "y": 186, - "w": 83, - "h": 46 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 0, - "y": 186, - "w": 83, - "h": 46 - } - }, - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 0, - "y": 186, - "w": 83, - "h": 46 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 169, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 169, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 169, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 169, - "y": 184, - "w": 83, - "h": 46 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 83, - "y": 230, - "w": 83, - "h": 46 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 83, - "h": 46 - }, - "frame": { - "x": 83, - "y": 230, - "w": 83, - "h": 46 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 48 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 81, - "h": 46 - }, - "frame": { - "x": 166, - "y": 230, - "w": 81, - "h": 46 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:4ad56d9607be6aa947d6e44195a90329:4e05bca229cb6af4241ccb9cf6b54cc3:c8e39c2aa3816f24d9e5ee92c7ddf6b0$" - } + "textures": [ + { + "image": "4083.png", + "format": "RGBA8888", + "size": { "w": 264, "h": 240 }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0019.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0024.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0025.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0026.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0027.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0028.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0029.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0030.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0031.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0032.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0033.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0034.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0035.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0036.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0037.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0038.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0039.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0040.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0041.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0042.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0043.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0044.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0045.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0046.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0047.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0048.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0049.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0050.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + }, + { + "filename": "0051.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0052.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0053.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0054.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0055.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 96, "w": 88, "h": 48 } + }, + { + "filename": "0056.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 96, "w": 88, "h": 48 } + }, + { + "filename": "0057.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 96, "w": 88, "h": 48 } + }, + { + "filename": "0058.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0059.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0060.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0061.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0062.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0063.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 144, "w": 88, "h": 48 } + }, + { + "filename": "0064.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 192, "w": 88, "h": 48 } + }, + { + "filename": "0065.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 192, "w": 88, "h": 48 } + }, + { + "filename": "0066.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 192, "w": 88, "h": 48 } + }, + { + "filename": "0067.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 192, "w": 88, "h": 48 } + }, + { + "filename": "0068.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 192, "w": 88, "h": 48 } + }, + { + "filename": "0069.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 96, "w": 88, "h": 48 } + }, + { + "filename": "0070.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 96, "w": 88, "h": 48 } + }, + { + "filename": "0071.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0072.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 176, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0073.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0074.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 88, "y": 48, "w": 88, "h": 48 } + }, + { + "filename": "0075.png", + "rotated": false, + "trimmed": true, + "sourceSize": { "w": 88, "h": 48 }, + "spriteSourceSize": { "x": 0, "y": 0, "w": 88, "h": 48 }, + "frame": { "x": 0, "y": 0, "w": 88, "h": 48 } + } + ] + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64" + } } diff --git a/public/images/pokemon/exp/shiny/4083.png b/public/images/pokemon/exp/shiny/4083.png index 4fd8c0e36a1..40d6c6cc50f 100644 Binary files a/public/images/pokemon/exp/shiny/4083.png and b/public/images/pokemon/exp/shiny/4083.png differ diff --git a/public/images/pokemon/exp/shiny/693.png b/public/images/pokemon/exp/shiny/693.png index 2212a4a5158..328c909b196 100644 Binary files a/public/images/pokemon/exp/shiny/693.png and b/public/images/pokemon/exp/shiny/693.png differ diff --git a/public/images/pokemon/icons/4/494.png b/public/images/pokemon/icons/5/494.png similarity index 100% rename from public/images/pokemon/icons/4/494.png rename to public/images/pokemon/icons/5/494.png diff --git a/public/images/pokemon/icons/4/494s.png b/public/images/pokemon/icons/5/494s.png similarity index 100% rename from public/images/pokemon/icons/4/494s.png rename to public/images/pokemon/icons/5/494s.png diff --git a/public/images/pokemon/icons/9/1012-artisan.png b/public/images/pokemon/icons/9/1012-artisan.png new file mode 100644 index 00000000000..96a215e47de Binary files /dev/null and b/public/images/pokemon/icons/9/1012-artisan.png differ diff --git a/public/images/pokemon/icons/9/1012s-artisan.png b/public/images/pokemon/icons/9/1012s-artisan.png new file mode 100644 index 00000000000..43d0f32a0c4 Binary files /dev/null and b/public/images/pokemon/icons/9/1012s-artisan.png differ diff --git a/public/images/pokemon/icons/9/1013-masterpiece.png b/public/images/pokemon/icons/9/1013-masterpiece.png new file mode 100644 index 00000000000..7f5ee1fddd1 Binary files /dev/null and b/public/images/pokemon/icons/9/1013-masterpiece.png differ diff --git a/public/images/pokemon/icons/9/1013s-masterpiece.png b/public/images/pokemon/icons/9/1013s-masterpiece.png new file mode 100644 index 00000000000..85edbb60ae0 Binary files /dev/null and b/public/images/pokemon/icons/9/1013s-masterpiece.png differ diff --git a/public/images/pokemon/icons/variant/6/354-mega_2.png b/public/images/pokemon/icons/variant/3/354-mega_2.png similarity index 100% rename from public/images/pokemon/icons/variant/6/354-mega_2.png rename to public/images/pokemon/icons/variant/3/354-mega_2.png diff --git a/public/images/pokemon/icons/variant/6/354-mega_3.png b/public/images/pokemon/icons/variant/3/354-mega_3.png similarity index 100% rename from public/images/pokemon/icons/variant/6/354-mega_3.png rename to public/images/pokemon/icons/variant/3/354-mega_3.png diff --git a/public/images/pokemon/icons/variant/4/494_2.png b/public/images/pokemon/icons/variant/5/494_2.png similarity index 100% rename from public/images/pokemon/icons/variant/4/494_2.png rename to public/images/pokemon/icons/variant/5/494_2.png diff --git a/public/images/pokemon/icons/variant/4/494_3.png b/public/images/pokemon/icons/variant/5/494_3.png similarity index 100% rename from public/images/pokemon/icons/variant/4/494_3.png rename to public/images/pokemon/icons/variant/5/494_3.png diff --git a/public/images/pokemon/icons/variant/6/742_2.png b/public/images/pokemon/icons/variant/7/742_2.png similarity index 100% rename from public/images/pokemon/icons/variant/6/742_2.png rename to public/images/pokemon/icons/variant/7/742_2.png diff --git a/public/images/pokemon/icons/variant/6/742_3.png b/public/images/pokemon/icons/variant/7/742_3.png similarity index 100% rename from public/images/pokemon/icons/variant/6/742_3.png rename to public/images/pokemon/icons/variant/7/742_3.png diff --git a/public/images/pokemon/icons/variant/6/743_2.png b/public/images/pokemon/icons/variant/7/743_2.png similarity index 100% rename from public/images/pokemon/icons/variant/6/743_2.png rename to public/images/pokemon/icons/variant/7/743_2.png diff --git a/public/images/pokemon/icons/variant/6/743_3.png b/public/images/pokemon/icons/variant/7/743_3.png similarity index 100% rename from public/images/pokemon/icons/variant/6/743_3.png rename to public/images/pokemon/icons/variant/7/743_3.png diff --git a/public/images/pokemon/icons/variant/6/777_2.png b/public/images/pokemon/icons/variant/7/777_2.png similarity index 100% rename from public/images/pokemon/icons/variant/6/777_2.png rename to public/images/pokemon/icons/variant/7/777_2.png diff --git a/public/images/pokemon/icons/variant/6/777_3.png b/public/images/pokemon/icons/variant/7/777_3.png similarity index 100% rename from public/images/pokemon/icons/variant/6/777_3.png rename to public/images/pokemon/icons/variant/7/777_3.png diff --git a/public/images/pokemon/icons/variant/7/778-busted_2.png b/public/images/pokemon/icons/variant/7/778-busted_2.png new file mode 100644 index 00000000000..4ee05ae0a64 Binary files /dev/null and b/public/images/pokemon/icons/variant/7/778-busted_2.png differ diff --git a/public/images/pokemon/icons/variant/7/778-busted_3.png b/public/images/pokemon/icons/variant/7/778-busted_3.png new file mode 100644 index 00000000000..a6c987989e1 Binary files /dev/null and b/public/images/pokemon/icons/variant/7/778-busted_3.png differ diff --git a/public/images/pokemon/icons/variant/6/779_2.png b/public/images/pokemon/icons/variant/7/779_2.png similarity index 100% rename from public/images/pokemon/icons/variant/6/779_2.png rename to public/images/pokemon/icons/variant/7/779_2.png diff --git a/public/images/pokemon/icons/variant/6/779_3.png b/public/images/pokemon/icons/variant/7/779_3.png similarity index 100% rename from public/images/pokemon/icons/variant/6/779_3.png rename to public/images/pokemon/icons/variant/7/779_3.png diff --git a/public/images/pokemon/variant/_masterlist.json b/public/images/pokemon/variant/_masterlist.json index c936fc8d0a1..d03d8d7f1f5 100644 --- a/public/images/pokemon/variant/_masterlist.json +++ b/public/images/pokemon/variant/_masterlist.json @@ -3265,6 +3265,11 @@ 1, 1 ], + "217": [ + 1, + 1, + 1 + ], "229": [ 0, 1, @@ -6658,6 +6663,11 @@ 1, 1 ], + "217": [ + 1, + 1, + 1 + ], "229": [ 0, 1, diff --git a/public/images/pokemon/variant/back/426_3.json b/public/images/pokemon/variant/back/426_3.json deleted file mode 100644 index 72c1bf371ad..00000000000 --- a/public/images/pokemon/variant/back/426_3.json +++ /dev/null @@ -1,1532 +0,0 @@ -{ - "textures": [ - { - "image": "426_3.png", - "format": "RGBA8888", - "size": { - "w": 335, - "h": 335 - }, - "scale": 1, - "frames": [ - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 63, - "h": 57 - }, - "frame": { - "x": 0, - "y": 0, - "w": 63, - "h": 57 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 63, - "h": 57 - }, - "frame": { - "x": 0, - "y": 0, - "w": 63, - "h": 57 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 63, - "h": 58 - }, - "frame": { - "x": 63, - "y": 0, - "w": 63, - "h": 58 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 63, - "h": 58 - }, - "frame": { - "x": 63, - "y": 0, - "w": 63, - "h": 58 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 64, - "h": 59 - }, - "frame": { - "x": 126, - "y": 0, - "w": 64, - "h": 59 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 64, - "h": 59 - }, - "frame": { - "x": 126, - "y": 0, - "w": 64, - "h": 59 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 64, - "h": 59 - }, - "frame": { - "x": 126, - "y": 0, - "w": 64, - "h": 59 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 64, - "h": 59 - }, - "frame": { - "x": 126, - "y": 0, - "w": 64, - "h": 59 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 2, - "y": 4, - "w": 67, - "h": 59 - }, - "frame": { - "x": 190, - "y": 0, - "w": 67, - "h": 59 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 2, - "y": 4, - "w": 67, - "h": 59 - }, - "frame": { - "x": 190, - "y": 0, - "w": 67, - "h": 59 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 59 - }, - "frame": { - "x": 190, - "y": 0, - "w": 67, - "h": 59 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 67, - "h": 59 - }, - "frame": { - "x": 190, - "y": 0, - "w": 67, - "h": 59 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 64, - "h": 60 - }, - "frame": { - "x": 257, - "y": 0, - "w": 64, - "h": 60 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 64, - "h": 60 - }, - "frame": { - "x": 257, - "y": 0, - "w": 64, - "h": 60 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 64, - "h": 60 - }, - "frame": { - "x": 257, - "y": 0, - "w": 64, - "h": 60 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 64, - "h": 60 - }, - "frame": { - "x": 257, - "y": 0, - "w": 64, - "h": 60 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 63, - "h": 60 - }, - "frame": { - "x": 0, - "y": 57, - "w": 63, - "h": 60 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 63, - "h": 60 - }, - "frame": { - "x": 0, - "y": 57, - "w": 63, - "h": 60 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 62, - "h": 61 - }, - "frame": { - "x": 63, - "y": 58, - "w": 62, - "h": 61 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 62, - "h": 61 - }, - "frame": { - "x": 63, - "y": 58, - "w": 62, - "h": 61 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 67, - "h": 60 - }, - "frame": { - "x": 125, - "y": 59, - "w": 67, - "h": 60 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 8, - "w": 67, - "h": 60 - }, - "frame": { - "x": 125, - "y": 59, - "w": 67, - "h": 60 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 6, - "w": 64, - "h": 61 - }, - "frame": { - "x": 192, - "y": 59, - "w": 64, - "h": 61 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 6, - "w": 64, - "h": 61 - }, - "frame": { - "x": 192, - "y": 59, - "w": 64, - "h": 61 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 2, - "w": 64, - "h": 61 - }, - "frame": { - "x": 192, - "y": 59, - "w": 64, - "h": 61 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 2, - "w": 64, - "h": 61 - }, - "frame": { - "x": 192, - "y": 59, - "w": 64, - "h": 61 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 1, - "y": 10, - "w": 69, - "h": 60 - }, - "frame": { - "x": 256, - "y": 60, - "w": 69, - "h": 60 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 1, - "y": 10, - "w": 69, - "h": 60 - }, - "frame": { - "x": 256, - "y": 60, - "w": 69, - "h": 60 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 9, - "w": 63, - "h": 62 - }, - "frame": { - "x": 0, - "y": 117, - "w": 63, - "h": 62 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 9, - "w": 63, - "h": 62 - }, - "frame": { - "x": 0, - "y": 117, - "w": 63, - "h": 62 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 63, - "h": 62 - }, - "frame": { - "x": 0, - "y": 117, - "w": 63, - "h": 62 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 63, - "h": 62 - }, - "frame": { - "x": 0, - "y": 117, - "w": 63, - "h": 62 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 0, - "y": 10, - "w": 70, - "h": 60 - }, - "frame": { - "x": 63, - "y": 119, - "w": 70, - "h": 60 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 0, - "y": 10, - "w": 70, - "h": 60 - }, - "frame": { - "x": 63, - "y": 119, - "w": 70, - "h": 60 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 1, - "y": 4, - "w": 69, - "h": 61 - }, - "frame": { - "x": 133, - "y": 120, - "w": 69, - "h": 61 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 1, - "y": 4, - "w": 69, - "h": 61 - }, - "frame": { - "x": 133, - "y": 120, - "w": 69, - "h": 61 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 69, - "h": 61 - }, - "frame": { - "x": 133, - "y": 120, - "w": 69, - "h": 61 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 69, - "h": 61 - }, - "frame": { - "x": 133, - "y": 120, - "w": 69, - "h": 61 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 71, - "h": 61 - }, - "frame": { - "x": 202, - "y": 120, - "w": 71, - "h": 61 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 0, - "y": 5, - "w": 71, - "h": 61 - }, - "frame": { - "x": 202, - "y": 120, - "w": 71, - "h": 61 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 71, - "h": 61 - }, - "frame": { - "x": 202, - "y": 120, - "w": 71, - "h": 61 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 71, - "h": 61 - }, - "frame": { - "x": 202, - "y": 120, - "w": 71, - "h": 61 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 62, - "h": 62 - }, - "frame": { - "x": 273, - "y": 120, - "w": 62, - "h": 62 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 62, - "h": 62 - }, - "frame": { - "x": 273, - "y": 120, - "w": 62, - "h": 62 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 62, - "h": 62 - }, - "frame": { - "x": 273, - "y": 120, - "w": 62, - "h": 62 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 62, - "h": 62 - }, - "frame": { - "x": 273, - "y": 120, - "w": 62, - "h": 62 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 64, - "h": 61 - }, - "frame": { - "x": 0, - "y": 179, - "w": 64, - "h": 61 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 64, - "h": 61 - }, - "frame": { - "x": 0, - "y": 179, - "w": 64, - "h": 61 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 1, - "y": 11, - "w": 69, - "h": 61 - }, - "frame": { - "x": 64, - "y": 179, - "w": 69, - "h": 61 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 1, - "y": 11, - "w": 69, - "h": 61 - }, - "frame": { - "x": 64, - "y": 179, - "w": 69, - "h": 61 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 11, - "w": 66, - "h": 61 - }, - "frame": { - "x": 133, - "y": 181, - "w": 66, - "h": 61 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 11, - "w": 66, - "h": 61 - }, - "frame": { - "x": 133, - "y": 181, - "w": 66, - "h": 61 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 64, - "h": 62 - }, - "frame": { - "x": 199, - "y": 181, - "w": 64, - "h": 62 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 64, - "h": 62 - }, - "frame": { - "x": 199, - "y": 181, - "w": 64, - "h": 62 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 64, - "h": 62 - }, - "frame": { - "x": 199, - "y": 181, - "w": 64, - "h": 62 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 4, - "y": 3, - "w": 64, - "h": 62 - }, - "frame": { - "x": 199, - "y": 181, - "w": 64, - "h": 62 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 2, - "y": 6, - "w": 69, - "h": 62 - }, - "frame": { - "x": 263, - "y": 182, - "w": 69, - "h": 62 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 2, - "y": 6, - "w": 69, - "h": 62 - }, - "frame": { - "x": 263, - "y": 182, - "w": 69, - "h": 62 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 69, - "h": 62 - }, - "frame": { - "x": 263, - "y": 182, - "w": 69, - "h": 62 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 2, - "y": 2, - "w": 69, - "h": 62 - }, - "frame": { - "x": 263, - "y": 182, - "w": 69, - "h": 62 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 7, - "w": 66, - "h": 62 - }, - "frame": { - "x": 0, - "y": 240, - "w": 66, - "h": 62 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 7, - "w": 66, - "h": 62 - }, - "frame": { - "x": 0, - "y": 240, - "w": 66, - "h": 62 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 66, - "h": 62 - }, - "frame": { - "x": 0, - "y": 240, - "w": 66, - "h": 62 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 66, - "h": 62 - }, - "frame": { - "x": 0, - "y": 240, - "w": 66, - "h": 62 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 64, - "h": 62 - }, - "frame": { - "x": 66, - "y": 240, - "w": 64, - "h": 62 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 64, - "h": 62 - }, - "frame": { - "x": 66, - "y": 240, - "w": 64, - "h": 62 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 63, - "h": 63 - }, - "frame": { - "x": 130, - "y": 242, - "w": 63, - "h": 63 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 63, - "h": 63 - }, - "frame": { - "x": 130, - "y": 242, - "w": 63, - "h": 63 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 64, - "h": 63 - }, - "frame": { - "x": 193, - "y": 243, - "w": 64, - "h": 63 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 64, - "h": 63 - }, - "frame": { - "x": 193, - "y": 243, - "w": 64, - "h": 63 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 65, - "h": 63 - }, - "frame": { - "x": 257, - "y": 244, - "w": 65, - "h": 63 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 71, - "h": 72 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 65, - "h": 63 - }, - "frame": { - "x": 257, - "y": 244, - "w": 65, - "h": 63 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:5a260d2a6180d3a382a352c076369741:e26f8902d45a6e7b427d7dd3cc82c868:b81a75872f1ff6f03d9cd643388500e3$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/426_3.png b/public/images/pokemon/variant/back/426_3.png deleted file mode 100644 index e994a22f917..00000000000 Binary files a/public/images/pokemon/variant/back/426_3.png and /dev/null differ diff --git a/public/images/pokemon/variant/back/female/217.json b/public/images/pokemon/variant/back/female/217.json new file mode 100644 index 00000000000..7ce80e163b6 --- /dev/null +++ b/public/images/pokemon/variant/back/female/217.json @@ -0,0 +1,38 @@ +{ + "0": { + "422919": "112114", + "7b7b8c": "7b7b8c", + "101010": "101010", + "945221": "2f6324", + "ffffff": "ffffff", + "634229": "1d3d26", + "b5b5bd": "b5b5bd", + "f7c563": "fecd85", + "c59c4a": "cd9343", + "dedede": "dedede" + }, + "1": { + "422919": "2d0e1f", + "7b7b8c": "7b7b8c", + "101010": "101010", + "945221": "8c2a37", + "ffffff": "ffffff", + "634229": "6b1d38", + "b5b5bd": "b5b5bd", + "f7c563": "f2cab8", + "c59c4a": "c48e81", + "dedede": "dedede" + }, + "2": { + "422919": "111433", + "7b7b8c": "7b7b8c", + "101010": "101010", + "945221": "323760", + "ffffff": "ffffff", + "634229": "1e2249", + "b5b5bd": "b5b5bd", + "f7c563": "5ccaf2", + "c59c4a": "45a2f9", + "dedede": "dedede" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/female/217.json b/public/images/pokemon/variant/female/217.json new file mode 100644 index 00000000000..e09efa5de60 --- /dev/null +++ b/public/images/pokemon/variant/female/217.json @@ -0,0 +1,50 @@ +{ + "0": { + "7b7b8c": "7b7b8c", + "101010": "101010", + "634229": "1d3d26", + "ffffff": "ffffff", + "945221": "2f6324", + "422919": "112114", + "dedede": "dedede", + "bd7342": "6a8a46", + "ffef84": "f7ffa5", + "b5b5bd": "b5b5bd", + "c59c4a": "ceb552", + "f7c563": "f7de7b", + "841931": "a52942", + "de3a5a": "ef526b" + }, + "1": { + "7b7b8c": "7b7b8c", + "101010": "101010", + "634229": "6b1d38", + "ffffff": "ffffff", + "945221": "8c2a37", + "422919": "2d0e1f", + "dedede": "dedede", + "bd7342": "b74543", + "ffef84": "f9eddb", + "b5b5bd": "b5b5bd", + "c59c4a": "c48e81", + "f7c563": "f2cab8", + "841931": "841931", + "de3a5a": "de3a5a" + }, + "2": { + "7b7b8c": "7b7b8c", + "101010": "101010", + "634229": "1e2249", + "ffffff": "ffffff", + "945221": "323760", + "422919": "111433", + "dedede": "dedede", + "bd7342": "46527a", + "ffef84": "adf2f7", + "b5b5bd": "b5b5bd", + "c59c4a": "45a2f9", + "f7c563": "5ccaf2", + "841931": "a52942", + "de3a5a": "ef526b" + } +} \ No newline at end of file diff --git a/public/images/pokemon_icons_4.json b/public/images/pokemon_icons_4.json index baa804fa2a0..bc32a16f02c 100644 --- a/public/images/pokemon_icons_4.json +++ b/public/images/pokemon_icons_4.json @@ -4,8 +4,8 @@ "image": "pokemon_icons_4.png", "format": "RGBA8888", "size": { - "w": 252, - "h": 663 + "w": 250, + "h": 665 }, "scale": 1, "frames": [ @@ -682,7 +682,7 @@ } }, { - "filename": "399", + "filename": "415", "rotated": false, "trimmed": true, "sourceSize": { @@ -690,16 +690,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, - "y": 12, - "w": 20, - "h": 16 + "x": 9, + "y": 9, + "w": 25, + "h": 18 }, "frame": { "x": 0, "y": 647, - "w": 20, - "h": 16 + "w": 25, + "h": 18 } }, { @@ -829,7 +829,7 @@ } }, { - "filename": "438", + "filename": "415s", "rotated": false, "trimmed": true, "sourceSize": { @@ -837,37 +837,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 14, - "y": 8, - "w": 12, - "h": 20 + "x": 9, + "y": 9, + "w": 25, + "h": 18 }, "frame": { - "x": 240, - "y": 23, - "w": 12, - "h": 20 - } - }, - { - "filename": "399s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 12, - "w": 20, - "h": 16 - }, - "frame": { - "x": 20, + "x": 25, "y": 647, - "w": 20, - "h": 16 + "w": 25, + "h": 18 } }, { @@ -1459,7 +1438,7 @@ } }, { - "filename": "462", + "filename": "479-mow", "rotated": false, "trimmed": true, "sourceSize": { @@ -1467,16 +1446,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 26, - "h": 24 + "x": 8, + "y": 5, + "w": 24, + "h": 25 }, "frame": { "x": 226, "y": 94, - "w": 26, - "h": 24 + "w": 24, + "h": 25 } }, { @@ -1501,7 +1480,7 @@ } }, { - "filename": "462s", + "filename": "479s-mow", "rotated": false, "trimmed": true, "sourceSize": { @@ -1509,20 +1488,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 26, - "h": 24 + "x": 8, + "y": 5, + "w": 24, + "h": 25 }, "frame": { "x": 226, - "y": 118, - "w": 26, - "h": 24 + "y": 119, + "w": 24, + "h": 25 } }, { - "filename": "482", + "filename": "426", "rotated": false, "trimmed": true, "sourceSize": { @@ -1530,20 +1509,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, + "x": 8, "y": 4, - "w": 26, + "w": 24, "h": 24 }, "frame": { "x": 226, - "y": 142, - "w": 26, + "y": 144, + "w": 24, "h": 24 } }, { - "filename": "450", + "filename": "450-f", "rotated": false, "trimmed": true, "sourceSize": { @@ -1563,27 +1542,6 @@ "h": 20 } }, - { - "filename": "482s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 4, - "w": 26, - "h": 24 - }, - "frame": { - "x": 226, - "y": 166, - "w": 26, - "h": 24 - } - }, { "filename": "469", "rotated": false, @@ -1732,7 +1690,7 @@ } }, { - "filename": "411", + "filename": "462", "rotated": false, "trimmed": true, "sourceSize": { @@ -1740,37 +1698,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 7, - "y": 5, + "x": 6, + "y": 4, "w": 26, - "h": 23 + "h": 24 }, "frame": { "x": 172, "y": 150, "w": 26, - "h": 23 - } - }, - { - "filename": "479-wash", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 28, - "h": 22 - }, - "frame": { - "x": 198, - "y": 168, - "w": 28, - "h": 22 + "h": 24 } }, { @@ -2131,7 +2068,7 @@ } }, { - "filename": "411s", + "filename": "411", "rotated": false, "trimmed": true, "sourceSize": { @@ -2215,7 +2152,7 @@ } }, { - "filename": "479-mow", + "filename": "462s", "rotated": false, "trimmed": true, "sourceSize": { @@ -2223,62 +2160,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 24, - "h": 25 + "x": 6, + "y": 4, + "w": 26, + "h": 24 }, "frame": { "x": 56, "y": 353, - "w": 24, - "h": 25 + "w": 26, + "h": 24 } }, { - "filename": "479s-mow", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 24, - "h": 25 - }, - "frame": { - "x": 28, - "y": 454, - "w": 24, - "h": 25 - } - }, - { - "filename": "395s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 23, - "h": 25 - }, - "frame": { - "x": 28, - "y": 479, - "w": 23, - "h": 25 - } - }, - { - "filename": "398", + "filename": "482", "rotated": false, "trimmed": true, "sourceSize": { @@ -2288,58 +2183,58 @@ "spriteSourceSize": { "x": 10, "y": 4, - "w": 23, - "h": 25 - }, - "frame": { - "x": 28, - "y": 504, - "w": 23, - "h": 25 - } - }, - { - "filename": "398s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 4, - "w": 23, - "h": 25 - }, - "frame": { - "x": 28, - "y": 529, - "w": 23, - "h": 25 - } - }, - { - "filename": "426", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 24, + "w": 26, "h": 24 }, "frame": { "x": 56, - "y": 378, - "w": 24, + "y": 377, + "w": 26, "h": 24 } }, + { + "filename": "482s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 4, + "w": 26, + "h": 24 + }, + "frame": { + "x": 28, + "y": 454, + "w": 26, + "h": 24 + } + }, + { + "filename": "411s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 26, + "h": 23 + }, + "frame": { + "x": 28, + "y": 478, + "w": 26, + "h": 23 + } + }, { "filename": "455", "rotated": false, @@ -2355,8 +2250,8 @@ "h": 23 }, "frame": { - "x": 53, - "y": 402, + "x": 28, + "y": 501, "w": 27, "h": 23 } @@ -2376,119 +2271,14 @@ "h": 23 }, "frame": { - "x": 53, - "y": 425, + "x": 28, + "y": 524, "w": 27, "h": 23 } }, { - "filename": "426s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 28, - "y": 554, - "w": 24, - "h": 24 - } - }, - { - "filename": "409", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 25, - "h": 23 - }, - "frame": { - "x": 28, - "y": 578, - "w": 25, - "h": 23 - } - }, - { - "filename": "409s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 25, - "h": 23 - }, - "frame": { - "x": 28, - "y": 601, - "w": 25, - "h": 23 - } - }, - { - "filename": "466", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 26, - "h": 23 - }, - "frame": { - "x": 28, - "y": 624, - "w": 26, - "h": 23 - } - }, - { - "filename": "492-land", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 12, - "w": 18, - "h": 16 - }, - "frame": { - "x": 40, - "y": 647, - "w": 18, - "h": 16 - } - }, - { - "filename": "416", + "filename": "471", "rotated": false, "trimmed": true, "sourceSize": { @@ -2497,15 +2287,78 @@ }, "spriteSourceSize": { "x": 6, - "y": 6, - "w": 26, - "h": 21 + "y": 5, + "w": 27, + "h": 23 }, "frame": { - "x": 172, - "y": 173, - "w": 26, - "h": 21 + "x": 28, + "y": 547, + "w": 27, + "h": 23 + } + }, + { + "filename": "471s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 27, + "h": 23 + }, + "frame": { + "x": 28, + "y": 570, + "w": 27, + "h": 23 + } + }, + { + "filename": "464", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 27, + "h": 22 + }, + "frame": { + "x": 28, + "y": 593, + "w": 27, + "h": 22 + } + }, + { + "filename": "464s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 27, + "h": 22 + }, + "frame": { + "x": 28, + "y": 615, + "w": 27, + "h": 22 } }, { @@ -2635,7 +2488,7 @@ } }, { - "filename": "471", + "filename": "479-wash", "rotated": false, "trimmed": true, "sourceSize": { @@ -2643,58 +2496,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 27, - "h": 23 - }, - "frame": { - "x": 141, - "y": 218, - "w": 27, - "h": 23 - } - }, - { - "filename": "471s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 27, - "h": 23 - }, - "frame": { - "x": 112, - "y": 262, - "w": 27, - "h": 23 - } - }, - { - "filename": "437", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, + "x": 8, "y": 6, - "w": 27, - "h": 21 + "w": 28, + "h": 22 }, "frame": { - "x": 141, - "y": 241, - "w": 27, - "h": 21 + "x": 170, + "y": 174, + "w": 28, + "h": 22 } }, { @@ -2712,14 +2523,35 @@ "h": 22 }, "frame": { - "x": 139, - "y": 262, + "x": 198, + "y": 168, "w": 28, "h": 22 } }, { - "filename": "464", + "filename": "426s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 226, + "y": 168, + "w": 24, + "h": 24 + } + }, + { + "filename": "466", "rotated": false, "trimmed": true, "sourceSize": { @@ -2728,19 +2560,187 @@ }, "spriteSourceSize": { "x": 7, + "y": 5, + "w": 26, + "h": 23 + }, + "frame": { + "x": 141, + "y": 218, + "w": 26, + "h": 23 + } + }, + { + "filename": "466s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 26, + "h": 23 + }, + "frame": { + "x": 112, + "y": 262, + "w": 26, + "h": 23 + } + }, + { + "filename": "473", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, "y": 6, "w": 27, "h": 22 }, "frame": { "x": 170, - "y": 194, + "y": 196, "w": 27, "h": 22 } }, { - "filename": "450-f", + "filename": "473s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 27, + "h": 22 + }, + "frame": { + "x": 167, + "y": 218, + "w": 27, + "h": 22 + } + }, + { + "filename": "416", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 26, + "h": 21 + }, + "frame": { + "x": 141, + "y": 241, + "w": 26, + "h": 21 + } + }, + { + "filename": "409", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 25, + "h": 23 + }, + "frame": { + "x": 138, + "y": 262, + "w": 25, + "h": 23 + } + }, + { + "filename": "428", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 167, + "y": 240, + "w": 26, + "h": 22 + } + }, + { + "filename": "409s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 25, + "h": 23 + }, + "frame": { + "x": 163, + "y": 262, + "w": 25, + "h": 23 + } + }, + { + "filename": "429", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 2, + "w": 19, + "h": 28 + }, + "frame": { + "x": 50, + "y": 637, + "w": 19, + "h": 28 + } + }, + { + "filename": "450", "rotated": false, "trimmed": true, "sourceSize": { @@ -2761,448 +2761,7 @@ } }, { - "filename": "464s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 27, - "h": 22 - }, - "frame": { - "x": 81, - "y": 308, - "w": 27, - "h": 22 - } - }, - { - "filename": "466s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 26, - "h": 23 - }, - "frame": { - "x": 81, - "y": 330, - "w": 26, - "h": 23 - } - }, - { - "filename": "473", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 27, - "h": 22 - }, - "frame": { - "x": 80, - "y": 353, - "w": 27, - "h": 22 - } - }, - { - "filename": "473s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 27, - "h": 22 - }, - "frame": { - "x": 80, - "y": 375, - "w": 27, - "h": 22 - } - }, - { - "filename": "428", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 80, - "y": 397, - "w": 26, - "h": 22 - } - }, - { - "filename": "428s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 80, - "y": 419, - "w": 26, - "h": 22 - } - }, - { - "filename": "416s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 26, - "h": 21 - }, - "frame": { - "x": 80, - "y": 441, - "w": 26, - "h": 21 - } - }, - { - "filename": "437s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 27, - "h": 21 - }, - "frame": { - "x": 53, - "y": 448, - "w": 27, - "h": 21 - } - }, - { - "filename": "450s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 28, - "h": 20 - }, - "frame": { - "x": 52, - "y": 469, - "w": 28, - "h": 20 - } - }, - { - "filename": "430", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 80, - "y": 462, - "w": 26, - "h": 22 - } - }, - { - "filename": "430s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 51, - "y": 489, - "w": 26, - "h": 22 - } - }, - { - "filename": "431", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 51, - "y": 511, - "w": 26, - "h": 22 - } - }, - { - "filename": "479-fan", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 26, - "h": 21 - }, - "frame": { - "x": 51, - "y": 533, - "w": 26, - "h": 21 - } - }, - { - "filename": "413-sandy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 52, - "y": 554, - "w": 24, - "h": 23 - } - }, - { - "filename": "429", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 19, - "h": 28 - }, - "frame": { - "x": 53, - "y": 577, - "w": 19, - "h": 28 - } - }, - { - "filename": "408", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 21, - "h": 19 - }, - "frame": { - "x": 53, - "y": 605, - "w": 21, - "h": 19 - } - }, - { - "filename": "391", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 22, - "h": 23 - }, - "frame": { - "x": 54, - "y": 624, - "w": 22, - "h": 23 - } - }, - { - "filename": "492s-land", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 12, - "w": 18, - "h": 16 - }, - "frame": { - "x": 58, - "y": 647, - "w": 18, - "h": 16 - } - }, - { - "filename": "429s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 19, - "h": 28 - }, - "frame": { - "x": 72, - "y": 577, - "w": 19, - "h": 28 - } - }, - { - "filename": "391s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 22, - "h": 23 - }, - "frame": { - "x": 76, - "y": 554, - "w": 22, - "h": 23 - } - }, - { - "filename": "408s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 21, - "h": 19 - }, - "frame": { - "x": 74, - "y": 605, - "w": 21, - "h": 19 - } - }, - { - "filename": "475", + "filename": "395s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3212,13 +2771,76 @@ "spriteSourceSize": { "x": 10, "y": 3, - "w": 22, + "w": 23, "h": 25 }, "frame": { - "x": 76, - "y": 624, - "w": 22, + "x": 81, + "y": 308, + "w": 23, + "h": 25 + } + }, + { + "filename": "414", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 25, + "h": 20 + }, + "frame": { + "x": 81, + "y": 333, + "w": 25, + "h": 20 + } + }, + { + "filename": "398", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 4, + "w": 23, + "h": 25 + }, + "frame": { + "x": 82, + "y": 353, + "w": 23, + "h": 25 + } + }, + { + "filename": "398s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 4, + "w": 23, + "h": 25 + }, + "frame": { + "x": 82, + "y": 378, + "w": 23, "h": 25 } }, @@ -3244,7 +2866,7 @@ } }, { - "filename": "431s", + "filename": "413-sandy", "rotated": false, "trimmed": true, "sourceSize": { @@ -3252,15 +2874,57 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 26, - "h": 22 + "x": 9, + "y": 5, + "w": 24, + "h": 23 }, "frame": { "x": 226, - "y": 190, - "w": 26, + "y": 192, + "w": 24, + "h": 23 + } + }, + { + "filename": "450s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 28, + "h": 20 + }, + "frame": { + "x": 197, + "y": 210, + "w": 28, + "h": 20 + } + }, + { + "filename": "467", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 225, + "y": 215, + "w": 25, "h": 22 } }, @@ -3279,159 +2943,12 @@ "h": 19 }, "frame": { - "x": 197, - "y": 210, + "x": 194, + "y": 230, "w": 28, "h": 19 } }, - { - "filename": "434", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 26, - "h": 19 - }, - "frame": { - "x": 225, - "y": 212, - "w": 26, - "h": 19 - } - }, - { - "filename": "475s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 22, - "h": 25 - }, - "frame": { - "x": 91, - "y": 577, - "w": 22, - "h": 25 - } - }, - { - "filename": "387s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 18, - "h": 22 - }, - "frame": { - "x": 95, - "y": 602, - "w": 18, - "h": 22 - } - }, - { - "filename": "402", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 4, - "w": 20, - "h": 24 - }, - "frame": { - "x": 98, - "y": 624, - "w": 20, - "h": 24 - } - }, - { - "filename": "434s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 26, - "h": 19 - }, - "frame": { - "x": 80, - "y": 484, - "w": 26, - "h": 19 - } - }, - { - "filename": "480", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 77, - "y": 503, - "w": 26, - "h": 22 - } - }, - { - "filename": "480s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 77, - "y": 525, - "w": 26, - "h": 22 - } - }, { "filename": "468s", "rotated": false, @@ -3447,14 +2964,77 @@ "h": 19 }, "frame": { - "x": 112, - "y": 285, + "x": 222, + "y": 237, "w": 28, "h": 19 } }, { - "filename": "479s-fan", + "filename": "437", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 27, + "h": 21 + }, + "frame": { + "x": 193, + "y": 249, + "w": 27, + "h": 21 + } + }, + { + "filename": "437s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 27, + "h": 21 + }, + "frame": { + "x": 220, + "y": 256, + "w": 27, + "h": 21 + } + }, + { + "filename": "416s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 26, + "h": 21 + }, + "frame": { + "x": 188, + "y": 270, + "w": 26, + "h": 21 + } + }, + { + "filename": "428s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3463,19 +3043,19 @@ }, "spriteSourceSize": { "x": 8, - "y": 7, + "y": 6, "w": 26, - "h": 21 + "h": 22 }, "frame": { - "x": 140, - "y": 284, + "x": 214, + "y": 277, "w": 26, - "h": 21 + "h": 22 } }, { - "filename": "414", + "filename": "475", "rotated": false, "trimmed": true, "sourceSize": { @@ -3484,57 +3064,15 @@ }, "spriteSourceSize": { "x": 10, - "y": 7, - "w": 25, - "h": 20 + "y": 3, + "w": 22, + "h": 25 }, "frame": { - "x": 111, - "y": 304, - "w": 25, - "h": 20 - } - }, - { - "filename": "414s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 25, - "h": 20 - }, - "frame": { - "x": 136, - "y": 305, - "w": 25, - "h": 20 - } - }, - { - "filename": "415", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 25, - "h": 18 - }, - "frame": { - "x": 108, - "y": 324, - "w": 25, - "h": 18 + "x": 104, + "y": 308, + "w": 22, + "h": 25 } }, { @@ -3552,12 +3090,243 @@ "h": 23 }, "frame": { - "x": 107, - "y": 342, + "x": 112, + "y": 285, "w": 24, "h": 23 } }, + { + "filename": "430", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 136, + "y": 285, + "w": 26, + "h": 22 + } + }, + { + "filename": "430s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 162, + "y": 285, + "w": 26, + "h": 22 + } + }, + { + "filename": "431", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 188, + "y": 291, + "w": 26, + "h": 22 + } + }, + { + "filename": "388", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 7, + "w": 22, + "h": 21 + }, + "frame": { + "x": 106, + "y": 333, + "w": 22, + "h": 21 + } + }, + { + "filename": "429s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 2, + "w": 19, + "h": 28 + }, + "frame": { + "x": 105, + "y": 354, + "w": 19, + "h": 28 + } + }, + { + "filename": "388s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 7, + "w": 22, + "h": 21 + }, + "frame": { + "x": 105, + "y": 382, + "w": 22, + "h": 21 + } + }, + { + "filename": "431s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 214, + "y": 299, + "w": 26, + "h": 22 + } + }, + { + "filename": "475s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 3, + "w": 22, + "h": 25 + }, + "frame": { + "x": 126, + "y": 308, + "w": 22, + "h": 25 + } + }, + { + "filename": "480", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 148, + "y": 307, + "w": 26, + "h": 22 + } + }, + { + "filename": "391", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 22, + "h": 23 + }, + "frame": { + "x": 128, + "y": 333, + "w": 22, + "h": 23 + } + }, + { + "filename": "480s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 124, + "y": 356, + "w": 26, + "h": 22 + } + }, { "filename": "476", "rotated": false, @@ -3573,138 +3342,12 @@ "h": 23 }, "frame": { - "x": 107, - "y": 365, + "x": 150, + "y": 329, "w": 24, "h": 23 } }, - { - "filename": "415s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 25, - "h": 18 - }, - "frame": { - "x": 133, - "y": 325, - "w": 25, - "h": 18 - } - }, - { - "filename": "467", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 131, - "y": 343, - "w": 25, - "h": 22 - } - }, - { - "filename": "467s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 131, - "y": 365, - "w": 25, - "h": 22 - } - }, - { - "filename": "403", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 7, - "w": 24, - "h": 21 - }, - "frame": { - "x": 107, - "y": 388, - "w": 24, - "h": 21 - } - }, - { - "filename": "470", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 131, - "y": 387, - "w": 25, - "h": 22 - } - }, - { - "filename": "470s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 106, - "y": 409, - "w": 25, - "h": 22 - } - }, { "filename": "476s", "rotated": false, @@ -3720,8 +3363,8 @@ "h": 23 }, "frame": { - "x": 106, - "y": 431, + "x": 150, + "y": 352, "w": 24, "h": 23 } @@ -3741,8 +3384,8 @@ "h": 23 }, "frame": { - "x": 106, - "y": 454, + "x": 127, + "y": 378, "w": 23, "h": 23 } @@ -3762,12 +3405,222 @@ "h": 23 }, "frame": { - "x": 106, - "y": 477, + "x": 150, + "y": 375, "w": 23, "h": 23 } }, + { + "filename": "439", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 14, + "h": 21 + }, + "frame": { + "x": 174, + "y": 307, + "w": 14, + "h": 21 + } + }, + { + "filename": "434", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 9, + "w": 26, + "h": 19 + }, + "frame": { + "x": 188, + "y": 313, + "w": 26, + "h": 19 + } + }, + { + "filename": "439s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 14, + "h": 21 + }, + "frame": { + "x": 174, + "y": 328, + "w": 14, + "h": 21 + } + }, + { + "filename": "434s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 9, + "w": 26, + "h": 19 + }, + "frame": { + "x": 188, + "y": 332, + "w": 26, + "h": 19 + } + }, + { + "filename": "467s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 214, + "y": 321, + "w": 25, + "h": 22 + } + }, + { + "filename": "440", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 9, + "w": 14, + "h": 19 + }, + "frame": { + "x": 174, + "y": 349, + "w": 14, + "h": 19 + } + }, + { + "filename": "479-fan", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 26, + "h": 21 + }, + "frame": { + "x": 188, + "y": 351, + "w": 26, + "h": 21 + } + }, + { + "filename": "470", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 214, + "y": 343, + "w": 25, + "h": 22 + } + }, + { + "filename": "414s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 25, + "h": 20 + }, + "frame": { + "x": 214, + "y": 365, + "w": 25, + "h": 20 + } + }, + { + "filename": "479s-fan", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 26, + "h": 21 + }, + "frame": { + "x": 56, + "y": 401, + "w": 26, + "h": 21 + } + }, { "filename": "419", "rotated": false, @@ -3783,14 +3636,14 @@ "h": 21 }, "frame": { - "x": 131, - "y": 409, + "x": 82, + "y": 403, "w": 25, "h": 21 } }, { - "filename": "402s", + "filename": "470s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3798,20 +3651,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, - "y": 4, - "w": 20, - "h": 24 + "x": 8, + "y": 6, + "w": 25, + "h": 22 }, "frame": { - "x": 103, - "y": 503, - "w": 20, - "h": 24 + "x": 53, + "y": 422, + "w": 25, + "h": 22 } }, { - "filename": "388", + "filename": "391s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3820,141 +3673,15 @@ }, "spriteSourceSize": { "x": 9, - "y": 7, - "w": 22, - "h": 21 - }, - "frame": { - "x": 103, - "y": 527, - "w": 22, - "h": 21 - } - }, - { - "filename": "419s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 25, - "h": 21 - }, - "frame": { - "x": 98, - "y": 548, - "w": 25, - "h": 21 - } - }, - { - "filename": "448-mega", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 4, - "w": 19, - "h": 24 - }, - "frame": { - "x": 123, - "y": 500, - "w": 19, - "h": 24 - } - }, - { - "filename": "448s-mega", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 4, - "w": 19, - "h": 24 - }, - "frame": { - "x": 125, - "y": 524, - "w": 19, - "h": 24 - } - }, - { - "filename": "388s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 7, - "w": 22, - "h": 21 - }, - "frame": { - "x": 123, - "y": 548, - "w": 22, - "h": 21 - } - }, - { - "filename": "451", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, "y": 6, - "w": 24, - "h": 22 + "w": 22, + "h": 23 }, "frame": { - "x": 113, - "y": 569, - "w": 24, - "h": 22 - } - }, - { - "filename": "451s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 24, - "h": 22 - }, - "frame": { - "x": 113, - "y": 591, - "w": 24, - "h": 22 + "x": 107, + "y": 403, + "w": 22, + "h": 23 } }, { @@ -3972,8 +3699,8 @@ "h": 23 }, "frame": { - "x": 137, - "y": 569, + "x": 129, + "y": 401, "w": 22, "h": 23 } @@ -3993,14 +3720,14 @@ "h": 23 }, "frame": { - "x": 137, - "y": 592, + "x": 151, + "y": 398, "w": 22, "h": 23 } }, { - "filename": "390", + "filename": "419s", "rotated": false, "trimmed": true, "sourceSize": { @@ -4008,20 +3735,62 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, + "x": 10, + "y": 7, + "w": 25, + "h": 21 + }, + "frame": { + "x": 78, + "y": 424, + "w": 25, + "h": 21 + } + }, + { + "filename": "403", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 7, + "w": 24, + "h": 21 + }, + "frame": { + "x": 103, + "y": 426, + "w": 24, + "h": 21 + } + }, + { + "filename": "451", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, "y": 6, - "w": 19, + "w": 24, "h": 22 }, "frame": { - "x": 118, - "y": 613, - "w": 19, + "x": 54, + "y": 444, + "w": 24, "h": 22 } }, { - "filename": "400", + "filename": "451s", "rotated": false, "trimmed": true, "sourceSize": { @@ -4029,57 +3798,15 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, + "x": 7, "y": 6, - "w": 22, + "w": 24, "h": 22 }, "frame": { - "x": 137, - "y": 615, - "w": 22, - "h": 22 - } - }, - { - "filename": "390s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 19, - "h": 22 - }, - "frame": { - "x": 118, - "y": 635, - "w": 19, - "h": 22 - } - }, - { - "filename": "400s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 22, - "h": 22 - }, - "frame": { - "x": 137, - "y": 637, - "w": 22, + "x": 54, + "y": 466, + "w": 24, "h": 22 } }, @@ -4098,159 +3825,12 @@ "h": 21 }, "frame": { - "x": 170, - "y": 216, + "x": 78, + "y": 445, "w": 24, "h": 21 } }, - { - "filename": "413-plant", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 168, - "y": 237, - "w": 22, - "h": 23 - } - }, - { - "filename": "449", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 10, - "w": 24, - "h": 18 - }, - "frame": { - "x": 194, - "y": 229, - "w": 24, - "h": 18 - } - }, - { - "filename": "449-f", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 10, - "w": 24, - "h": 18 - }, - "frame": { - "x": 218, - "y": 231, - "w": 24, - "h": 18 - } - }, - { - "filename": "449s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 10, - "w": 24, - "h": 18 - }, - "frame": { - "x": 190, - "y": 247, - "w": 24, - "h": 18 - } - }, - { - "filename": "449s-f", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 10, - "w": 24, - "h": 18 - }, - "frame": { - "x": 214, - "y": 249, - "w": 24, - "h": 18 - } - }, - { - "filename": "439", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 14, - "h": 21 - }, - "frame": { - "x": 238, - "y": 249, - "w": 14, - "h": 21 - } - }, - { - "filename": "413s-plant", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 168, - "y": 260, - "w": 22, - "h": 23 - } - }, { "filename": "423-east", "rotated": false, @@ -4266,8 +3846,8 @@ "h": 22 }, "frame": { - "x": 190, - "y": 265, + "x": 78, + "y": 466, "w": 23, "h": 22 } @@ -4287,33 +3867,12 @@ "h": 22 }, "frame": { - "x": 213, - "y": 267, + "x": 102, + "y": 447, "w": 23, "h": 22 } }, - { - "filename": "412-trash", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 5, - "w": 16, - "h": 23 - }, - "frame": { - "x": 236, - "y": 270, - "w": 16, - "h": 23 - } - }, { "filename": "423s-east", "rotated": false, @@ -4329,14 +3888,14 @@ "h": 22 }, "frame": { - "x": 167, - "y": 283, + "x": 101, + "y": 469, "w": 23, "h": 22 } }, { - "filename": "423s-west", + "filename": "413-plant", "rotated": false, "trimmed": true, "sourceSize": { @@ -4344,62 +3903,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 190, - "y": 287, - "w": 23, - "h": 22 - } - }, - { - "filename": "432", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 23, - "h": 21 - }, - "frame": { - "x": 213, - "y": 289, - "w": 23, - "h": 21 - } - }, - { - "filename": "412s-trash", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, + "x": 9, "y": 5, - "w": 16, + "w": 22, "h": 23 }, "frame": { - "x": 236, - "y": 293, - "w": 16, + "x": 55, + "y": 488, + "w": 22, "h": 23 } }, { - "filename": "432s", + "filename": "413s-plant", "rotated": false, "trimmed": true, "sourceSize": { @@ -4407,37 +3924,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 23, - "h": 21 + "x": 9, + "y": 5, + "w": 22, + "h": 23 }, "frame": { - "x": 161, - "y": 305, - "w": 23, - "h": 21 - } - }, - { - "filename": "433", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 23, - "h": 19 - }, - "frame": { - "x": 158, - "y": 326, - "w": 23, - "h": 19 + "x": 77, + "y": 488, + "w": 22, + "h": 23 } }, { @@ -4455,8 +3951,8 @@ "h": 23 }, "frame": { - "x": 156, - "y": 345, + "x": 55, + "y": 511, "w": 22, "h": 23 } @@ -4476,12 +3972,33 @@ "h": 23 }, "frame": { - "x": 156, - "y": 368, + "x": 77, + "y": 511, "w": 22, "h": 23 } }, + { + "filename": "423s-west", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 23, + "h": 22 + }, + "frame": { + "x": 55, + "y": 534, + "w": 23, + "h": 22 + } + }, { "filename": "457", "rotated": false, @@ -4497,75 +4014,12 @@ "h": 23 }, "frame": { - "x": 156, - "y": 391, + "x": 55, + "y": 556, "w": 22, "h": 23 } }, - { - "filename": "433s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 23, - "h": 19 - }, - "frame": { - "x": 156, - "y": 414, - "w": 23, - "h": 19 - } - }, - { - "filename": "444", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 23, - "h": 21 - }, - "frame": { - "x": 184, - "y": 309, - "w": 23, - "h": 21 - } - }, - { - "filename": "444s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 23, - "h": 21 - }, - "frame": { - "x": 207, - "y": 310, - "w": 23, - "h": 21 - } - }, { "filename": "457s", "rotated": false, @@ -4581,33 +4035,12 @@ "h": 23 }, "frame": { - "x": 230, - "y": 316, + "x": 55, + "y": 579, "w": 22, "h": 23 } }, - { - "filename": "489", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 11, - "w": 23, - "h": 17 - }, - "frame": { - "x": 181, - "y": 330, - "w": 23, - "h": 17 - } - }, { "filename": "463", "rotated": false, @@ -4623,12 +4056,33 @@ "h": 23 }, "frame": { - "x": 178, - "y": 347, + "x": 55, + "y": 602, "w": 22, "h": 23 } }, + { + "filename": "400", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 22, + "h": 22 + }, + "frame": { + "x": 78, + "y": 534, + "w": 22, + "h": 22 + } + }, { "filename": "463s", "rotated": false, @@ -4644,14 +4098,77 @@ "h": 23 }, "frame": { - "x": 178, - "y": 370, + "x": 77, + "y": 556, "w": 22, "h": 23 } }, { - "filename": "474", + "filename": "400s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 22, + "h": 22 + }, + "frame": { + "x": 77, + "y": 579, + "w": 22, + "h": 22 + } + }, + { + "filename": "402", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 4, + "w": 20, + "h": 24 + }, + "frame": { + "x": 77, + "y": 601, + "w": 20, + "h": 24 + } + }, + { + "filename": "402s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 4, + "w": 20, + "h": 24 + }, + "frame": { + "x": 99, + "y": 491, + "w": 20, + "h": 24 + } + }, + { + "filename": "408", "rotated": false, "trimmed": true, "sourceSize": { @@ -4660,15 +4177,15 @@ }, "spriteSourceSize": { "x": 9, - "y": 6, + "y": 9, "w": 21, - "h": 21 + "h": 19 }, "frame": { - "x": 178, - "y": 393, + "x": 99, + "y": 515, "w": 21, - "h": 21 + "h": 19 } }, { @@ -4686,33 +4203,12 @@ "h": 22 }, "frame": { - "x": 179, - "y": 414, + "x": 100, + "y": 534, "w": 20, "h": 22 } }, - { - "filename": "489s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 11, - "w": 23, - "h": 17 - }, - "frame": { - "x": 204, - "y": 331, - "w": 23, - "h": 17 - } - }, { "filename": "460", "rotated": false, @@ -4728,8 +4224,8 @@ "h": 23 }, "frame": { - "x": 200, - "y": 348, + "x": 99, + "y": 556, "w": 21, "h": 23 } @@ -4749,12 +4245,117 @@ "h": 22 }, "frame": { - "x": 200, - "y": 371, + "x": 99, + "y": 579, "w": 21, "h": 22 } }, + { + "filename": "432", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 23, + "h": 21 + }, + "frame": { + "x": 97, + "y": 601, + "w": 23, + "h": 21 + } + }, + { + "filename": "432s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 23, + "h": 21 + }, + "frame": { + "x": 69, + "y": 625, + "w": 23, + "h": 21 + } + }, + { + "filename": "433", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 23, + "h": 19 + }, + "frame": { + "x": 69, + "y": 646, + "w": 23, + "h": 19 + } + }, + { + "filename": "448-mega", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 4, + "w": 19, + "h": 24 + }, + "frame": { + "x": 119, + "y": 491, + "w": 19, + "h": 24 + } + }, + { + "filename": "448s-mega", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 4, + "w": 19, + "h": 24 + }, + "frame": { + "x": 120, + "y": 515, + "w": 19, + "h": 24 + } + }, { "filename": "460s", "rotated": false, @@ -4770,285 +4371,12 @@ "h": 23 }, "frame": { - "x": 199, - "y": 393, + "x": 120, + "y": 539, "w": 21, "h": 23 } }, - { - "filename": "418", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 21, - "h": 20 - }, - "frame": { - "x": 199, - "y": 416, - "w": 21, - "h": 20 - } - }, - { - "filename": "412-sandy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 5, - "w": 15, - "h": 23 - }, - "frame": { - "x": 221, - "y": 348, - "w": 15, - "h": 23 - } - }, - { - "filename": "478", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 16, - "h": 22 - }, - "frame": { - "x": 236, - "y": 339, - "w": 16, - "h": 22 - } - }, - { - "filename": "478s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 16, - "h": 22 - }, - "frame": { - "x": 236, - "y": 361, - "w": 16, - "h": 22 - } - }, - { - "filename": "412s-sandy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 5, - "w": 15, - "h": 23 - }, - "frame": { - "x": 221, - "y": 371, - "w": 15, - "h": 23 - } - }, - { - "filename": "448", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 7, - "w": 16, - "h": 21 - }, - "frame": { - "x": 236, - "y": 383, - "w": 16, - "h": 21 - } - }, - { - "filename": "448s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 7, - "w": 16, - "h": 21 - }, - "frame": { - "x": 220, - "y": 394, - "w": 16, - "h": 21 - } - }, - { - "filename": "421-overcast", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 16, - "h": 20 - }, - "frame": { - "x": 236, - "y": 404, - "w": 16, - "h": 20 - } - }, - { - "filename": "421s-overcast", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 16, - "h": 20 - }, - "frame": { - "x": 220, - "y": 415, - "w": 16, - "h": 20 - } - }, - { - "filename": "425", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 15, - "h": 22 - }, - "frame": { - "x": 236, - "y": 424, - "w": 15, - "h": 22 - } - }, - { - "filename": "394", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 17, - "h": 22 - }, - "frame": { - "x": 129, - "y": 454, - "w": 17, - "h": 22 - } - }, - { - "filename": "394s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 17, - "h": 22 - }, - "frame": { - "x": 129, - "y": 476, - "w": 17, - "h": 22 - } - }, - { - "filename": "421-sunshine", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 20, - "h": 21 - }, - "frame": { - "x": 130, - "y": 433, - "w": 20, - "h": 21 - } - }, { "filename": "454s", "rotated": false, @@ -5064,8 +4392,8 @@ "h": 22 }, "frame": { - "x": 150, - "y": 433, + "x": 120, + "y": 562, "w": 21, "h": 22 } @@ -5085,14 +4413,77 @@ "h": 22 }, "frame": { - "x": 146, - "y": 455, + "x": 120, + "y": 584, "w": 21, "h": 22 } }, { - "filename": "474s", + "filename": "387s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 124, + "y": 469, + "w": 18, + "h": 22 + } + }, + { + "filename": "390", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 19, + "h": 22 + }, + "frame": { + "x": 125, + "y": 447, + "w": 19, + "h": 22 + } + }, + { + "filename": "421-sunshine", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 7, + "w": 20, + "h": 21 + }, + "frame": { + "x": 127, + "y": 426, + "w": 20, + "h": 21 + } + }, + { + "filename": "408s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5101,19 +4492,19 @@ }, "spriteSourceSize": { "x": 9, - "y": 6, + "y": 9, "w": 21, - "h": 21 + "h": 19 }, "frame": { - "x": 146, - "y": 477, + "x": 120, + "y": 606, "w": 21, - "h": 21 + "h": 19 } }, { - "filename": "492s-sky", + "filename": "433s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5121,20 +4512,41 @@ "h": 30 }, "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 21, - "h": 22 + "x": 12, + "y": 9, + "w": 23, + "h": 19 }, "frame": { - "x": 142, - "y": 498, - "w": 21, - "h": 22 + "x": 97, + "y": 622, + "w": 23, + "h": 19 } }, { - "filename": "407s", + "filename": "444", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 23, + "h": 21 + }, + "frame": { + "x": 92, + "y": 641, + "w": 23, + "h": 21 + } + }, + { + "filename": "418", "rotated": false, "trimmed": true, "sourceSize": { @@ -5143,36 +4555,15 @@ }, "spriteSourceSize": { "x": 10, - "y": 6, - "w": 20, - "h": 22 + "y": 8, + "w": 21, + "h": 20 }, "frame": { - "x": 144, - "y": 520, - "w": 20, - "h": 22 - } - }, - { - "filename": "441", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 20, - "h": 22 - }, - "frame": { - "x": 145, - "y": 542, - "w": 20, - "h": 22 + "x": 120, + "y": 625, + "w": 21, + "h": 20 } }, { @@ -5190,8 +4581,8 @@ "h": 20 }, "frame": { - "x": 171, - "y": 436, + "x": 115, + "y": 645, "w": 22, "h": 20 } @@ -5211,14 +4602,14 @@ "h": 20 }, "frame": { - "x": 193, - "y": 436, + "x": 137, + "y": 645, "w": 22, "h": 20 } }, { - "filename": "441s", + "filename": "412-sandy", "rotated": false, "trimmed": true, "sourceSize": { @@ -5226,104 +4617,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 20, - "h": 22 + "x": 13, + "y": 5, + "w": 15, + "h": 23 }, "frame": { - "x": 167, - "y": 456, - "w": 20, - "h": 22 + "x": 138, + "y": 491, + "w": 15, + "h": 23 } }, { - "filename": "418s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 21, - "h": 20 - }, - "frame": { - "x": 187, - "y": 456, - "w": 21, - "h": 20 - } - }, - { - "filename": "410", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 20, - "h": 20 - }, - "frame": { - "x": 167, - "y": 478, - "w": 20, - "h": 20 - } - }, - { - "filename": "461", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 19, - "h": 22 - }, - "frame": { - "x": 163, - "y": 498, - "w": 19, - "h": 22 - } - }, - { - "filename": "421s-sunshine", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 20, - "h": 21 - }, - "frame": { - "x": 187, - "y": 476, - "w": 20, - "h": 21 - } - }, - { - "filename": "427", + "filename": "412-trash", "rotated": false, "trimmed": true, "sourceSize": { @@ -5332,14 +4639,119 @@ }, "spriteSourceSize": { "x": 12, + "y": 5, + "w": 16, + "h": 23 + }, + "frame": { + "x": 139, + "y": 514, + "w": 16, + "h": 23 + } + }, + { + "filename": "390s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, "y": 6, - "w": 18, + "w": 19, "h": 22 }, "frame": { - "x": 164, - "y": 520, - "w": 18, + "x": 142, + "y": 469, + "w": 19, + "h": 22 + } + }, + { + "filename": "394", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 17, + "h": 22 + }, + "frame": { + "x": 144, + "y": 447, + "w": 17, + "h": 22 + } + }, + { + "filename": "412s-sandy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 5, + "w": 15, + "h": 23 + }, + "frame": { + "x": 147, + "y": 424, + "w": 15, + "h": 23 + } + }, + { + "filename": "412s-trash", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 5, + "w": 16, + "h": 23 + }, + "frame": { + "x": 141, + "y": 537, + "w": 16, + "h": 23 + } + }, + { + "filename": "394s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 17, + "h": 22 + }, + "frame": { + "x": 141, + "y": 560, + "w": 17, "h": 22 } }, @@ -5358,138 +4770,12 @@ "h": 22 }, "frame": { - "x": 165, - "y": 542, + "x": 141, + "y": 582, "w": 17, "h": 22 } }, - { - "filename": "442", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 21, - "h": 20 - }, - "frame": { - "x": 159, - "y": 564, - "w": 21, - "h": 20 - } - }, - { - "filename": "442s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 21, - "h": 20 - }, - "frame": { - "x": 159, - "y": 584, - "w": 21, - "h": 20 - } - }, - { - "filename": "459", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 21, - "h": 20 - }, - "frame": { - "x": 159, - "y": 604, - "w": 21, - "h": 20 - } - }, - { - "filename": "459s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 21, - "h": 20 - }, - "frame": { - "x": 159, - "y": 624, - "w": 21, - "h": 20 - } - }, - { - "filename": "443", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 19, - "h": 19 - }, - "frame": { - "x": 159, - "y": 644, - "w": 19, - "h": 19 - } - }, - { - "filename": "443s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 19, - "h": 19 - }, - "frame": { - "x": 178, - "y": 644, - "w": 19, - "h": 19 - } - }, { "filename": "401s", "rotated": false, @@ -5505,14 +4791,35 @@ "h": 22 }, "frame": { - "x": 208, - "y": 456, + "x": 141, + "y": 604, "w": 17, "h": 22 } }, { - "filename": "410s", + "filename": "443", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 9, + "w": 19, + "h": 19 + }, + "frame": { + "x": 141, + "y": 626, + "w": 19, + "h": 19 + } + }, + { + "filename": "418s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5522,18 +4829,18 @@ "spriteSourceSize": { "x": 10, "y": 8, - "w": 20, + "w": 21, "h": 20 }, "frame": { - "x": 207, - "y": 478, - "w": 20, + "x": 159, + "y": 645, + "w": 21, "h": 20 } }, { - "filename": "422-east", + "filename": "407s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5541,20 +4848,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 19, - "h": 20 + "x": 10, + "y": 6, + "w": 20, + "h": 22 }, "frame": { - "x": 215, - "y": 436, - "w": 19, - "h": 20 + "x": 153, + "y": 491, + "w": 20, + "h": 22 } }, { - "filename": "427s", + "filename": "427", "rotated": false, "trimmed": true, "sourceSize": { @@ -5568,8 +4875,8 @@ "h": 22 }, "frame": { - "x": 234, - "y": 446, + "x": 155, + "y": 513, "w": 18, "h": 22 } @@ -5589,8 +4896,8 @@ "h": 22 }, "frame": { - "x": 182, - "y": 498, + "x": 157, + "y": 535, "w": 17, "h": 22 } @@ -5610,14 +4917,35 @@ "h": 22 }, "frame": { - "x": 182, - "y": 520, + "x": 158, + "y": 557, "w": 17, "h": 22 } }, { - "filename": "461s", + "filename": "427s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 158, + "y": 579, + "w": 18, + "h": 22 + } + }, + { + "filename": "441", "rotated": false, "trimmed": true, "sourceSize": { @@ -5627,18 +4955,18 @@ "spriteSourceSize": { "x": 10, "y": 6, - "w": 19, + "w": 20, "h": 22 }, "frame": { - "x": 182, - "y": 542, - "w": 19, + "x": 158, + "y": 601, + "w": 20, "h": 22 } }, { - "filename": "494", + "filename": "441s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5646,62 +4974,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, + "x": 10, "y": 6, - "w": 18, + "w": 20, "h": 22 }, "frame": { - "x": 180, - "y": 564, - "w": 18, + "x": 160, + "y": 623, + "w": 20, "h": 22 } }, { - "filename": "494s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 18, - "h": 22 - }, - "frame": { - "x": 180, - "y": 586, - "w": 18, - "h": 22 - } - }, - { - "filename": "422s-east", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 180, - "y": 608, - "w": 19, - "h": 20 - } - }, - { - "filename": "436", + "filename": "425", "rotated": false, "trimmed": true, "sourceSize": { @@ -5710,19 +4996,19 @@ }, "spriteSourceSize": { "x": 13, - "y": 12, - "w": 13, - "h": 16 + "y": 7, + "w": 15, + "h": 22 }, "frame": { - "x": 180, - "y": 628, - "w": 13, - "h": 16 + "x": 162, + "y": 421, + "w": 15, + "h": 22 } }, { - "filename": "456", + "filename": "440s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5730,20 +5016,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, + "x": 13, "y": 9, - "w": 20, - "h": 18 + "w": 14, + "h": 19 }, "frame": { - "x": 199, - "y": 498, - "w": 20, - "h": 18 + "x": 174, + "y": 368, + "w": 14, + "h": 19 } }, { - "filename": "456s", + "filename": "449-f", "rotated": false, "trimmed": true, "sourceSize": { @@ -5751,15 +5037,15 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 20, + "x": 8, + "y": 10, + "w": 24, "h": 18 }, "frame": { - "x": 199, - "y": 516, - "w": 20, + "x": 188, + "y": 372, + "w": 24, "h": 18 } }, @@ -5778,12 +5064,369 @@ "h": 22 }, "frame": { - "x": 219, - "y": 498, + "x": 173, + "y": 387, "w": 15, "h": 22 } }, + { + "filename": "444s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 23, + "h": 21 + }, + "frame": { + "x": 188, + "y": 390, + "w": 23, + "h": 21 + } + }, + { + "filename": "449", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 10, + "w": 24, + "h": 18 + }, + "frame": { + "x": 212, + "y": 385, + "w": 24, + "h": 18 + } + }, + { + "filename": "446", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 9, + "w": 14, + "h": 19 + }, + "frame": { + "x": 236, + "y": 385, + "w": 14, + "h": 19 + } + }, + { + "filename": "449s-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 10, + "w": 24, + "h": 18 + }, + "frame": { + "x": 211, + "y": 403, + "w": 24, + "h": 18 + } + }, + { + "filename": "446s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 9, + "w": 14, + "h": 19 + }, + "frame": { + "x": 235, + "y": 404, + "w": 14, + "h": 19 + } + }, + { + "filename": "461", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 19, + "h": 22 + }, + "frame": { + "x": 161, + "y": 447, + "w": 19, + "h": 22 + } + }, + { + "filename": "461s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 19, + "h": 22 + }, + "frame": { + "x": 161, + "y": 469, + "w": 19, + "h": 22 + } + }, + { + "filename": "478", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 16, + "h": 22 + }, + "frame": { + "x": 173, + "y": 491, + "w": 16, + "h": 22 + } + }, + { + "filename": "478s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 16, + "h": 22 + }, + "frame": { + "x": 173, + "y": 513, + "w": 16, + "h": 22 + } + }, + { + "filename": "492s-sky", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 21, + "h": 22 + }, + "frame": { + "x": 174, + "y": 535, + "w": 21, + "h": 22 + } + }, + { + "filename": "421s-sunshine", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 7, + "w": 20, + "h": 21 + }, + "frame": { + "x": 175, + "y": 557, + "w": 20, + "h": 21 + } + }, + { + "filename": "474", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 176, + "y": 578, + "w": 21, + "h": 21 + } + }, + { + "filename": "474s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 178, + "y": 599, + "w": 21, + "h": 21 + } + }, + { + "filename": "410", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 20, + "h": 20 + }, + "frame": { + "x": 180, + "y": 620, + "w": 20, + "h": 20 + } + }, + { + "filename": "410s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 20, + "h": 20 + }, + "frame": { + "x": 180, + "y": 640, + "w": 20, + "h": 20 + } + }, + { + "filename": "421-overcast", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 16, + "h": 20 + }, + "frame": { + "x": 195, + "y": 411, + "w": 16, + "h": 20 + } + }, + { + "filename": "449s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 10, + "w": 24, + "h": 18 + }, + "frame": { + "x": 211, + "y": 421, + "w": 24, + "h": 18 + } + }, { "filename": "420", "rotated": false, @@ -5799,8 +5442,8 @@ "h": 18 }, "frame": { - "x": 234, - "y": 468, + "x": 177, + "y": 411, "w": 18, "h": 18 } @@ -5820,12 +5463,117 @@ "h": 18 }, "frame": { - "x": 234, - "y": 486, + "x": 177, + "y": 429, "w": 18, "h": 18 } }, + { + "filename": "421s-overcast", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 16, + "h": 20 + }, + "frame": { + "x": 195, + "y": 431, + "w": 16, + "h": 20 + } + }, + { + "filename": "489", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 11, + "w": 23, + "h": 17 + }, + "frame": { + "x": 211, + "y": 439, + "w": 23, + "h": 17 + } + }, + { + "filename": "448", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 7, + "w": 16, + "h": 21 + }, + "frame": { + "x": 234, + "y": 439, + "w": 16, + "h": 21 + } + }, + { + "filename": "436", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 12, + "w": 13, + "h": 16 + }, + "frame": { + "x": 235, + "y": 423, + "w": 13, + "h": 16 + } + }, + { + "filename": "393", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 9, + "w": 13, + "h": 19 + }, + "frame": { + "x": 180, + "y": 447, + "w": 13, + "h": 19 + } + }, { "filename": "447", "rotated": false, @@ -5841,12 +5589,327 @@ "h": 18 }, "frame": { - "x": 234, - "y": 504, + "x": 193, + "y": 451, "w": 18, "h": 18 } }, + { + "filename": "489s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 11, + "w": 23, + "h": 17 + }, + "frame": { + "x": 211, + "y": 456, + "w": 23, + "h": 17 + } + }, + { + "filename": "448s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 7, + "w": 16, + "h": 21 + }, + "frame": { + "x": 234, + "y": 460, + "w": 16, + "h": 21 + } + }, + { + "filename": "393s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 9, + "w": 13, + "h": 19 + }, + "frame": { + "x": 180, + "y": 466, + "w": 13, + "h": 19 + } + }, + { + "filename": "447s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 10, + "w": 18, + "h": 18 + }, + "frame": { + "x": 193, + "y": 469, + "w": 18, + "h": 18 + } + }, + { + "filename": "442", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 21, + "h": 20 + }, + "frame": { + "x": 211, + "y": 473, + "w": 21, + "h": 20 + } + }, + { + "filename": "492-land", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 12, + "w": 18, + "h": 16 + }, + "frame": { + "x": 232, + "y": 481, + "w": 18, + "h": 16 + } + }, + { + "filename": "442s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 21, + "h": 20 + }, + "frame": { + "x": 189, + "y": 487, + "w": 21, + "h": 20 + } + }, + { + "filename": "459", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 21, + "h": 20 + }, + "frame": { + "x": 189, + "y": 507, + "w": 21, + "h": 20 + } + }, + { + "filename": "459s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 21, + "h": 20 + }, + "frame": { + "x": 210, + "y": 493, + "w": 21, + "h": 20 + } + }, + { + "filename": "422-east", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 231, + "y": 497, + "w": 19, + "h": 20 + } + }, + { + "filename": "399", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 12, + "w": 20, + "h": 16 + }, + "frame": { + "x": 210, + "y": 513, + "w": 20, + "h": 16 + } + }, + { + "filename": "456", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 9, + "w": 20, + "h": 18 + }, + "frame": { + "x": 230, + "y": 517, + "w": 20, + "h": 18 + } + }, + { + "filename": "438", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 8, + "w": 12, + "h": 20 + }, + "frame": { + "x": 195, + "y": 527, + "w": 12, + "h": 20 + } + }, + { + "filename": "456s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 9, + "w": 20, + "h": 18 + }, + "frame": { + "x": 207, + "y": 529, + "w": 20, + "h": 18 + } + }, + { + "filename": "422s-east", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 195, + "y": 547, + "w": 19, + "h": 20 + } + }, { "filename": "422-west", "rotated": false, @@ -5862,14 +5925,14 @@ "h": 20 }, "frame": { - "x": 201, - "y": 534, + "x": 214, + "y": 547, "w": 17, "h": 20 } }, { - "filename": "439s", + "filename": "443s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5877,16 +5940,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 14, - "h": 21 + "x": 11, + "y": 9, + "w": 19, + "h": 19 }, "frame": { - "x": 219, - "y": 520, - "w": 14, - "h": 21 + "x": 231, + "y": 535, + "w": 19, + "h": 19 } }, { @@ -5904,8 +5967,8 @@ "h": 18 }, "frame": { - "x": 233, - "y": 522, + "x": 231, + "y": 554, "w": 19, "h": 18 } @@ -5925,12 +5988,54 @@ "h": 18 }, "frame": { - "x": 233, - "y": 540, + "x": 197, + "y": 567, "w": 19, "h": 18 } }, + { + "filename": "406", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 10, + "w": 12, + "h": 18 + }, + "frame": { + "x": 216, + "y": 567, + "w": 12, + "h": 18 + } + }, + { + "filename": "399s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 12, + "w": 20, + "h": 16 + }, + "frame": { + "x": 228, + "y": 572, + "w": 20, + "h": 16 + } + }, { "filename": "422s-west", "rotated": false, @@ -5946,12 +6051,33 @@ "h": 20 }, "frame": { - "x": 201, - "y": 554, + "x": 199, + "y": 585, "w": 17, "h": 20 } }, + { + "filename": "438s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 8, + "w": 12, + "h": 20 + }, + "frame": { + "x": 216, + "y": 585, + "w": 12, + "h": 20 + } + }, { "filename": "458", "rotated": false, @@ -5967,8 +6093,8 @@ "h": 17 }, "frame": { - "x": 198, - "y": 574, + "x": 228, + "y": 588, "w": 20, "h": 17 } @@ -5988,96 +6114,12 @@ "h": 17 }, "frame": { - "x": 198, - "y": 591, + "x": 200, + "y": 605, "w": 20, "h": 17 } }, - { - "filename": "447s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 10, - "w": 18, - "h": 18 - }, - "frame": { - "x": 199, - "y": 608, - "w": 18, - "h": 18 - } - }, - { - "filename": "440", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 9, - "w": 14, - "h": 19 - }, - "frame": { - "x": 218, - "y": 541, - "w": 14, - "h": 19 - } - }, - { - "filename": "440s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 9, - "w": 14, - "h": 19 - }, - "frame": { - "x": 218, - "y": 560, - "w": 14, - "h": 19 - } - }, - { - "filename": "446", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 9, - "w": 14, - "h": 19 - }, - "frame": { - "x": 218, - "y": 579, - "w": 14, - "h": 19 - } - }, { "filename": "453", "rotated": false, @@ -6093,8 +6135,8 @@ "h": 17 }, "frame": { - "x": 232, - "y": 558, + "x": 200, + "y": 622, "w": 17, "h": 17 } @@ -6114,8 +6156,8 @@ "h": 17 }, "frame": { - "x": 232, - "y": 575, + "x": 220, + "y": 605, "w": 17, "h": 17 } @@ -6135,14 +6177,14 @@ "h": 16 }, "frame": { - "x": 193, - "y": 628, + "x": 237, + "y": 605, "w": 13, "h": 16 } }, { - "filename": "446s", + "filename": "492s-land", "rotated": false, "trimmed": true, "sourceSize": { @@ -6150,100 +6192,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 13, - "y": 9, - "w": 14, - "h": 19 + "x": 12, + "y": 12, + "w": 18, + "h": 16 }, "frame": { - "x": 197, - "y": 644, - "w": 14, - "h": 19 - } - }, - { - "filename": "406", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 12, - "h": 18 - }, - "frame": { - "x": 206, - "y": 626, - "w": 12, - "h": 18 - } - }, - { - "filename": "393", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 9, - "w": 13, - "h": 19 - }, - "frame": { - "x": 211, - "y": 644, - "w": 13, - "h": 19 - } - }, - { - "filename": "393s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 9, - "w": 13, - "h": 19 - }, - "frame": { - "x": 218, - "y": 598, - "w": 13, - "h": 19 - } - }, - { - "filename": "438s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 8, - "w": 12, - "h": 20 - }, - "frame": { - "x": 218, - "y": 617, - "w": 12, - "h": 20 + "x": 217, + "y": 622, + "w": 18, + "h": 16 } }, { @@ -6261,8 +6219,8 @@ "h": 18 }, "frame": { - "x": 231, - "y": 598, + "x": 200, + "y": 639, "w": 12, "h": 18 } @@ -6273,6 +6231,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:d81cce65ebf0d5fbab1f9b7dbc080d4a:2eeffac5a7c6cd09ee563c646d89e345:3f74c54ad2b3085ce7282c3466535f4a$" + "smartupdate": "$TexturePacker:SmartUpdate:840d25653028f4586676114238d98794:576800da918eeca99e7b1b1a0d84af42:3f74c54ad2b3085ce7282c3466535f4a$" } } diff --git a/public/images/pokemon_icons_4.png b/public/images/pokemon_icons_4.png index 5dcfffb5579..9a3fb2cefa9 100644 Binary files a/public/images/pokemon_icons_4.png and b/public/images/pokemon_icons_4.png differ diff --git a/public/images/pokemon_icons_4v.json b/public/images/pokemon_icons_4v.json index 48c1519d88a..44bced3adc7 100644 --- a/public/images/pokemon_icons_4v.json +++ b/public/images/pokemon_icons_4v.json @@ -4,8 +4,8 @@ "image": "pokemon_icons_4v.png", "format": "RGBA8888", "size": { - "w": 124, - "h": 660 + "w": 123, + "h": 656 }, "scale": 1, "frames": [ @@ -135,6 +135,27 @@ "h": 25 } }, + { + "filename": "445_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 29, + "h": 22 + }, + "frame": { + "x": 94, + "y": 0, + "w": 29, + "h": 22 + } + }, { "filename": "445-mega_3", "rotated": false, @@ -150,12 +171,33 @@ "h": 25 }, "frame": { - "x": 94, - "y": 0, + "x": 0, + "y": 81, "w": 30, "h": 25 } }, + { + "filename": "445_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 29, + "h": 22 + }, + "frame": { + "x": 94, + "y": 22, + "w": 29, + "h": 22 + } + }, { "filename": "487-altered_2", "rotated": false, @@ -171,12 +213,33 @@ "h": 24 }, "frame": { - "x": 0, - "y": 81, + "x": 64, + "y": 25, "w": 30, "h": 24 } }, + { + "filename": "445_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 29, + "h": 22 + }, + "frame": { + "x": 94, + "y": 44, + "w": 29, + "h": 22 + } + }, { "filename": "487-altered_3", "rotated": false, @@ -193,53 +256,11 @@ }, "frame": { "x": 0, - "y": 105, + "y": 106, "w": 30, "h": 24 } }, - { - "filename": "472_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 31, - "h": 22 - }, - "frame": { - "x": 64, - "y": 25, - "w": 31, - "h": 22 - } - }, - { - "filename": "445_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 29, - "h": 22 - }, - "frame": { - "x": 95, - "y": 25, - "w": 29, - "h": 22 - } - }, { "filename": "487-origin_2", "rotated": false, @@ -256,7 +277,7 @@ }, "frame": { "x": 0, - "y": 129, + "y": 130, "w": 28, "h": 25 } @@ -277,7 +298,7 @@ }, "frame": { "x": 0, - "y": 154, + "y": 155, "w": 28, "h": 25 } @@ -298,7 +319,7 @@ }, "frame": { "x": 0, - "y": 179, + "y": 180, "w": 28, "h": 23 } @@ -319,7 +340,7 @@ }, "frame": { "x": 0, - "y": 202, + "y": 203, "w": 28, "h": 23 } @@ -340,7 +361,7 @@ }, "frame": { "x": 0, - "y": 225, + "y": 226, "w": 25, "h": 26 } @@ -361,7 +382,7 @@ }, "frame": { "x": 0, - "y": 251, + "y": 252, "w": 25, "h": 26 } @@ -382,7 +403,7 @@ }, "frame": { "x": 0, - "y": 277, + "y": 278, "w": 25, "h": 26 } @@ -403,7 +424,7 @@ }, "frame": { "x": 0, - "y": 303, + "y": 304, "w": 25, "h": 26 } @@ -424,7 +445,7 @@ }, "frame": { "x": 0, - "y": 329, + "y": 330, "w": 26, "h": 24 } @@ -445,7 +466,7 @@ }, "frame": { "x": 0, - "y": 353, + "y": 354, "w": 26, "h": 24 } @@ -466,7 +487,7 @@ }, "frame": { "x": 0, - "y": 377, + "y": 378, "w": 26, "h": 24 } @@ -487,7 +508,7 @@ }, "frame": { "x": 0, - "y": 401, + "y": 402, "w": 26, "h": 24 } @@ -508,7 +529,7 @@ }, "frame": { "x": 0, - "y": 425, + "y": 426, "w": 26, "h": 24 } @@ -529,7 +550,7 @@ }, "frame": { "x": 0, - "y": 449, + "y": 450, "w": 26, "h": 23 } @@ -550,7 +571,7 @@ }, "frame": { "x": 0, - "y": 472, + "y": 473, "w": 26, "h": 23 } @@ -571,7 +592,7 @@ }, "frame": { "x": 0, - "y": 495, + "y": 496, "w": 26, "h": 23 } @@ -592,7 +613,7 @@ }, "frame": { "x": 0, - "y": 518, + "y": 519, "w": 27, "h": 23 } @@ -613,7 +634,7 @@ }, "frame": { "x": 0, - "y": 541, + "y": 542, "w": 27, "h": 23 } @@ -634,13 +655,55 @@ }, "frame": { "x": 0, - "y": 564, + "y": 565, "w": 27, "h": 23 } }, { - "filename": "445_2", + "filename": "464_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 27, + "h": 22 + }, + "frame": { + "x": 0, + "y": 588, + "w": 27, + "h": 22 + } + }, + { + "filename": "464_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 27, + "h": 22 + }, + "frame": { + "x": 0, + "y": 610, + "w": 27, + "h": 22 + } + }, + { + "filename": "426_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -649,19 +712,19 @@ }, "spriteSourceSize": { "x": 8, - "y": 6, - "w": 29, - "h": 22 + "y": 4, + "w": 24, + "h": 24 }, "frame": { "x": 0, - "y": 587, - "w": 29, - "h": 22 + "y": 632, + "w": 24, + "h": 24 } }, { - "filename": "445_3", + "filename": "426_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -670,36 +733,15 @@ }, "spriteSourceSize": { "x": 8, - "y": 6, - "w": 29, - "h": 22 + "y": 4, + "w": 24, + "h": 24 }, "frame": { - "x": 0, - "y": 609, - "w": 29, - "h": 22 - } - }, - { - "filename": "465_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 29, - "h": 22 - }, - "frame": { - "x": 0, - "y": 631, - "w": 29, - "h": 22 + "x": 24, + "y": 632, + "w": 24, + "h": 24 } }, { @@ -724,49 +766,7 @@ } }, { - "filename": "485_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 5, - "y": 8, - "w": 33, - "h": 20 - }, - "frame": { - "x": 64, - "y": 47, - "w": 33, - "h": 20 - } - }, - { - "filename": "464_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 27, - "h": 22 - }, - "frame": { - "x": 97, - "y": 47, - "w": 27, - "h": 22 - } - }, - { - "filename": "472_3", + "filename": "472_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -786,6 +786,69 @@ "h": 22 } }, + { + "filename": "472_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 31, + "h": 22 + }, + "frame": { + "x": 30, + "y": 90, + "w": 31, + "h": 22 + } + }, + { + "filename": "485_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 8, + "w": 33, + "h": 20 + }, + "frame": { + "x": 30, + "y": 112, + "w": 33, + "h": 20 + } + }, + { + "filename": "465_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 29, + "h": 22 + }, + "frame": { + "x": 28, + "y": 132, + "w": 29, + "h": 22 + } + }, { "filename": "465_3", "rotated": false, @@ -801,8 +864,8 @@ "h": 22 }, "frame": { - "x": 30, - "y": 90, + "x": 28, + "y": 154, "w": 29, "h": 22 } @@ -822,8 +885,8 @@ "h": 22 }, "frame": { - "x": 30, - "y": 112, + "x": 28, + "y": 176, "w": 29, "h": 22 } @@ -844,7 +907,7 @@ }, "frame": { "x": 28, - "y": 134, + "y": 198, "w": 29, "h": 22 } @@ -864,558 +927,12 @@ "h": 22 }, "frame": { - "x": 28, - "y": 156, + "x": 64, + "y": 49, "w": 29, "h": 22 } }, - { - "filename": "464_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 27, - "h": 22 - }, - "frame": { - "x": 28, - "y": 178, - "w": 27, - "h": 22 - } - }, - { - "filename": "426_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 28, - "y": 200, - "w": 24, - "h": 24 - } - }, - { - "filename": "429_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 19, - "h": 28 - }, - "frame": { - "x": 25, - "y": 225, - "w": 19, - "h": 28 - } - }, - { - "filename": "429_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 19, - "h": 28 - }, - "frame": { - "x": 25, - "y": 253, - "w": 19, - "h": 28 - } - }, - { - "filename": "429_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 19, - "h": 28 - }, - "frame": { - "x": 25, - "y": 281, - "w": 19, - "h": 28 - } - }, - { - "filename": "414_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 25, - "h": 20 - }, - "frame": { - "x": 25, - "y": 309, - "w": 25, - "h": 20 - } - }, - { - "filename": "426_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 26, - "y": 329, - "w": 24, - "h": 24 - } - }, - { - "filename": "413-sandy_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 26, - "y": 353, - "w": 24, - "h": 23 - } - }, - { - "filename": "413-sandy_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 26, - "y": 376, - "w": 24, - "h": 23 - } - }, - { - "filename": "413-sandy_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 26, - "y": 399, - "w": 24, - "h": 23 - } - }, - { - "filename": "475_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 22, - "h": 25 - }, - "frame": { - "x": 26, - "y": 422, - "w": 22, - "h": 25 - } - }, - { - "filename": "475_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 22, - "h": 25 - }, - "frame": { - "x": 26, - "y": 447, - "w": 22, - "h": 25 - } - }, - { - "filename": "413-plant_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 26, - "y": 472, - "w": 22, - "h": 23 - } - }, - { - "filename": "413-plant_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 26, - "y": 495, - "w": 22, - "h": 23 - } - }, - { - "filename": "402_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 4, - "w": 20, - "h": 24 - }, - "frame": { - "x": 27, - "y": 518, - "w": 20, - "h": 24 - } - }, - { - "filename": "402_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 4, - "w": 20, - "h": 24 - }, - "frame": { - "x": 27, - "y": 542, - "w": 20, - "h": 24 - } - }, - { - "filename": "388_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 7, - "w": 22, - "h": 21 - }, - "frame": { - "x": 27, - "y": 566, - "w": 22, - "h": 21 - } - }, - { - "filename": "413-plant_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 29, - "y": 587, - "w": 22, - "h": 23 - } - }, - { - "filename": "413-trash_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 29, - "y": 610, - "w": 23, - "h": 23 - } - }, - { - "filename": "413-trash_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 29, - "y": 633, - "w": 23, - "h": 23 - } - }, - { - "filename": "448-mega_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 4, - "w": 19, - "h": 24 - }, - "frame": { - "x": 44, - "y": 224, - "w": 19, - "h": 24 - } - }, - { - "filename": "448-mega_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 4, - "w": 19, - "h": 24 - }, - "frame": { - "x": 44, - "y": 248, - "w": 19, - "h": 24 - } - }, - { - "filename": "448-mega_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 4, - "w": 19, - "h": 24 - }, - "frame": { - "x": 44, - "y": 272, - "w": 19, - "h": 24 - } - }, - { - "filename": "468_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 28, - "h": 19 - }, - "frame": { - "x": 64, - "y": 67, - "w": 28, - "h": 19 - } - }, - { - "filename": "468_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 28, - "h": 19 - }, - "frame": { - "x": 92, - "y": 69, - "w": 28, - "h": 19 - } - }, - { - "filename": "468_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 28, - "h": 19 - }, - "frame": { - "x": 61, - "y": 86, - "w": 28, - "h": 19 - } - }, { "filename": "428_2", "rotated": false, @@ -1431,8 +948,50 @@ "h": 22 }, "frame": { - "x": 59, - "y": 105, + "x": 61, + "y": 71, + "w": 26, + "h": 22 + } + }, + { + "filename": "468_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 28, + "h": 19 + }, + "frame": { + "x": 61, + "y": 93, + "w": 28, + "h": 19 + } + }, + { + "filename": "428_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 63, + "y": 112, "w": 26, "h": 22 } @@ -1452,8 +1011,8 @@ "h": 21 }, "frame": { - "x": 89, - "y": 88, + "x": 57, + "y": 134, "w": 27, "h": 21 } @@ -1473,54 +1032,12 @@ "h": 21 }, "frame": { - "x": 85, - "y": 109, + "x": 57, + "y": 155, "w": 27, "h": 21 } }, - { - "filename": "406_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 12, - "h": 18 - }, - "frame": { - "x": 112, - "y": 109, - "w": 12, - "h": 18 - } - }, - { - "filename": "428_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 59, - "y": 127, - "w": 26, - "h": 22 - } - }, { "filename": "480_1", "rotated": false, @@ -1537,7 +1054,7 @@ }, "frame": { "x": 57, - "y": 149, + "y": 176, "w": 26, "h": 22 } @@ -1557,12 +1074,54 @@ "h": 22 }, "frame": { - "x": 85, - "y": 130, + "x": 57, + "y": 198, "w": 26, "h": 22 } }, + { + "filename": "468_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 28, + "h": 19 + }, + "frame": { + "x": 28, + "y": 220, + "w": 28, + "h": 19 + } + }, + { + "filename": "468_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 28, + "h": 19 + }, + "frame": { + "x": 56, + "y": 220, + "w": 28, + "h": 19 + } + }, { "filename": "480_3", "rotated": false, @@ -1578,14 +1137,14 @@ "h": 22 }, "frame": { - "x": 83, - "y": 152, + "x": 25, + "y": 239, "w": 26, "h": 22 } }, { - "filename": "412-sandy_1", + "filename": "413-sandy_1", "rotated": false, "trimmed": true, "sourceSize": { @@ -1593,20 +1152,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 13, + "x": 9, "y": 5, - "w": 15, + "w": 24, "h": 23 }, "frame": { - "x": 109, - "y": 152, - "w": 15, + "x": 25, + "y": 261, + "w": 24, "h": 23 } }, { - "filename": "406_3", + "filename": "413-sandy_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -1614,20 +1173,41 @@ "h": 30 }, "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 12, - "h": 18 + "x": 9, + "y": 5, + "w": 24, + "h": 23 }, "frame": { - "x": 112, - "y": 127, - "w": 12, - "h": 18 + "x": 25, + "y": 284, + "w": 24, + "h": 23 } }, { - "filename": "414_3", + "filename": "413-sandy_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 25, + "y": 307, + "w": 24, + "h": 23 + } + }, + { + "filename": "429_1", "rotated": false, "trimmed": true, "sourceSize": { @@ -1636,15 +1216,57 @@ }, "spriteSourceSize": { "x": 10, - "y": 7, - "w": 25, - "h": 20 + "y": 2, + "w": 19, + "h": 28 }, "frame": { - "x": 57, - "y": 171, - "w": 25, - "h": 20 + "x": 26, + "y": 330, + "w": 19, + "h": 28 + } + }, + { + "filename": "429_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 2, + "w": 19, + "h": 28 + }, + "frame": { + "x": 26, + "y": 358, + "w": 19, + "h": 28 + } + }, + { + "filename": "429_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 2, + "w": 19, + "h": 28 + }, + "frame": { + "x": 26, + "y": 386, + "w": 19, + "h": 28 } }, { @@ -1662,33 +1284,12 @@ "h": 22 }, "frame": { - "x": 82, - "y": 174, + "x": 51, + "y": 239, "w": 25, "h": 22 } }, - { - "filename": "401_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 17, - "h": 22 - }, - "frame": { - "x": 107, - "y": 175, - "w": 17, - "h": 22 - } - }, { "filename": "470_2", "rotated": false, @@ -1704,8 +1305,8 @@ "h": 22 }, "frame": { - "x": 55, - "y": 191, + "x": 49, + "y": 261, "w": 25, "h": 22 } @@ -1725,14 +1326,14 @@ "h": 22 }, "frame": { - "x": 80, - "y": 196, + "x": 49, + "y": 283, "w": 25, "h": 22 } }, { - "filename": "461_2", + "filename": "475_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -1741,19 +1342,19 @@ }, "spriteSourceSize": { "x": 10, - "y": 6, - "w": 19, - "h": 22 + "y": 3, + "w": 22, + "h": 25 }, "frame": { - "x": 105, - "y": 197, - "w": 19, - "h": 22 + "x": 49, + "y": 305, + "w": 22, + "h": 25 } }, { - "filename": "401_3", + "filename": "475_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -1761,16 +1362,163 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 17, - "h": 22 + "x": 10, + "y": 3, + "w": 22, + "h": 25 }, "frame": { - "x": 63, - "y": 213, - "w": 17, - "h": 22 + "x": 45, + "y": 330, + "w": 22, + "h": 25 + } + }, + { + "filename": "413-plant_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 45, + "y": 355, + "w": 22, + "h": 23 + } + }, + { + "filename": "413-plant_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 45, + "y": 378, + "w": 22, + "h": 23 + } + }, + { + "filename": "402_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 4, + "w": 20, + "h": 24 + }, + "frame": { + "x": 26, + "y": 414, + "w": 20, + "h": 24 + } + }, + { + "filename": "402_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 4, + "w": 20, + "h": 24 + }, + "frame": { + "x": 26, + "y": 438, + "w": 20, + "h": 24 + } + }, + { + "filename": "413-plant_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 26, + "y": 462, + "w": 22, + "h": 23 + } + }, + { + "filename": "413-trash_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 26, + "y": 485, + "w": 23, + "h": 23 + } + }, + { + "filename": "413-trash_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 27, + "y": 508, + "w": 23, + "h": 23 } }, { @@ -1788,96 +1536,12 @@ "h": 23 }, "frame": { - "x": 63, - "y": 235, + "x": 27, + "y": 531, "w": 23, "h": 23 } }, - { - "filename": "489_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 11, - "w": 23, - "h": 17 - }, - "frame": { - "x": 80, - "y": 218, - "w": 23, - "h": 17 - } - }, - { - "filename": "454_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 21, - "h": 22 - }, - "frame": { - "x": 103, - "y": 219, - "w": 21, - "h": 22 - } - }, - { - "filename": "412-plant_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 17, - "h": 22 - }, - "frame": { - "x": 86, - "y": 235, - "w": 17, - "h": 22 - } - }, - { - "filename": "454_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 21, - "h": 22 - }, - "frame": { - "x": 103, - "y": 241, - "w": 21, - "h": 22 - } - }, { "filename": "423-east_1", "rotated": false, @@ -1893,54 +1557,12 @@ "h": 22 }, "frame": { - "x": 63, - "y": 258, + "x": 27, + "y": 554, "w": 23, "h": 22 } }, - { - "filename": "412-plant_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 17, - "h": 22 - }, - "frame": { - "x": 86, - "y": 257, - "w": 17, - "h": 22 - } - }, - { - "filename": "492-sky_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 21, - "h": 22 - }, - "frame": { - "x": 103, - "y": 263, - "w": 21, - "h": 22 - } - }, { "filename": "423-east_2", "rotated": false, @@ -1956,138 +1578,12 @@ "h": 22 }, "frame": { - "x": 63, - "y": 280, + "x": 27, + "y": 576, "w": 23, "h": 22 } }, - { - "filename": "412-plant_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 17, - "h": 22 - }, - "frame": { - "x": 86, - "y": 279, - "w": 17, - "h": 22 - } - }, - { - "filename": "492-sky_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 21, - "h": 22 - }, - "frame": { - "x": 103, - "y": 285, - "w": 21, - "h": 22 - } - }, - { - "filename": "412-sandy_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 5, - "w": 15, - "h": 23 - }, - "frame": { - "x": 48, - "y": 422, - "w": 15, - "h": 23 - } - }, - { - "filename": "412-sandy_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 5, - "w": 15, - "h": 23 - }, - "frame": { - "x": 48, - "y": 445, - "w": 15, - "h": 23 - } - }, - { - "filename": "412-trash_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 5, - "w": 16, - "h": 23 - }, - "frame": { - "x": 48, - "y": 468, - "w": 16, - "h": 23 - } - }, - { - "filename": "412-trash_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 5, - "w": 16, - "h": 23 - }, - "frame": { - "x": 48, - "y": 491, - "w": 16, - "h": 23 - } - }, { "filename": "423-east_3", "rotated": false, @@ -2103,117 +1599,12 @@ "h": 22 }, "frame": { - "x": 50, - "y": 302, + "x": 27, + "y": 598, "w": 23, "h": 22 } }, - { - "filename": "423-west_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 50, - "y": 324, - "w": 23, - "h": 22 - } - }, - { - "filename": "423-west_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 50, - "y": 346, - "w": 23, - "h": 22 - } - }, - { - "filename": "423-west_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 50, - "y": 368, - "w": 23, - "h": 22 - } - }, - { - "filename": "400_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 22, - "h": 22 - }, - "frame": { - "x": 50, - "y": 390, - "w": 22, - "h": 22 - } - }, - { - "filename": "412-trash_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 5, - "w": 16, - "h": 23 - }, - "frame": { - "x": 73, - "y": 302, - "w": 16, - "h": 23 - } - }, { "filename": "387_2", "rotated": false, @@ -2229,8 +1620,8 @@ "h": 22 }, "frame": { - "x": 73, - "y": 325, + "x": 87, + "y": 71, "w": 18, "h": 22 } @@ -2250,14 +1641,119 @@ "h": 22 }, "frame": { - "x": 73, - "y": 347, + "x": 105, + "y": 66, "w": 18, "h": 22 } }, { - "filename": "388_3", + "filename": "427_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 105, + "y": 88, + "w": 18, + "h": 22 + } + }, + { + "filename": "412-trash_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 5, + "w": 16, + "h": 23 + }, + "frame": { + "x": 89, + "y": 93, + "w": 16, + "h": 23 + } + }, + { + "filename": "427_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 105, + "y": 110, + "w": 18, + "h": 22 + } + }, + { + "filename": "412-trash_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 5, + "w": 16, + "h": 23 + }, + "frame": { + "x": 89, + "y": 116, + "w": 16, + "h": 23 + } + }, + { + "filename": "447_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 10, + "w": 18, + "h": 18 + }, + "frame": { + "x": 105, + "y": 132, + "w": 18, + "h": 18 + } + }, + { + "filename": "454_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -2266,40 +1762,19 @@ }, "spriteSourceSize": { "x": 9, - "y": 7, - "w": 22, - "h": 21 - }, - "frame": { - "x": 73, - "y": 369, - "w": 22, - "h": 21 - } - }, - { - "filename": "400_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, "y": 6, - "w": 22, + "w": 21, "h": 22 }, "frame": { - "x": 72, - "y": 390, - "w": 22, + "x": 84, + "y": 139, + "w": 21, "h": 22 } }, { - "filename": "440_1", + "filename": "447_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -2307,16 +1782,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 13, - "y": 9, - "w": 14, - "h": 19 + "x": 12, + "y": 10, + "w": 18, + "h": 18 }, "frame": { - "x": 89, - "y": 301, - "w": 14, - "h": 19 + "x": 105, + "y": 150, + "w": 18, + "h": 18 } }, { @@ -2334,12 +1809,390 @@ "h": 20 }, "frame": { - "x": 103, - "y": 307, + "x": 84, + "y": 161, "w": 21, "h": 20 } }, + { + "filename": "447_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 10, + "w": 18, + "h": 18 + }, + "frame": { + "x": 105, + "y": 168, + "w": 18, + "h": 18 + } + }, + { + "filename": "400_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 22, + "h": 22 + }, + "frame": { + "x": 83, + "y": 181, + "w": 22, + "h": 22 + } + }, + { + "filename": "492-land_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 12, + "w": 18, + "h": 16 + }, + "frame": { + "x": 105, + "y": 186, + "w": 18, + "h": 16 + } + }, + { + "filename": "489_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 11, + "w": 23, + "h": 17 + }, + "frame": { + "x": 83, + "y": 203, + "w": 23, + "h": 17 + } + }, + { + "filename": "401_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 17, + "h": 22 + }, + "frame": { + "x": 106, + "y": 202, + "w": 17, + "h": 22 + } + }, + { + "filename": "388_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 7, + "w": 22, + "h": 21 + }, + "frame": { + "x": 84, + "y": 220, + "w": 22, + "h": 21 + } + }, + { + "filename": "401_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 17, + "h": 22 + }, + "frame": { + "x": 106, + "y": 224, + "w": 17, + "h": 22 + } + }, + { + "filename": "414_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 25, + "h": 20 + }, + "frame": { + "x": 76, + "y": 241, + "w": 25, + "h": 20 + } + }, + { + "filename": "400_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 22, + "h": 22 + }, + "frame": { + "x": 101, + "y": 246, + "w": 22, + "h": 22 + } + }, + { + "filename": "414_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 25, + "h": 20 + }, + "frame": { + "x": 74, + "y": 261, + "w": 25, + "h": 20 + } + }, + { + "filename": "423-west_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 23, + "h": 22 + }, + "frame": { + "x": 74, + "y": 281, + "w": 23, + "h": 22 + } + }, + { + "filename": "423-west_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 23, + "h": 22 + }, + "frame": { + "x": 99, + "y": 268, + "w": 23, + "h": 22 + } + }, + { + "filename": "423-west_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 23, + "h": 22 + }, + "frame": { + "x": 97, + "y": 290, + "w": 23, + "h": 22 + } + }, + { + "filename": "433_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 23, + "h": 19 + }, + "frame": { + "x": 74, + "y": 303, + "w": 23, + "h": 19 + } + }, + { + "filename": "433_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 23, + "h": 19 + }, + "frame": { + "x": 97, + "y": 312, + "w": 23, + "h": 19 + } + }, + { + "filename": "448-mega_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 4, + "w": 19, + "h": 24 + }, + "frame": { + "x": 46, + "y": 401, + "w": 19, + "h": 24 + } + }, + { + "filename": "448-mega_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 4, + "w": 19, + "h": 24 + }, + "frame": { + "x": 46, + "y": 425, + "w": 19, + "h": 24 + } + }, + { + "filename": "433_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 23, + "h": 19 + }, + "frame": { + "x": 71, + "y": 322, + "w": 23, + "h": 19 + } + }, { "filename": "444_1", "rotated": false, @@ -2355,8 +2208,8 @@ "h": 21 }, "frame": { - "x": 63, - "y": 412, + "x": 67, + "y": 341, "w": 23, "h": 21 } @@ -2376,8 +2229,8 @@ "h": 21 }, "frame": { - "x": 63, - "y": 433, + "x": 67, + "y": 362, "w": 23, "h": 21 } @@ -2397,14 +2250,35 @@ "h": 21 }, "frame": { - "x": 91, - "y": 327, + "x": 67, + "y": 383, "w": 23, "h": 21 } }, { - "filename": "433_1", + "filename": "388_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 7, + "w": 22, + "h": 21 + }, + "frame": { + "x": 65, + "y": 404, + "w": 22, + "h": 21 + } + }, + { + "filename": "448-mega_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -2413,15 +2287,36 @@ }, "spriteSourceSize": { "x": 12, - "y": 9, - "w": 23, - "h": 19 + "y": 4, + "w": 19, + "h": 24 }, "frame": { - "x": 91, - "y": 348, - "w": 23, - "h": 19 + "x": 65, + "y": 425, + "w": 19, + "h": 24 + } + }, + { + "filename": "454_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 21, + "h": 22 + }, + "frame": { + "x": 48, + "y": 449, + "w": 21, + "h": 22 } }, { @@ -2439,14 +2334,14 @@ "h": 22 }, "frame": { - "x": 95, - "y": 367, + "x": 69, + "y": 449, "w": 20, "h": 22 } }, { - "filename": "407_3", + "filename": "489_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -2454,18 +2349,102 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, + "x": 11, + "y": 11, + "w": 23, + "h": 17 + }, + "frame": { + "x": 94, + "y": 331, + "w": 23, + "h": 17 + } + }, + { + "filename": "492-sky_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, "y": 6, - "w": 20, + "w": 21, "h": 22 }, "frame": { - "x": 86, - "y": 412, - "w": 20, + "x": 90, + "y": 348, + "w": 21, "h": 22 } }, + { + "filename": "492-sky_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 21, + "h": 22 + }, + "frame": { + "x": 90, + "y": 370, + "w": 21, + "h": 22 + } + }, + { + "filename": "406_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 10, + "w": 12, + "h": 18 + }, + "frame": { + "x": 111, + "y": 348, + "w": 12, + "h": 18 + } + }, + { + "filename": "406_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 10, + "w": 12, + "h": 18 + }, + "frame": { + "x": 111, + "y": 366, + "w": 12, + "h": 18 + } + }, { "filename": "442_3", "rotated": false, @@ -2481,14 +2460,14 @@ "h": 20 }, "frame": { - "x": 86, - "y": 434, + "x": 90, + "y": 392, "w": 21, "h": 20 } }, { - "filename": "425_2", + "filename": "489_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -2496,121 +2475,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 15, - "h": 22 + "x": 11, + "y": 11, + "w": 23, + "h": 17 }, "frame": { - "x": 94, - "y": 390, - "w": 15, - "h": 22 - } - }, - { - "filename": "425_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 15, - "h": 22 - }, - "frame": { - "x": 109, - "y": 389, - "w": 15, - "h": 22 - } - }, - { - "filename": "427_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 18, - "h": 22 - }, - "frame": { - "x": 106, + "x": 87, "y": 412, - "w": 18, - "h": 22 - } - }, - { - "filename": "422-west_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 17, - "h": 20 - }, - "frame": { - "x": 107, - "y": 434, - "w": 17, - "h": 20 - } - }, - { - "filename": "433_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, "w": 23, - "h": 19 - }, - "frame": { - "x": 64, - "y": 454, - "w": 23, - "h": 19 - } - }, - { - "filename": "433_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 23, - "h": 19 - }, - "frame": { - "x": 64, - "y": 473, - "w": 23, - "h": 19 + "h": 17 } }, { @@ -2628,12 +2502,117 @@ "h": 20 }, "frame": { - "x": 87, - "y": 454, + "x": 84, + "y": 429, "w": 22, "h": 20 } }, + { + "filename": "412-plant_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 17, + "h": 22 + }, + "frame": { + "x": 106, + "y": 429, + "w": 17, + "h": 22 + } + }, + { + "filename": "412-plant_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 17, + "h": 22 + }, + "frame": { + "x": 89, + "y": 449, + "w": 17, + "h": 22 + } + }, + { + "filename": "412-plant_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 17, + "h": 22 + }, + "frame": { + "x": 106, + "y": 451, + "w": 17, + "h": 22 + } + }, + { + "filename": "436_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 12, + "w": 13, + "h": 16 + }, + "frame": { + "x": 110, + "y": 412, + "w": 13, + "h": 16 + } + }, + { + "filename": "407_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 20, + "h": 22 + }, + "frame": { + "x": 49, + "y": 471, + "w": 20, + "h": 22 + } + }, { "filename": "490_2", "rotated": false, @@ -2649,12 +2628,75 @@ "h": 20 }, "frame": { - "x": 64, - "y": 492, + "x": 69, + "y": 471, "w": 22, "h": 20 } }, + { + "filename": "412-sandy_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 5, + "w": 15, + "h": 23 + }, + "frame": { + "x": 91, + "y": 471, + "w": 15, + "h": 23 + } + }, + { + "filename": "422-west_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 17, + "h": 20 + }, + "frame": { + "x": 106, + "y": 473, + "w": 17, + "h": 20 + } + }, + { + "filename": "422-west_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 17, + "h": 20 + }, + "frame": { + "x": 106, + "y": 493, + "w": 17, + "h": 20 + } + }, { "filename": "490_3", "rotated": false, @@ -2670,14 +2712,14 @@ "h": 20 }, "frame": { - "x": 87, - "y": 474, + "x": 69, + "y": 491, "w": 22, "h": 20 } }, { - "filename": "489_2", + "filename": "412-sandy_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -2685,20 +2727,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, - "y": 11, - "w": 23, - "h": 17 + "x": 13, + "y": 5, + "w": 15, + "h": 23 }, "frame": { - "x": 86, + "x": 91, "y": 494, - "w": 23, - "h": 17 + "w": 15, + "h": 23 } }, { - "filename": "440_2", + "filename": "461_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -2706,104 +2748,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 13, - "y": 9, - "w": 14, - "h": 19 - }, - "frame": { - "x": 109, - "y": 454, - "w": 14, - "h": 19 - } - }, - { - "filename": "440_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 9, - "w": 14, - "h": 19 - }, - "frame": { - "x": 109, - "y": 473, - "w": 14, - "h": 19 - } - }, - { - "filename": "436_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 12, - "w": 13, - "h": 16 - }, - "frame": { - "x": 109, - "y": 492, - "w": 13, - "h": 16 - } - }, - { - "filename": "489_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 11, - "w": 23, - "h": 17 - }, - "frame": { - "x": 64, - "y": 512, - "w": 23, - "h": 17 - } - }, - { - "filename": "422-east_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, + "x": 10, + "y": 6, "w": 19, - "h": 20 + "h": 22 }, "frame": { - "x": 87, - "y": 511, + "x": 50, + "y": 493, "w": 19, - "h": 20 + "h": 22 } }, { - "filename": "427_3", + "filename": "422-west_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -2812,36 +2770,15 @@ }, "spriteSourceSize": { "x": 12, - "y": 6, - "w": 18, - "h": 22 + "y": 8, + "w": 17, + "h": 20 }, "frame": { "x": 106, - "y": 511, - "w": 18, - "h": 22 - } - }, - { - "filename": "448_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 7, - "w": 16, - "h": 21 - }, - "frame": { - "x": 48, - "y": 514, - "w": 16, - "h": 21 + "y": 513, + "w": 17, + "h": 20 } }, { @@ -2859,14 +2796,35 @@ "h": 22 }, "frame": { - "x": 47, - "y": 535, + "x": 50, + "y": 515, "w": 19, "h": 22 } }, { - "filename": "494_2", + "filename": "412-trash_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 5, + "w": 16, + "h": 23 + }, + "frame": { + "x": 69, + "y": 511, + "w": 16, + "h": 23 + } + }, + { + "filename": "422-east_1", "rotated": false, "trimmed": true, "sourceSize": { @@ -2875,15 +2833,15 @@ }, "spriteSourceSize": { "x": 11, - "y": 6, - "w": 18, - "h": 22 + "y": 8, + "w": 19, + "h": 20 }, "frame": { - "x": 66, - "y": 529, - "w": 18, - "h": 22 + "x": 50, + "y": 537, + "w": 19, + "h": 20 } }, { @@ -2901,8 +2859,8 @@ "h": 20 }, "frame": { - "x": 84, - "y": 531, + "x": 50, + "y": 557, "w": 19, "h": 20 } @@ -2922,14 +2880,14 @@ "h": 20 }, "frame": { - "x": 103, - "y": 533, + "x": 50, + "y": 577, "w": 19, "h": 20 } }, { - "filename": "494_3", + "filename": "412-sandy_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -2937,16 +2895,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, - "y": 6, - "w": 18, - "h": 22 + "x": 13, + "y": 5, + "w": 15, + "h": 23 }, "frame": { - "x": 49, - "y": 557, - "w": 18, - "h": 22 + "x": 69, + "y": 534, + "w": 15, + "h": 23 } }, { @@ -2964,14 +2922,14 @@ "h": 19 }, "frame": { - "x": 67, - "y": 551, + "x": 50, + "y": 597, "w": 19, "h": 19 } }, { - "filename": "422-west_2", + "filename": "425_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -2979,16 +2937,58 @@ "h": 30 }, "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 17, - "h": 20 + "x": 13, + "y": 7, + "w": 15, + "h": 22 }, "frame": { - "x": 86, - "y": 551, - "w": 17, - "h": 20 + "x": 69, + "y": 557, + "w": 15, + "h": 22 + } + }, + { + "filename": "425_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 15, + "h": 22 + }, + "frame": { + "x": 69, + "y": 579, + "w": 15, + "h": 22 + } + }, + { + "filename": "458_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 10, + "w": 20, + "h": 17 + }, + "frame": { + "x": 85, + "y": 517, + "w": 20, + "h": 17 } }, { @@ -3006,7 +3006,28 @@ "h": 19 }, "frame": { - "x": 103, + "x": 84, + "y": 534, + "w": 19, + "h": 19 + } + }, + { + "filename": "443_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 9, + "w": 19, + "h": 19 + }, + "frame": { + "x": 84, "y": 553, "w": 19, "h": 19 @@ -3027,14 +3048,14 @@ "h": 22 }, "frame": { - "x": 51, - "y": 579, + "x": 84, + "y": 572, "w": 16, "h": 22 } }, { - "filename": "443_3", + "filename": "458_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -3042,79 +3063,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, - "y": 9, - "w": 19, - "h": 19 - }, - "frame": { - "x": 67, - "y": 570, - "w": 19, - "h": 19 - } - }, - { - "filename": "422-west_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 17, - "h": 20 - }, - "frame": { - "x": 86, - "y": 571, - "w": 17, - "h": 20 - } - }, - { - "filename": "447_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, + "x": 10, "y": 10, - "w": 18, - "h": 18 + "w": 20, + "h": 17 }, "frame": { "x": 103, - "y": 572, - "w": 18, - "h": 18 - } - }, - { - "filename": "447_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 10, - "w": 18, - "h": 18 - }, - "frame": { - "x": 67, - "y": 589, - "w": 18, - "h": 18 + "y": 534, + "w": 20, + "h": 17 } }, { @@ -3132,14 +3090,35 @@ "h": 16 }, "frame": { - "x": 85, - "y": 591, + "x": 103, + "y": 551, "w": 20, "h": 16 } }, { - "filename": "447_3", + "filename": "399_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 12, + "w": 20, + "h": 16 + }, + "frame": { + "x": 103, + "y": 567, + "w": 20, + "h": 16 + } + }, + { + "filename": "448_1", "rotated": false, "trimmed": true, "sourceSize": { @@ -3148,36 +3127,15 @@ }, "spriteSourceSize": { "x": 12, - "y": 10, - "w": 18, - "h": 18 + "y": 7, + "w": 16, + "h": 21 }, "frame": { - "x": 105, - "y": 590, - "w": 18, - "h": 18 - } - }, - { - "filename": "436_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 12, - "w": 13, - "h": 16 - }, - "frame": { - "x": 52, + "x": 69, "y": 601, - "w": 13, - "h": 16 + "w": 16, + "h": 21 } }, { @@ -3195,8 +3153,8 @@ "h": 22 }, "frame": { - "x": 52, - "y": 617, + "x": 85, + "y": 594, "w": 16, "h": 22 } @@ -3216,8 +3174,8 @@ "h": 21 }, "frame": { - "x": 52, - "y": 639, + "x": 101, + "y": 583, "w": 16, "h": 21 } @@ -3237,14 +3195,14 @@ "h": 21 }, "frame": { - "x": 68, - "y": 607, + "x": 101, + "y": 604, "w": 16, "h": 21 } }, { - "filename": "458_2", + "filename": "492-land_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -3252,37 +3210,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 20, - "h": 17 + "x": 12, + "y": 12, + "w": 18, + "h": 16 }, "frame": { - "x": 84, - "y": 607, - "w": 20, - "h": 17 - } - }, - { - "filename": "458_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 20, - "h": 17 - }, - "frame": { - "x": 104, - "y": 608, - "w": 20, - "h": 17 + "x": 50, + "y": 616, + "w": 18, + "h": 16 } }, { @@ -3300,8 +3237,8 @@ "h": 17 }, "frame": { - "x": 68, - "y": 628, + "x": 48, + "y": 632, "w": 17, "h": 17 } @@ -3321,14 +3258,14 @@ "h": 17 }, "frame": { - "x": 85, - "y": 624, + "x": 68, + "y": 622, "w": 17, "h": 17 } }, { - "filename": "399_3", + "filename": "440_1", "rotated": false, "trimmed": true, "sourceSize": { @@ -3336,41 +3273,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, - "y": 12, - "w": 20, - "h": 16 - }, - "frame": { - "x": 102, - "y": 625, - "w": 20, - "h": 16 - } - }, - { - "filename": "492-land_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 12, - "w": 18, - "h": 16 + "x": 13, + "y": 9, + "w": 14, + "h": 19 }, "frame": { "x": 85, - "y": 641, - "w": 18, - "h": 16 + "y": 616, + "w": 14, + "h": 19 } }, { - "filename": "492-land_3", + "filename": "440_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -3378,15 +3294,57 @@ "h": 30 }, "spriteSourceSize": { - "x": 12, + "x": 13, + "y": 9, + "w": 14, + "h": 19 + }, + "frame": { + "x": 99, + "y": 625, + "w": 14, + "h": 19 + } + }, + { + "filename": "440_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 9, + "w": 14, + "h": 19 + }, + "frame": { + "x": 85, + "y": 635, + "w": 14, + "h": 19 + } + }, + { + "filename": "436_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, "y": 12, - "w": 18, + "w": 13, "h": 16 }, "frame": { - "x": 103, - "y": 641, - "w": 18, + "x": 65, + "y": 639, + "w": 13, "h": 16 } } @@ -3396,6 +3354,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:8d567785b198c5a2f6892242773436c5:1a0706846c40b2345d9ac32977f8c2e5:ebc3f8ec5b2480b298192d752b6e57dc$" + "smartupdate": "$TexturePacker:SmartUpdate:ff9a4f796b02d3e2c7977d3c3d76a7b8:eabe987f61ff488162814a018b9b9c12:ebc3f8ec5b2480b298192d752b6e57dc$" } } diff --git a/public/images/pokemon_icons_4v.png b/public/images/pokemon_icons_4v.png index eaf8d009ca8..9f2a9ac1f19 100644 Binary files a/public/images/pokemon_icons_4v.png and b/public/images/pokemon_icons_4v.png differ diff --git a/public/images/pokemon_icons_5.json b/public/images/pokemon_icons_5.json index fdbba6575e7..685ce770889 100644 --- a/public/images/pokemon_icons_5.json +++ b/public/images/pokemon_icons_5.json @@ -4,8 +4,8 @@ "image": "pokemon_icons_5.png", "format": "RGBA8888", "size": { - "w": 256, - "h": 681 + "w": 245, + "h": 713 }, "scale": 1, "frames": [ @@ -324,6 +324,27 @@ "h": 27 } }, + { + "filename": "640", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 2, + "w": 21, + "h": 26 + }, + "frame": { + "x": 224, + "y": 0, + "w": 21, + "h": 26 + } + }, { "filename": "644s", "rotated": false, @@ -345,27 +366,6 @@ "h": 27 } }, - { - "filename": "645-incarnate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 4, - "y": 2, - "w": 31, - "h": 26 - }, - "frame": { - "x": 224, - "y": 0, - "w": 31, - "h": 26 - } - }, { "filename": "641-incarnate", "rotated": false, @@ -409,7 +409,7 @@ } }, { - "filename": "645s-incarnate", + "filename": "645-incarnate", "rotated": false, "trimmed": true, "sourceSize": { @@ -430,7 +430,7 @@ } }, { - "filename": "646", + "filename": "645s-incarnate", "rotated": false, "trimmed": true, "sourceSize": { @@ -451,7 +451,7 @@ } }, { - "filename": "646s", + "filename": "646", "rotated": false, "trimmed": true, "sourceSize": { @@ -471,6 +471,27 @@ "h": 26 } }, + { + "filename": "646s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 4, + "y": 2, + "w": 31, + "h": 26 + }, + "frame": { + "x": 0, + "y": 352, + "w": 31, + "h": 26 + } + }, { "filename": "534", "rotated": false, @@ -487,7 +508,7 @@ }, "frame": { "x": 0, - "y": 352, + "y": 378, "w": 31, "h": 25 } @@ -508,7 +529,7 @@ }, "frame": { "x": 0, - "y": 377, + "y": 403, "w": 31, "h": 25 } @@ -529,7 +550,7 @@ }, "frame": { "x": 0, - "y": 402, + "y": 428, "w": 30, "h": 25 } @@ -550,7 +571,7 @@ }, "frame": { "x": 0, - "y": 427, + "y": 453, "w": 30, "h": 25 } @@ -571,7 +592,7 @@ }, "frame": { "x": 0, - "y": 452, + "y": 478, "w": 30, "h": 25 } @@ -592,7 +613,7 @@ }, "frame": { "x": 0, - "y": 477, + "y": 503, "w": 30, "h": 25 } @@ -613,7 +634,7 @@ }, "frame": { "x": 0, - "y": 502, + "y": 528, "w": 27, "h": 28 } @@ -634,7 +655,7 @@ }, "frame": { "x": 0, - "y": 530, + "y": 556, "w": 27, "h": 28 } @@ -655,7 +676,7 @@ }, "frame": { "x": 0, - "y": 558, + "y": 584, "w": 28, "h": 25 } @@ -676,7 +697,7 @@ }, "frame": { "x": 0, - "y": 583, + "y": 609, "w": 28, "h": 25 } @@ -697,7 +718,7 @@ }, "frame": { "x": 0, - "y": 608, + "y": 634, "w": 29, "h": 25 } @@ -718,13 +739,13 @@ }, "frame": { "x": 0, - "y": 633, + "y": 659, "w": 29, "h": 25 } }, { - "filename": "503", + "filename": "635", "rotated": false, "trimmed": true, "sourceSize": { @@ -732,20 +753,41 @@ "h": 30 }, "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 31, - "h": 23 + "x": 6, + "y": 3, + "w": 29, + "h": 25 }, "frame": { "x": 0, - "y": 658, - "w": 31, - "h": 23 + "y": 684, + "w": 29, + "h": 25 } }, { - "filename": "503s", + "filename": "640s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 2, + "w": 21, + "h": 26 + }, + "frame": { + "x": 224, + "y": 26, + "w": 21, + "h": 26 + } + }, + { + "filename": "503", "rotated": false, "trimmed": true, "sourceSize": { @@ -766,7 +808,7 @@ } }, { - "filename": "569", + "filename": "503s", "rotated": false, "trimmed": true, "sourceSize": { @@ -775,36 +817,15 @@ }, "spriteSourceSize": { "x": 5, - "y": 6, - "w": 30, - "h": 22 + "y": 5, + "w": 31, + "h": 23 }, "frame": { "x": 33, "y": 81, - "w": 30, - "h": 22 - } - }, - { - "filename": "635", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 29, - "h": 25 - }, - "frame": { - "x": 32, - "y": 103, - "w": 29, - "h": 25 + "w": 31, + "h": 23 } }, { @@ -823,11 +844,32 @@ }, "frame": { "x": 32, - "y": 128, + "y": 104, "w": 29, "h": 25 } }, + { + "filename": "609", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 29, + "h": 23 + }, + "frame": { + "x": 32, + "y": 129, + "w": 29, + "h": 23 + } + }, { "filename": "530", "rotated": false, @@ -844,11 +886,32 @@ }, "frame": { "x": 32, - "y": 153, + "y": 152, "w": 29, "h": 22 } }, + { + "filename": "569", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 30, + "h": 22 + }, + "frame": { + "x": 30, + "y": 174, + "w": 30, + "h": 22 + } + }, { "filename": "569s", "rotated": false, @@ -865,7 +928,7 @@ }, "frame": { "x": 30, - "y": 175, + "y": 196, "w": 30, "h": 22 } @@ -886,7 +949,7 @@ }, "frame": { "x": 30, - "y": 197, + "y": 218, "w": 30, "h": 22 } @@ -907,53 +970,11 @@ }, "frame": { "x": 30, - "y": 219, + "y": 240, "w": 30, "h": 22 } }, - { - "filename": "598", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 30, - "h": 22 - }, - "frame": { - "x": 30, - "y": 241, - "w": 30, - "h": 22 - } - }, - { - "filename": "609", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 29, - "h": 23 - }, - "frame": { - "x": 31, - "y": 263, - "w": 29, - "h": 23 - } - }, { "filename": "609s", "rotated": false, @@ -970,7 +991,7 @@ }, "frame": { "x": 31, - "y": 286, + "y": 262, "w": 29, "h": 23 } @@ -991,7 +1012,7 @@ }, "frame": { "x": 31, - "y": 309, + "y": 285, "w": 29, "h": 22 } @@ -1012,7 +1033,7 @@ }, "frame": { "x": 31, - "y": 331, + "y": 307, "w": 27, "h": 24 } @@ -1033,11 +1054,53 @@ }, "frame": { "x": 31, - "y": 355, + "y": 331, "w": 27, "h": 24 } }, + { + "filename": "623", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 3, + "w": 26, + "h": 25 + }, + "frame": { + "x": 31, + "y": 355, + "w": 26, + "h": 25 + } + }, + { + "filename": "623s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 3, + "w": 26, + "h": 25 + }, + "frame": { + "x": 31, + "y": 380, + "w": 26, + "h": 25 + } + }, { "filename": "508", "rotated": false, @@ -1054,7 +1117,7 @@ }, "frame": { "x": 31, - "y": 379, + "y": 405, "w": 27, "h": 23 } @@ -1075,7 +1138,7 @@ }, "frame": { "x": 30, - "y": 402, + "y": 428, "w": 28, "h": 23 } @@ -1096,7 +1159,7 @@ }, "frame": { "x": 30, - "y": 425, + "y": 451, "w": 28, "h": 23 } @@ -1117,7 +1180,7 @@ }, "frame": { "x": 30, - "y": 448, + "y": 474, "w": 28, "h": 23 } @@ -1138,7 +1201,7 @@ }, "frame": { "x": 30, - "y": 471, + "y": 497, "w": 28, "h": 23 } @@ -1159,13 +1222,13 @@ }, "frame": { "x": 30, - "y": 494, + "y": 520, "w": 28, "h": 22 } }, { - "filename": "598s", + "filename": "598", "rotated": false, "trimmed": true, "sourceSize": { @@ -1180,7 +1243,7 @@ }, "frame": { "x": 27, - "y": 516, + "y": 542, "w": 30, "h": 22 } @@ -1201,13 +1264,13 @@ }, "frame": { "x": 27, - "y": 538, + "y": 564, "w": 29, "h": 20 } }, { - "filename": "623", + "filename": "497s", "rotated": false, "trimmed": true, "sourceSize": { @@ -1216,19 +1279,19 @@ }, "spriteSourceSize": { "x": 6, - "y": 3, - "w": 26, - "h": 25 + "y": 6, + "w": 28, + "h": 22 }, "frame": { "x": 28, - "y": 558, - "w": 26, - "h": 25 + "y": 584, + "w": 28, + "h": 22 } }, { - "filename": "623s", + "filename": "508s", "rotated": false, "trimmed": true, "sourceSize": { @@ -1236,16 +1299,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 26, - "h": 25 + "x": 7, + "y": 5, + "w": 27, + "h": 23 }, "frame": { "x": 28, - "y": 583, - "w": 26, - "h": 25 + "y": 606, + "w": 27, + "h": 23 } }, { @@ -1264,7 +1327,7 @@ }, "frame": { "x": 29, - "y": 608, + "y": 629, "w": 25, "h": 25 } @@ -1285,13 +1348,13 @@ }, "frame": { "x": 29, - "y": 633, + "y": 654, "w": 25, "h": 25 } }, { - "filename": "508s", + "filename": "586-autumn", "rotated": false, "trimmed": true, "sourceSize": { @@ -1300,15 +1363,15 @@ }, "spriteSourceSize": { "x": 7, - "y": 5, - "w": 27, - "h": 23 + "y": 3, + "w": 25, + "h": 25 }, "frame": { - "x": 31, - "y": 658, - "w": 27, - "h": 23 + "x": 29, + "y": 679, + "w": 25, + "h": 25 } }, { @@ -1354,7 +1417,7 @@ } }, { - "filename": "604", + "filename": "598s", "rotated": false, "trimmed": true, "sourceSize": { @@ -1375,7 +1438,7 @@ } }, { - "filename": "604s", + "filename": "604", "rotated": false, "trimmed": true, "sourceSize": { @@ -1396,7 +1459,7 @@ } }, { - "filename": "647-resolute", + "filename": "604s", "rotated": false, "trimmed": true, "sourceSize": { @@ -1405,7 +1468,7 @@ }, "spriteSourceSize": { "x": 5, - "y": 6, + "y": 7, "w": 30, "h": 22 }, @@ -1417,7 +1480,7 @@ } }, { - "filename": "647s-resolute", + "filename": "647-resolute", "rotated": false, "trimmed": true, "sourceSize": { @@ -1437,6 +1500,27 @@ "h": 22 } }, + { + "filename": "647s-resolute", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 30, + "h": 22 + }, + "frame": { + "x": 101, + "y": 49, + "w": 30, + "h": 22 + } + }, { "filename": "545", "rotated": false, @@ -1452,7 +1536,7 @@ "h": 22 }, "frame": { - "x": 101, + "x": 131, "y": 49, "w": 29, "h": 22 @@ -1473,7 +1557,7 @@ "h": 22 }, "frame": { - "x": 130, + "x": 160, "y": 49, "w": 29, "h": 22 @@ -1494,12 +1578,33 @@ "h": 22 }, "frame": { - "x": 159, + "x": 189, "y": 49, "w": 29, "h": 22 } }, + { + "filename": "523", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 27, + "h": 23 + }, + "frame": { + "x": 218, + "y": 52, + "w": 27, + "h": 23 + } + }, { "filename": "571s", "rotated": false, @@ -1515,35 +1620,14 @@ "h": 22 }, "frame": { - "x": 188, - "y": 49, + "x": 99, + "y": 71, "w": 29, "h": 22 } }, { - "filename": "639s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 5, - "y": 8, - "w": 29, - "h": 20 - }, - "frame": { - "x": 99, - "y": 71, - "w": 29, - "h": 20 - } - }, - { - "filename": "497s", + "filename": "593", "rotated": false, "trimmed": true, "sourceSize": { @@ -1564,7 +1648,7 @@ } }, { - "filename": "593", + "filename": "593s", "rotated": false, "trimmed": true, "sourceSize": { @@ -1585,7 +1669,7 @@ } }, { - "filename": "593s", + "filename": "596", "rotated": false, "trimmed": true, "sourceSize": { @@ -1605,6 +1689,27 @@ "h": 22 } }, + { + "filename": "639s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 8, + "w": 29, + "h": 20 + }, + "frame": { + "x": 212, + "y": 75, + "w": 29, + "h": 20 + } + }, { "filename": "537", "rotated": false, @@ -1621,7 +1726,7 @@ }, "frame": { "x": 98, - "y": 91, + "y": 93, "w": 28, "h": 21 } @@ -1648,7 +1753,7 @@ } }, { - "filename": "596", + "filename": "596s", "rotated": false, "trimmed": true, "sourceSize": { @@ -1669,7 +1774,7 @@ } }, { - "filename": "596s", + "filename": "523s", "rotated": false, "trimmed": true, "sourceSize": { @@ -1677,16 +1782,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 28, - "h": 22 + "x": 7, + "y": 5, + "w": 27, + "h": 23 }, "frame": { "x": 182, "y": 93, - "w": 28, - "h": 22 + "w": 27, + "h": 23 } }, { @@ -1704,8 +1809,8 @@ "h": 20 }, "frame": { - "x": 224, - "y": 26, + "x": 209, + "y": 95, "w": 28, "h": 20 } @@ -1725,75 +1830,12 @@ "h": 20 }, "frame": { - "x": 222, - "y": 46, + "x": 64, + "y": 98, "w": 28, "h": 20 } }, - { - "filename": "531-mega", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 22, - "h": 26 - }, - "frame": { - "x": 58, - "y": 331, - "w": 22, - "h": 26 - } - }, - { - "filename": "531s-mega", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 2, - "w": 22, - "h": 26 - }, - "frame": { - "x": 58, - "y": 357, - "w": 22, - "h": 26 - } - }, - { - "filename": "586-autumn", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 3, - "w": 25, - "h": 25 - }, - "frame": { - "x": 58, - "y": 383, - "w": 25, - "h": 25 - } - }, { "filename": "586s-autumn", "rotated": false, @@ -1809,8 +1851,8 @@ "h": 25 }, "frame": { - "x": 58, - "y": 408, + "x": 61, + "y": 118, "w": 25, "h": 25 } @@ -1830,29 +1872,8 @@ "h": 24 }, "frame": { - "x": 58, - "y": 433, - "w": 26, - "h": 24 - } - }, - { - "filename": "612s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 26, - "h": 24 - }, - "frame": { - "x": 58, - "y": 457, + "x": 61, + "y": 143, "w": 26, "h": 24 } @@ -1872,12 +1893,33 @@ "h": 23 }, "frame": { - "x": 58, - "y": 481, + "x": 61, + "y": 167, "w": 26, "h": 23 } }, + { + "filename": "612s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 26, + "h": 24 + }, + "frame": { + "x": 60, + "y": 190, + "w": 26, + "h": 24 + } + }, { "filename": "510s", "rotated": false, @@ -1893,138 +1935,12 @@ "h": 23 }, "frame": { - "x": 58, - "y": 504, + "x": 60, + "y": 214, "w": 26, "h": 23 } }, - { - "filename": "523", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 27, - "h": 23 - }, - "frame": { - "x": 57, - "y": 527, - "w": 27, - "h": 23 - } - }, - { - "filename": "631", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 28, - "h": 20 - }, - "frame": { - "x": 56, - "y": 550, - "w": 28, - "h": 20 - } - }, - { - "filename": "523s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 27, - "h": 23 - }, - "frame": { - "x": 54, - "y": 570, - "w": 27, - "h": 23 - } - }, - { - "filename": "621", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 27, - "h": 23 - }, - "frame": { - "x": 54, - "y": 593, - "w": 27, - "h": 23 - } - }, - { - "filename": "621s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 27, - "h": 23 - }, - "frame": { - "x": 54, - "y": 616, - "w": 27, - "h": 23 - } - }, - { - "filename": "600", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 5, - "y": 9, - "w": 27, - "h": 19 - }, - "frame": { - "x": 54, - "y": 639, - "w": 27, - "h": 19 - } - }, { "filename": "584", "rotated": false, @@ -2040,96 +1956,12 @@ "h": 23 }, "frame": { - "x": 58, - "y": 658, + "x": 60, + "y": 237, "w": 26, "h": 23 } }, - { - "filename": "498", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 18, - "h": 18 - }, - "frame": { - "x": 80, - "y": 98, - "w": 18, - "h": 18 - } - }, - { - "filename": "502", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 19, - "h": 23 - }, - "frame": { - "x": 61, - "y": 103, - "w": 19, - "h": 23 - } - }, - { - "filename": "640", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 2, - "w": 21, - "h": 26 - }, - "frame": { - "x": 61, - "y": 126, - "w": 21, - "h": 26 - } - }, - { - "filename": "556", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 61, - "y": 152, - "w": 23, - "h": 23 - } - }, { "filename": "584s", "rotated": false, @@ -2146,13 +1978,13 @@ }, "frame": { "x": 60, - "y": 175, + "y": 260, "w": 26, "h": 23 } }, { - "filename": "514", + "filename": "621", "rotated": false, "trimmed": true, "sourceSize": { @@ -2160,20 +1992,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 26, - "h": 22 + "x": 6, + "y": 5, + "w": 27, + "h": 23 }, "frame": { "x": 60, - "y": 198, - "w": 26, - "h": 22 + "y": 283, + "w": 27, + "h": 23 } }, { - "filename": "514s", + "filename": "638", "rotated": false, "trimmed": true, "sourceSize": { @@ -2181,16 +2013,79 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 26, - "h": 22 + "x": 10, + "y": 3, + "w": 20, + "h": 25 }, "frame": { - "x": 60, - "y": 220, - "w": 26, - "h": 22 + "x": 86, + "y": 118, + "w": 20, + "h": 25 + } + }, + { + "filename": "621s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 27, + "h": 23 + }, + "frame": { + "x": 106, + "y": 114, + "w": 27, + "h": 23 + } + }, + { + "filename": "531-mega", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 2, + "w": 22, + "h": 26 + }, + "frame": { + "x": 87, + "y": 143, + "w": 22, + "h": 26 + } + }, + { + "filename": "561", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 5, + "w": 21, + "h": 23 + }, + "frame": { + "x": 133, + "y": 114, + "w": 21, + "h": 23 } }, { @@ -2208,8 +2103,8 @@ "h": 22 }, "frame": { - "x": 60, - "y": 242, + "x": 154, + "y": 115, "w": 27, "h": 22 } @@ -2229,119 +2124,14 @@ "h": 22 }, "frame": { - "x": 60, - "y": 264, - "w": 27, - "h": 22 - } - }, - { - "filename": "634", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 60, - "y": 286, - "w": 26, - "h": 22 - } - }, - { - "filename": "556s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 60, - "y": 308, - "w": 23, - "h": 23 - } - }, - { - "filename": "631s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 28, - "h": 20 - }, - "frame": { - "x": 98, - "y": 112, - "w": 28, - "h": 20 - } - }, - { - "filename": "600s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 5, - "y": 9, - "w": 27, - "h": 19 - }, - "frame": { - "x": 126, - "y": 114, - "w": 27, - "h": 19 - } - }, - { - "filename": "630", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 16, - "h": 22 - }, - "frame": { - "x": 82, + "x": 181, "y": 116, - "w": 16, + "w": 27, "h": 22 } }, { - "filename": "567", + "filename": "499", "rotated": false, "trimmed": true, "sourceSize": { @@ -2349,20 +2139,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, + "x": 10, "y": 7, - "w": 26, + "w": 23, "h": 21 }, "frame": { - "x": 153, - "y": 115, - "w": 26, + "x": 87, + "y": 169, + "w": 23, "h": 21 } }, { - "filename": "567s", + "filename": "531s-mega", "rotated": false, "trimmed": true, "sourceSize": { @@ -2370,78 +2160,15 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 26, - "h": 21 - }, - "frame": { - "x": 179, - "y": 115, - "w": 26, - "h": 21 - } - }, - { - "filename": "543", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 14, - "w": 18, - "h": 14 - }, - "frame": { - "x": 82, - "y": 138, - "w": 18, - "h": 14 - } - }, - { - "filename": "502s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 19, - "h": 23 - }, - "frame": { - "x": 84, - "y": 152, - "w": 19, - "h": 23 - } - }, - { - "filename": "640s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, + "x": 10, "y": 2, - "w": 21, + "w": 22, "h": 26 }, "frame": { "x": 86, - "y": 175, - "w": 21, + "y": 190, + "w": 22, "h": 26 } }, @@ -2461,13 +2188,13 @@ }, "frame": { "x": 86, - "y": 201, + "y": 216, "w": 23, "h": 24 } }, { - "filename": "528", + "filename": "586-summer", "rotated": false, "trimmed": true, "sourceSize": { @@ -2475,20 +2202,104 @@ "h": 30 }, "spriteSourceSize": { - "x": 9, - "y": 8, + "x": 8, + "y": 4, "w": 23, - "h": 20 + "h": 24 }, "frame": { - "x": 100, - "y": 132, + "x": 86, + "y": 240, "w": 23, - "h": 20 + "h": 24 } }, { - "filename": "521", + "filename": "532", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 9, + "w": 24, + "h": 19 + }, + "frame": { + "x": 86, + "y": 264, + "w": 24, + "h": 19 + } + }, + { + "filename": "556", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 87, + "y": 283, + "w": 23, + "h": 23 + } + }, + { + "filename": "514", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 109, + "y": 137, + "w": 26, + "h": 22 + } + }, + { + "filename": "514s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 135, + "y": 137, + "w": 26, + "h": 22 + } + }, + { + "filename": "505", "rotated": false, "trimmed": true, "sourceSize": { @@ -2497,19 +2308,19 @@ }, "spriteSourceSize": { "x": 10, - "y": 5, + "y": 6, "w": 20, - "h": 23 + "h": 22 }, "frame": { - "x": 103, - "y": 152, + "x": 161, + "y": 137, "w": 20, - "h": 23 + "h": 22 } }, { - "filename": "634s", + "filename": "567", "rotated": false, "trimmed": true, "sourceSize": { @@ -2517,16 +2328,121 @@ "h": 30 }, "spriteSourceSize": { - "x": 7, - "y": 6, + "x": 8, + "y": 7, "w": 26, - "h": 22 + "h": 21 }, "frame": { - "x": 123, - "y": 133, + "x": 181, + "y": 138, "w": 26, - "h": 22 + "h": 21 + } + }, + { + "filename": "631", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 28, + "h": 20 + }, + "frame": { + "x": 110, + "y": 159, + "w": 28, + "h": 20 + } + }, + { + "filename": "631s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 28, + "h": 20 + }, + "frame": { + "x": 138, + "y": 159, + "w": 28, + "h": 20 + } + }, + { + "filename": "567s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 26, + "h": 21 + }, + "frame": { + "x": 166, + "y": 159, + "w": 26, + "h": 21 + } + }, + { + "filename": "600", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 9, + "w": 27, + "h": 19 + }, + "frame": { + "x": 110, + "y": 179, + "w": 27, + "h": 19 + } + }, + { + "filename": "600s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 9, + "w": 27, + "h": 19 + }, + "frame": { + "x": 137, + "y": 179, + "w": 27, + "h": 19 } }, { @@ -2544,14 +2460,14 @@ "h": 21 }, "frame": { - "x": 123, - "y": 155, + "x": 164, + "y": 180, "w": 26, "h": 21 } }, { - "filename": "637", + "filename": "568", "rotated": false, "trimmed": true, "sourceSize": { @@ -2559,20 +2475,41 @@ "h": 30 }, "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 26, - "h": 22 + "x": 9, + "y": 10, + "w": 21, + "h": 18 }, "frame": { - "x": 149, - "y": 136, - "w": 26, - "h": 22 + "x": 108, + "y": 198, + "w": 21, + "h": 18 } }, { - "filename": "637s", + "filename": "638s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 3, + "w": 20, + "h": 25 + }, + "frame": { + "x": 109, + "y": 216, + "w": 20, + "h": 25 + } + }, + { + "filename": "634", "rotated": false, "trimmed": true, "sourceSize": { @@ -2586,8 +2523,8 @@ "h": 22 }, "frame": { - "x": 175, - "y": 136, + "x": 129, + "y": 198, "w": 26, "h": 22 } @@ -2607,14 +2544,14 @@ "h": 21 }, "frame": { - "x": 149, - "y": 158, + "x": 129, + "y": 220, "w": 26, "h": 21 } }, { - "filename": "552", + "filename": "634s", "rotated": false, "trimmed": true, "sourceSize": { @@ -2622,100 +2559,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 25, - "h": 21 + "x": 7, + "y": 6, + "w": 26, + "h": 22 }, "frame": { - "x": 175, - "y": 158, - "w": 25, - "h": 21 - } - }, - { - "filename": "529", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 21, - "h": 17 - }, - "frame": { - "x": 86, - "y": 225, - "w": 21, - "h": 17 - } - }, - { - "filename": "638", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 20, - "h": 25 - }, - "frame": { - "x": 87, - "y": 242, - "w": 20, - "h": 25 - } - }, - { - "filename": "496", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 22, - "h": 20 - }, - "frame": { - "x": 87, - "y": 267, - "w": 22, - "h": 20 - } - }, - { - "filename": "499", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 23, - "h": 21 - }, - "frame": { - "x": 86, - "y": 287, - "w": 23, - "h": 21 + "x": 109, + "y": 241, + "w": 26, + "h": 22 } }, { @@ -2733,35 +2586,14 @@ "h": 22 }, "frame": { - "x": 83, - "y": 308, + "x": 110, + "y": 263, "w": 25, "h": 22 } }, { - "filename": "630s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 16, - "h": 22 - }, - "frame": { - "x": 107, - "y": 175, - "w": 16, - "h": 22 - } - }, - { - "filename": "552s", + "filename": "552", "rotated": false, "trimmed": true, "sourceSize": { @@ -2775,180 +2607,12 @@ "h": 21 }, "frame": { - "x": 123, - "y": 176, + "x": 110, + "y": 285, "w": 25, "h": 21 } }, - { - "filename": "565s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 109, - "y": 197, - "w": 25, - "h": 22 - } - }, - { - "filename": "611", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 25, - "h": 21 - }, - "frame": { - "x": 148, - "y": 179, - "w": 25, - "h": 21 - } - }, - { - "filename": "611s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 25, - "h": 21 - }, - "frame": { - "x": 173, - "y": 179, - "w": 25, - "h": 21 - } - }, - { - "filename": "542", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 14, - "h": 21 - }, - "frame": { - "x": 134, - "y": 197, - "w": 14, - "h": 21 - } - }, - { - "filename": "620", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 148, - "y": 200, - "w": 25, - "h": 22 - } - }, - { - "filename": "620s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 173, - "y": 200, - "w": 25, - "h": 22 - } - }, - { - "filename": "628", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 10, - "w": 25, - "h": 19 - }, - "frame": { - "x": 109, - "y": 219, - "w": 25, - "h": 19 - } - }, - { - "filename": "586-summer", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 107, - "y": 238, - "w": 23, - "h": 24 - } - }, { "filename": "586-winter", "rotated": false, @@ -2964,222 +2628,12 @@ "h": 24 }, "frame": { - "x": 109, - "y": 262, + "x": 135, + "y": 241, "w": 23, "h": 24 } }, - { - "filename": "518", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 109, - "y": 286, - "w": 23, - "h": 22 - } - }, - { - "filename": "647-ordinary", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 108, - "y": 308, - "w": 25, - "h": 22 - } - }, - { - "filename": "542s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 14, - "h": 21 - }, - "frame": { - "x": 134, - "y": 218, - "w": 14, - "h": 21 - } - }, - { - "filename": "628s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 10, - "w": 25, - "h": 19 - }, - "frame": { - "x": 148, - "y": 222, - "w": 25, - "h": 19 - } - }, - { - "filename": "647s-ordinary", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 173, - "y": 222, - "w": 25, - "h": 22 - } - }, - { - "filename": "585-autumn", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 18, - "h": 22 - }, - "frame": { - "x": 130, - "y": 239, - "w": 18, - "h": 22 - } - }, - { - "filename": "516", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 24, - "h": 21 - }, - "frame": { - "x": 148, - "y": 241, - "w": 24, - "h": 21 - } - }, - { - "filename": "516s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 24, - "h": 21 - }, - "frame": { - "x": 172, - "y": 244, - "w": 24, - "h": 21 - } - }, - { - "filename": "648-pirouette", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 15, - "h": 23 - }, - "frame": { - "x": 132, - "y": 261, - "w": 15, - "h": 23 - } - }, - { - "filename": "518s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 147, - "y": 262, - "w": 23, - "h": 22 - } - }, { "filename": "586s-spring", "rotated": false, @@ -3195,14 +2649,56 @@ "h": 24 }, "frame": { - "x": 132, - "y": 284, + "x": 135, + "y": 265, "w": 23, "h": 24 } }, { - "filename": "531", + "filename": "499s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 23, + "h": 21 + }, + "frame": { + "x": 135, + "y": 289, + "w": 23, + "h": 21 + } + }, + { + "filename": "637", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 155, + "y": 201, + "w": 26, + "h": 22 + } + }, + { + "filename": "568s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3211,78 +2707,15 @@ }, "spriteSourceSize": { "x": 9, - "y": 6, - "w": 22, - "h": 22 - }, - "frame": { - "x": 133, - "y": 308, - "w": 22, - "h": 22 - } - }, - { - "filename": "525", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 24, - "h": 21 - }, - "frame": { - "x": 170, - "y": 265, - "w": 24, - "h": 21 - } - }, - { - "filename": "648s-pirouette", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 15, - "h": 23 + "y": 10, + "w": 21, + "h": 18 }, "frame": { "x": 155, - "y": 284, - "w": 15, - "h": 23 - } - }, - { - "filename": "525s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 24, - "h": 21 - }, - "frame": { - "x": 170, - "y": 286, - "w": 24, - "h": 21 + "y": 223, + "w": 21, + "h": 18 } }, { @@ -3300,8 +2733,8 @@ "h": 24 }, "frame": { - "x": 155, - "y": 307, + "x": 158, + "y": 241, "w": 23, "h": 24 } @@ -3321,14 +2754,98 @@ "h": 24 }, "frame": { - "x": 178, - "y": 307, + "x": 158, + "y": 265, "w": 23, "h": 24 } }, { - "filename": "638s", + "filename": "516", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 24, + "h": 21 + }, + "frame": { + "x": 158, + "y": 289, + "w": 24, + "h": 21 + } + }, + { + "filename": "494", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 192, + "y": 159, + "w": 18, + "h": 22 + } + }, + { + "filename": "496", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 22, + "h": 20 + }, + "frame": { + "x": 190, + "y": 181, + "w": 22, + "h": 20 + } + }, + { + "filename": "637s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 181, + "y": 201, + "w": 26, + "h": 22 + } + }, + { + "filename": "504", "rotated": false, "trimmed": true, "sourceSize": { @@ -3337,15 +2854,15 @@ }, "spriteSourceSize": { "x": 10, - "y": 3, + "y": 10, "w": 20, - "h": 25 + "h": 18 }, "frame": { - "x": 81, - "y": 570, + "x": 176, + "y": 223, "w": 20, - "h": 25 + "h": 18 } }, { @@ -3363,8 +2880,8 @@ "h": 24 }, "frame": { - "x": 81, - "y": 595, + "x": 181, + "y": 241, "w": 23, "h": 24 } @@ -3384,14 +2901,161 @@ "h": 24 }, "frame": { - "x": 81, - "y": 619, + "x": 181, + "y": 265, "w": 23, "h": 24 } }, { - "filename": "564", + "filename": "516s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 24, + "h": 21 + }, + "frame": { + "x": 182, + "y": 289, + "w": 24, + "h": 21 + } + }, + { + "filename": "498", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 10, + "w": 18, + "h": 18 + }, + "frame": { + "x": 196, + "y": 223, + "w": 18, + "h": 18 + } + }, + { + "filename": "494s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 207, + "y": 201, + "w": 18, + "h": 22 + } + }, + { + "filename": "521", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 5, + "w": 20, + "h": 23 + }, + "frame": { + "x": 225, + "y": 115, + "w": 20, + "h": 23 + } + }, + { + "filename": "522", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 17, + "h": 22 + }, + "frame": { + "x": 208, + "y": 116, + "w": 17, + "h": 22 + } + }, + { + "filename": "552s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 25, + "h": 21 + }, + "frame": { + "x": 207, + "y": 138, + "w": 25, + "h": 21 + } + }, + { + "filename": "594", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 6, + "w": 13, + "h": 22 + }, + "frame": { + "x": 232, + "y": 138, + "w": 13, + "h": 22 + } + }, + { + "filename": "531", "rotated": false, "trimmed": true, "sourceSize": { @@ -3400,19 +3064,103 @@ }, "spriteSourceSize": { "x": 9, - "y": 13, - "w": 23, - "h": 15 + "y": 6, + "w": 22, + "h": 22 }, "frame": { - "x": 81, - "y": 643, - "w": 23, - "h": 15 + "x": 210, + "y": 159, + "w": 22, + "h": 22 } }, { - "filename": "561", + "filename": "594s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 6, + "w": 13, + "h": 22 + }, + "frame": { + "x": 232, + "y": 160, + "w": 13, + "h": 22 + } + }, + { + "filename": "513", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 8, + "w": 20, + "h": 20 + }, + "frame": { + "x": 212, + "y": 181, + "w": 20, + "h": 20 + } + }, + { + "filename": "521s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 5, + "w": 20, + "h": 23 + }, + "frame": { + "x": 225, + "y": 201, + "w": 20, + "h": 23 + } + }, + { + "filename": "605", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 9, + "w": 13, + "h": 19 + }, + "frame": { + "x": 232, + "y": 182, + "w": 13, + "h": 19 + } + }, + { + "filename": "625", "rotated": false, "trimmed": true, "sourceSize": { @@ -3422,18 +3170,123 @@ "spriteSourceSize": { "x": 9, "y": 5, - "w": 21, + "w": 22, + "h": 24 + }, + "frame": { + "x": 204, + "y": 241, + "w": 22, + "h": 24 + } + }, + { + "filename": "502", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 19, "h": 23 }, "frame": { - "x": 84, - "y": 658, - "w": 21, + "x": 226, + "y": 224, + "w": 19, "h": 23 } }, { - "filename": "505", + "filename": "502s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 19, + "h": 23 + }, + "frame": { + "x": 226, + "y": 247, + "w": 19, + "h": 23 + } + }, + { + "filename": "625s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 5, + "w": 22, + "h": 24 + }, + "frame": { + "x": 204, + "y": 265, + "w": 22, + "h": 24 + } + }, + { + "filename": "520", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 226, + "y": 270, + "w": 19, + "h": 20 + } + }, + { + "filename": "588", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 11, + "w": 12, + "h": 17 + }, + "frame": { + "x": 214, + "y": 224, + "w": 12, + "h": 17 + } + }, + { + "filename": "505s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3447,14 +3300,77 @@ "h": 22 }, "frame": { - "x": 212, - "y": 71, + "x": 206, + "y": 289, "w": 20, "h": 22 } }, { - "filename": "573", + "filename": "520s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 226, + "y": 290, + "w": 19, + "h": 20 + } + }, + { + "filename": "592-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 226, + "y": 310, + "w": 19, + "h": 20 + } + }, + { + "filename": "565s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 60, + "y": 306, + "w": 25, + "h": 22 + } + }, + { + "filename": "620", "rotated": false, "trimmed": true, "sourceSize": { @@ -3463,19 +3379,124 @@ }, "spriteSourceSize": { "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 85, + "y": 306, + "w": 25, + "h": 22 + } + }, + { + "filename": "620s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 110, + "y": 306, + "w": 25, + "h": 22 + } + }, + { + "filename": "647-ordinary", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 58, + "y": 328, + "w": 25, + "h": 22 + } + }, + { + "filename": "647s-ordinary", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 83, + "y": 328, + "w": 25, + "h": 22 + } + }, + { + "filename": "611", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, "y": 7, - "w": 24, + "w": 25, "h": 21 }, "frame": { - "x": 232, - "y": 66, - "w": 24, + "x": 108, + "y": 328, + "w": 25, "h": 21 } }, { - "filename": "573s", + "filename": "611s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 25, + "h": 21 + }, + "frame": { + "x": 135, + "y": 310, + "w": 25, + "h": 21 + } + }, + { + "filename": "525", "rotated": false, "trimmed": true, "sourceSize": { @@ -3489,8 +3510,8 @@ "h": 21 }, "frame": { - "x": 232, - "y": 87, + "x": 160, + "y": 310, "w": 24, "h": 21 } @@ -3510,14 +3531,14 @@ "h": 22 }, "frame": { - "x": 210, - "y": 93, + "x": 184, + "y": 310, "w": 22, "h": 22 } }, { - "filename": "532", + "filename": "511", "rotated": false, "trimmed": true, "sourceSize": { @@ -3525,20 +3546,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 9, - "w": 24, - "h": 19 + "x": 11, + "y": 7, + "w": 20, + "h": 21 }, "frame": { - "x": 232, - "y": 108, - "w": 24, - "h": 19 + "x": 206, + "y": 311, + "w": 20, + "h": 21 } }, { - "filename": "499s", + "filename": "592", "rotated": false, "trimmed": true, "sourceSize": { @@ -3547,122 +3568,143 @@ }, "spriteSourceSize": { "x": 10, - "y": 7, - "w": 23, - "h": 21 - }, - "frame": { - "x": 205, - "y": 115, - "w": 23, - "h": 21 - } - }, - { - "filename": "555", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 201, - "y": 136, - "w": 23, - "h": 22 - } - }, - { - "filename": "555s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 200, - "y": 158, - "w": 23, - "h": 22 - } - }, - { - "filename": "625", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 22, - "h": 24 - }, - "frame": { - "x": 198, - "y": 180, - "w": 22, - "h": 24 - } - }, - { - "filename": "625s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 22, - "h": 24 - }, - "frame": { - "x": 198, - "y": 204, - "w": 22, - "h": 24 - } - }, - { - "filename": "496s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, "y": 8, - "w": 22, + "w": 19, "h": 20 }, "frame": { - "x": 198, - "y": 228, - "w": 22, + "x": 226, + "y": 330, + "w": 19, "h": 20 } }, + { + "filename": "628", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 10, + "w": 25, + "h": 19 + }, + "frame": { + "x": 133, + "y": 331, + "w": 25, + "h": 19 + } + }, + { + "filename": "628s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 10, + "w": 25, + "h": 19 + }, + "frame": { + "x": 158, + "y": 331, + "w": 25, + "h": 19 + } + }, + { + "filename": "525s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 24, + "h": 21 + }, + "frame": { + "x": 183, + "y": 332, + "w": 24, + "h": 21 + } + }, + { + "filename": "592s-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 207, + "y": 332, + "w": 19, + "h": 20 + } + }, + { + "filename": "592s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 226, + "y": 350, + "w": 19, + "h": 20 + } + }, + { + "filename": "608", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 10, + "w": 19, + "h": 18 + }, + "frame": { + "x": 207, + "y": 352, + "w": 19, + "h": 18 + } + }, { "filename": "532s", "rotated": false, @@ -3678,14 +3720,14 @@ "h": 19 }, "frame": { - "x": 196, - "y": 248, + "x": 58, + "y": 350, "w": 24, "h": 19 } }, { - "filename": "649", + "filename": "556s", "rotated": false, "trimmed": true, "sourceSize": { @@ -3695,18 +3737,18 @@ "spriteSourceSize": { "x": 8, "y": 5, - "w": 22, - "h": 24 + "w": 23, + "h": 23 }, "frame": { - "x": 194, - "y": 267, - "w": 22, - "h": 24 + "x": 57, + "y": 369, + "w": 23, + "h": 23 } }, { - "filename": "544", + "filename": "573", "rotated": false, "trimmed": true, "sourceSize": { @@ -3714,16 +3756,37 @@ "h": 30 }, "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 22, - "h": 16 + "x": 8, + "y": 7, + "w": 24, + "h": 21 }, "frame": { - "x": 194, - "y": 291, - "w": 22, - "h": 16 + "x": 82, + "y": 350, + "w": 24, + "h": 21 + } + }, + { + "filename": "573s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 24, + "h": 21 + }, + "frame": { + "x": 80, + "y": 371, + "w": 24, + "h": 21 } }, { @@ -3741,75 +3804,12 @@ "h": 24 }, "frame": { - "x": 201, - "y": 307, + "x": 58, + "y": 392, "w": 22, "h": 24 } }, - { - "filename": "632", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 12, - "w": 24, - "h": 16 - }, - "frame": { - "x": 228, - "y": 127, - "w": 24, - "h": 16 - } - }, - { - "filename": "632s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 12, - "w": 24, - "h": 16 - }, - "frame": { - "x": 224, - "y": 143, - "w": 24, - "h": 16 - } - }, - { - "filename": "614", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 223, - "y": 159, - "w": 23, - "h": 22 - } - }, { "filename": "649-chill", "rotated": false, @@ -3825,33 +3825,12 @@ "h": 24 }, "frame": { - "x": 220, - "y": 181, + "x": 58, + "y": 416, "w": 22, "h": 24 } }, - { - "filename": "648-aria", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 14, - "h": 21 - }, - "frame": { - "x": 242, - "y": 181, - "w": 14, - "h": 21 - } - }, { "filename": "649-douse", "rotated": false, @@ -3867,33 +3846,12 @@ "h": 24 }, "frame": { - "x": 220, - "y": 205, + "x": 80, + "y": 392, "w": 22, "h": 24 } }, - { - "filename": "648s-aria", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 14, - "h": 21 - }, - "frame": { - "x": 242, - "y": 202, - "w": 14, - "h": 21 - } - }, { "filename": "649-shock", "rotated": false, @@ -3909,98 +3867,14 @@ "h": 24 }, "frame": { - "x": 220, - "y": 229, + "x": 58, + "y": 440, "w": 22, "h": 24 } }, { - "filename": "624", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 14, - "h": 20 - }, - "frame": { - "x": 242, - "y": 223, - "w": 14, - "h": 20 - } - }, - { - "filename": "624s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 8, - "w": 14, - "h": 20 - }, - "frame": { - "x": 242, - "y": 243, - "w": 14, - "h": 20 - } - }, - { - "filename": "539", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 22, - "h": 22 - }, - "frame": { - "x": 220, - "y": 253, - "w": 22, - "h": 22 - } - }, - { - "filename": "574", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 10, - "w": 14, - "h": 18 - }, - "frame": { - "x": 242, - "y": 263, - "w": 14, - "h": 18 - } - }, - { - "filename": "649s", + "filename": "649", "rotated": false, "trimmed": true, "sourceSize": { @@ -4014,117 +3888,12 @@ "h": 24 }, "frame": { - "x": 216, - "y": 275, + "x": 80, + "y": 416, "w": 22, "h": 24 } }, - { - "filename": "585-spring", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 18, - "h": 22 - }, - "frame": { - "x": 238, - "y": 281, - "w": 18, - "h": 22 - } - }, - { - "filename": "606", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 15, - "h": 22 - }, - "frame": { - "x": 223, - "y": 299, - "w": 15, - "h": 22 - } - }, - { - "filename": "585-summer", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 18, - "h": 22 - }, - "frame": { - "x": 238, - "y": 303, - "w": 18, - "h": 22 - } - }, - { - "filename": "517", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 14, - "w": 15, - "h": 14 - }, - "frame": { - "x": 223, - "y": 321, - "w": 15, - "h": 14 - } - }, - { - "filename": "585-winter", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 18, - "h": 22 - }, - "frame": { - "x": 238, - "y": 325, - "w": 18, - "h": 22 - } - }, { "filename": "649s-burn", "rotated": false, @@ -4140,8 +3909,8 @@ "h": 24 }, "frame": { - "x": 80, - "y": 331, + "x": 58, + "y": 464, "w": 22, "h": 24 } @@ -4162,7 +3931,7 @@ }, "frame": { "x": 80, - "y": 355, + "y": 440, "w": 22, "h": 24 } @@ -4182,8 +3951,8 @@ "h": 24 }, "frame": { - "x": 102, - "y": 330, + "x": 58, + "y": 488, "w": 22, "h": 24 } @@ -4203,12 +3972,180 @@ "h": 24 }, "frame": { - "x": 124, - "y": 330, + "x": 80, + "y": 464, "w": 22, "h": 24 } }, + { + "filename": "649s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 22, + "h": 24 + }, + "frame": { + "x": 58, + "y": 512, + "w": 22, + "h": 24 + } + }, + { + "filename": "518", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 23, + "h": 22 + }, + "frame": { + "x": 80, + "y": 488, + "w": 23, + "h": 22 + } + }, + { + "filename": "518s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 23, + "h": 22 + }, + "frame": { + "x": 80, + "y": 510, + "w": 23, + "h": 22 + } + }, + { + "filename": "496s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 22, + "h": 20 + }, + "frame": { + "x": 58, + "y": 536, + "w": 22, + "h": 20 + } + }, + { + "filename": "555", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 23, + "h": 22 + }, + "frame": { + "x": 80, + "y": 532, + "w": 23, + "h": 22 + } + }, + { + "filename": "528", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 23, + "h": 20 + }, + "frame": { + "x": 57, + "y": 556, + "w": 23, + "h": 20 + } + }, + { + "filename": "555s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 23, + "h": 22 + }, + "frame": { + "x": 80, + "y": 554, + "w": 23, + "h": 22 + } + }, + { + "filename": "614", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 23, + "h": 22 + }, + "frame": { + "x": 56, + "y": 576, + "w": 23, + "h": 22 + } + }, { "filename": "614s", "rotated": false, @@ -4224,14 +4161,35 @@ "h": 22 }, "frame": { - "x": 102, - "y": 354, + "x": 79, + "y": 576, "w": 23, "h": 22 } }, { - "filename": "507", + "filename": "632", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 12, + "w": 24, + "h": 16 + }, + "frame": { + "x": 56, + "y": 598, + "w": 24, + "h": 16 + } + }, + { + "filename": "528s", "rotated": false, "trimmed": true, "sourceSize": { @@ -4240,59 +4198,59 @@ }, "spriteSourceSize": { "x": 9, + "y": 8, + "w": 23, + "h": 20 + }, + "frame": { + "x": 80, + "y": 598, + "w": 23, + "h": 20 + } + }, + { + "filename": "632s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 12, + "w": 24, + "h": 16 + }, + "frame": { + "x": 55, + "y": 614, + "w": 24, + "h": 16 + } + }, + { + "filename": "539", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, "y": 6, - "w": 21, + "w": 22, "h": 22 }, "frame": { - "x": 125, - "y": 354, - "w": 21, + "x": 54, + "y": 630, + "w": 22, "h": 22 } }, - { - "filename": "521s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 5, - "w": 20, - "h": 23 - }, - "frame": { - "x": 83, - "y": 379, - "w": 20, - "h": 23 - } - }, - { - "filename": "561s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 5, - "w": 21, - "h": 23 - }, - "frame": { - "x": 83, - "y": 402, - "w": 21, - "h": 23 - } - }, { "filename": "539s", "rotated": false, @@ -4308,12 +4266,96 @@ "h": 22 }, "frame": { - "x": 103, - "y": 376, + "x": 54, + "y": 652, "w": 22, "h": 22 } }, + { + "filename": "561s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 5, + "w": 21, + "h": 23 + }, + "frame": { + "x": 54, + "y": 674, + "w": 21, + "h": 23 + } + }, + { + "filename": "544", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 22, + "h": 16 + }, + "frame": { + "x": 54, + "y": 697, + "w": 22, + "h": 16 + } + }, + { + "filename": "564", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 13, + "w": 23, + "h": 15 + }, + "frame": { + "x": 79, + "y": 618, + "w": 23, + "h": 15 + } + }, + { + "filename": "507", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, + "w": 21, + "h": 22 + }, + "frame": { + "x": 76, + "y": 633, + "w": 21, + "h": 22 + } + }, { "filename": "507s", "rotated": false, @@ -4329,12 +4371,159 @@ "h": 22 }, "frame": { - "x": 125, - "y": 376, + "x": 76, + "y": 655, "w": 21, "h": 22 } }, + { + "filename": "575", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 22, + "h": 20 + }, + "frame": { + "x": 75, + "y": 677, + "w": 22, + "h": 20 + } + }, + { + "filename": "544s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 22, + "h": 16 + }, + "frame": { + "x": 76, + "y": 697, + "w": 22, + "h": 16 + } + }, + { + "filename": "648-pirouette", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 15, + "h": 23 + }, + "frame": { + "x": 97, + "y": 633, + "w": 15, + "h": 23 + } + }, + { + "filename": "648s-pirouette", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 15, + "h": 23 + }, + "frame": { + "x": 97, + "y": 656, + "w": 15, + "h": 23 + } + }, + { + "filename": "498s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 10, + "w": 18, + "h": 18 + }, + "frame": { + "x": 97, + "y": 679, + "w": 18, + "h": 18 + } + }, + { + "filename": "551", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 13, + "w": 22, + "h": 16 + }, + "frame": { + "x": 98, + "y": 697, + "w": 22, + "h": 16 + } + }, + { + "filename": "527", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 13, + "w": 20, + "h": 15 + }, + "frame": { + "x": 102, + "y": 618, + "w": 20, + "h": 15 + } + }, { "filename": "509", "rotated": false, @@ -4350,8 +4539,8 @@ "h": 22 }, "frame": { - "x": 104, - "y": 398, + "x": 112, + "y": 633, "w": 21, "h": 22 } @@ -4371,14 +4560,14 @@ "h": 22 }, "frame": { - "x": 125, - "y": 398, + "x": 112, + "y": 655, "w": 21, "h": 22 } }, { - "filename": "505s", + "filename": "513s", "rotated": false, "trimmed": true, "sourceSize": { @@ -4386,20 +4575,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, - "y": 6, + "x": 11, + "y": 8, "w": 20, - "h": 22 + "h": 20 }, "frame": { - "x": 84, - "y": 425, + "x": 115, + "y": 677, "w": 20, - "h": 22 + "h": 20 } }, { - "filename": "528s", + "filename": "551s", "rotated": false, "trimmed": true, "sourceSize": { @@ -4407,16 +4596,37 @@ "h": 30 }, "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 23, - "h": 20 + "x": 8, + "y": 13, + "w": 22, + "h": 16 }, "frame": { - "x": 104, - "y": 420, - "w": 23, - "h": 20 + "x": 120, + "y": 697, + "w": 22, + "h": 16 + } + }, + { + "filename": "522s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 17, + "h": 22 + }, + "frame": { + "x": 102, + "y": 392, + "w": 17, + "h": 22 } }, { @@ -4434,8 +4644,8 @@ "h": 22 }, "frame": { - "x": 84, - "y": 447, + "x": 102, + "y": 414, "w": 21, "h": 22 } @@ -4455,8 +4665,8 @@ "h": 22 }, "frame": { - "x": 84, - "y": 469, + "x": 102, + "y": 436, "w": 21, "h": 22 } @@ -4476,12 +4686,33 @@ "h": 21 }, "frame": { - "x": 84, - "y": 491, + "x": 102, + "y": 458, "w": 21, "h": 21 } }, + { + "filename": "511s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 7, + "w": 20, + "h": 21 + }, + "frame": { + "x": 104, + "y": 371, + "w": 20, + "h": 21 + } + }, { "filename": "515s", "rotated": false, @@ -4497,138 +4728,12 @@ "h": 21 }, "frame": { - "x": 84, - "y": 512, + "x": 106, + "y": 350, "w": 21, "h": 21 } }, - { - "filename": "576", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 20, - "h": 22 - }, - "frame": { - "x": 84, - "y": 533, - "w": 20, - "h": 22 - } - }, - { - "filename": "527", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 13, - "w": 20, - "h": 15 - }, - "frame": { - "x": 84, - "y": 555, - "w": 20, - "h": 15 - } - }, - { - "filename": "511", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 20, - "h": 21 - }, - "frame": { - "x": 127, - "y": 420, - "w": 20, - "h": 21 - } - }, - { - "filename": "575", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 22, - "h": 20 - }, - "frame": { - "x": 105, - "y": 440, - "w": 22, - "h": 20 - } - }, - { - "filename": "575s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 22, - "h": 20 - }, - "frame": { - "x": 105, - "y": 460, - "w": 22, - "h": 20 - } - }, - { - "filename": "576s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 20, - "h": 22 - }, - "frame": { - "x": 127, - "y": 441, - "w": 20, - "h": 22 - } - }, { "filename": "587", "rotated": false, @@ -4644,8 +4749,8 @@ "h": 20 }, "frame": { - "x": 105, - "y": 480, + "x": 127, + "y": 350, "w": 23, "h": 20 } @@ -4665,14 +4770,14 @@ "h": 20 }, "frame": { - "x": 105, - "y": 500, + "x": 150, + "y": 350, "w": 23, "h": 20 } }, { - "filename": "495", + "filename": "576", "rotated": false, "trimmed": true, "sourceSize": { @@ -4681,15 +4786,36 @@ }, "spriteSourceSize": { "x": 10, - "y": 11, + "y": 6, "w": 20, - "h": 17 + "h": 22 }, "frame": { - "x": 127, - "y": 463, + "x": 103, + "y": 479, "w": 20, - "h": 17 + "h": 22 + } + }, + { + "filename": "576s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 20, + "h": 22 + }, + "frame": { + "x": 103, + "y": 501, + "w": 20, + "h": 22 } }, { @@ -4707,180 +4833,12 @@ "h": 22 }, "frame": { - "x": 128, - "y": 480, + "x": 103, + "y": 523, "w": 20, "h": 22 } }, - { - "filename": "504", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 20, - "h": 18 - }, - "frame": { - "x": 128, - "y": 502, - "w": 20, - "h": 18 - } - }, - { - "filename": "564s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 13, - "w": 23, - "h": 15 - }, - "frame": { - "x": 105, - "y": 520, - "w": 23, - "h": 15 - } - }, - { - "filename": "617", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 23, - "h": 20 - }, - "frame": { - "x": 104, - "y": 535, - "w": 23, - "h": 20 - } - }, - { - "filename": "617s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 23, - "h": 20 - }, - "frame": { - "x": 104, - "y": 555, - "w": 23, - "h": 20 - } - }, - { - "filename": "513", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 20, - "h": 20 - }, - "frame": { - "x": 101, - "y": 575, - "w": 20, - "h": 20 - } - }, - { - "filename": "522", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 17, - "h": 22 - }, - "frame": { - "x": 104, - "y": 595, - "w": 17, - "h": 22 - } - }, - { - "filename": "522s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 17, - "h": 22 - }, - "frame": { - "x": 104, - "y": 617, - "w": 17, - "h": 22 - } - }, - { - "filename": "572", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 22, - "h": 19 - }, - "frame": { - "x": 104, - "y": 639, - "w": 22, - "h": 19 - } - }, { "filename": "591s", "rotated": false, @@ -4896,14 +4854,14 @@ "h": 22 }, "frame": { - "x": 105, - "y": 658, + "x": 103, + "y": 545, "w": 20, "h": 22 } }, { - "filename": "495s", + "filename": "585-autumn", "rotated": false, "trimmed": true, "sourceSize": { @@ -4912,99 +4870,15 @@ }, "spriteSourceSize": { "x": 10, - "y": 11, - "w": 20, - "h": 17 + "y": 6, + "w": 18, + "h": 22 }, "frame": { - "x": 128, - "y": 520, - "w": 20, - "h": 17 - } - }, - { - "filename": "511s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 20, - "h": 21 - }, - "frame": { - "x": 127, - "y": 537, - "w": 20, - "h": 21 - } - }, - { - "filename": "504s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 20, - "h": 18 - }, - "frame": { - "x": 127, - "y": 558, - "w": 20, - "h": 18 - } - }, - { - "filename": "560", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 20, - "h": 21 - }, - "frame": { - "x": 121, - "y": 576, - "w": 20, - "h": 21 - } - }, - { - "filename": "560s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 20, - "h": 21 - }, - "frame": { - "x": 121, - "y": 597, - "w": 20, - "h": 21 + "x": 119, + "y": 392, + "w": 18, + "h": 22 } }, { @@ -5022,14 +4896,14 @@ "h": 21 }, "frame": { - "x": 121, - "y": 618, + "x": 124, + "y": 371, "w": 18, "h": 21 } }, { - "filename": "513s", + "filename": "617", "rotated": false, "trimmed": true, "sourceSize": { @@ -5037,18 +4911,81 @@ "h": 30 }, "spriteSourceSize": { - "x": 11, + "x": 9, "y": 8, - "w": 20, + "w": 23, "h": 20 }, "frame": { - "x": 126, - "y": 639, - "w": 20, + "x": 142, + "y": 370, + "w": 23, "h": 20 } }, + { + "filename": "585-spring", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 123, + "y": 414, + "w": 18, + "h": 22 + } + }, + { + "filename": "585-summer", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 123, + "y": 436, + "w": 18, + "h": 22 + } + }, + { + "filename": "585-winter", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 123, + "y": 458, + "w": 18, + "h": 22 + } + }, { "filename": "585s-autumn", "rotated": false, @@ -5064,8 +5001,8 @@ "h": 22 }, "frame": { - "x": 125, - "y": 659, + "x": 123, + "y": 480, "w": 18, "h": 22 } @@ -5085,12 +5022,432 @@ "h": 22 }, "frame": { - "x": 143, - "y": 659, + "x": 123, + "y": 502, "w": 18, "h": 22 } }, + { + "filename": "585s-summer", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 123, + "y": 524, + "w": 18, + "h": 22 + } + }, + { + "filename": "521s-f", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 7, + "w": 18, + "h": 21 + }, + "frame": { + "x": 123, + "y": 546, + "w": 18, + "h": 21 + } + }, + { + "filename": "564s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 13, + "w": 23, + "h": 15 + }, + "frame": { + "x": 103, + "y": 567, + "w": 23, + "h": 15 + } + }, + { + "filename": "562", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 22, + "h": 16 + }, + "frame": { + "x": 102, + "y": 582, + "w": 22, + "h": 16 + } + }, + { + "filename": "575s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 22, + "h": 20 + }, + "frame": { + "x": 103, + "y": 598, + "w": 22, + "h": 20 + } + }, + { + "filename": "585s-winter", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 6, + "w": 18, + "h": 22 + }, + "frame": { + "x": 137, + "y": 392, + "w": 18, + "h": 22 + } + }, + { + "filename": "606", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 15, + "h": 22 + }, + "frame": { + "x": 141, + "y": 414, + "w": 15, + "h": 22 + } + }, + { + "filename": "606s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 15, + "h": 22 + }, + "frame": { + "x": 141, + "y": 436, + "w": 15, + "h": 22 + } + }, + { + "filename": "630", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 16, + "h": 22 + }, + "frame": { + "x": 141, + "y": 458, + "w": 16, + "h": 22 + } + }, + { + "filename": "630s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 16, + "h": 22 + }, + "frame": { + "x": 141, + "y": 480, + "w": 16, + "h": 22 + } + }, + { + "filename": "549", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 7, + "w": 17, + "h": 21 + }, + "frame": { + "x": 141, + "y": 502, + "w": 17, + "h": 21 + } + }, + { + "filename": "549s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 7, + "w": 17, + "h": 21 + }, + "frame": { + "x": 141, + "y": 523, + "w": 17, + "h": 21 + } + }, + { + "filename": "560", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 20, + "h": 21 + }, + "frame": { + "x": 141, + "y": 544, + "w": 20, + "h": 21 + } + }, + { + "filename": "495", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 11, + "w": 20, + "h": 17 + }, + "frame": { + "x": 126, + "y": 567, + "w": 20, + "h": 17 + } + }, + { + "filename": "546", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 14, + "w": 21, + "h": 14 + }, + "frame": { + "x": 124, + "y": 584, + "w": 21, + "h": 14 + } + }, + { + "filename": "560s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 20, + "h": 21 + }, + "frame": { + "x": 125, + "y": 598, + "w": 20, + "h": 21 + } + }, + { + "filename": "546s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 14, + "w": 21, + "h": 14 + }, + "frame": { + "x": 122, + "y": 619, + "w": 21, + "h": 14 + } + }, + { + "filename": "572", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 9, + "w": 22, + "h": 19 + }, + "frame": { + "x": 146, + "y": 565, + "w": 22, + "h": 19 + } + }, + { + "filename": "617s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 23, + "h": 20 + }, + "frame": { + "x": 145, + "y": 584, + "w": 23, + "h": 20 + } + }, + { + "filename": "562s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 22, + "h": 16 + }, + "frame": { + "x": 145, + "y": 604, + "w": 22, + "h": 16 + } + }, { "filename": "572s", "rotated": false, @@ -5106,8 +5463,8 @@ "h": 19 }, "frame": { - "x": 146, - "y": 331, + "x": 143, + "y": 620, "w": 22, "h": 19 } @@ -5127,8 +5484,8 @@ "h": 19 }, "frame": { - "x": 146, - "y": 350, + "x": 133, + "y": 639, "w": 22, "h": 19 } @@ -5148,14 +5505,14 @@ "h": 19 }, "frame": { - "x": 168, - "y": 331, + "x": 133, + "y": 658, "w": 22, "h": 19 } }, { - "filename": "585s-summer", + "filename": "615", "rotated": false, "trimmed": true, "sourceSize": { @@ -5164,19 +5521,61 @@ }, "spriteSourceSize": { "x": 10, - "y": 6, - "w": 18, - "h": 22 + "y": 8, + "w": 19, + "h": 20 }, "frame": { - "x": 146, - "y": 369, - "w": 18, - "h": 22 + "x": 135, + "y": 677, + "w": 19, + "h": 20 } }, { - "filename": "585s-winter", + "filename": "599", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 11, + "w": 22, + "h": 16 + }, + "frame": { + "x": 142, + "y": 697, + "w": 22, + "h": 16 + } + }, + { + "filename": "542", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 14, + "h": 21 + }, + "frame": { + "x": 155, + "y": 639, + "w": 14, + "h": 21 + } + }, + { + "filename": "495s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5185,15 +5584,141 @@ }, "spriteSourceSize": { "x": 10, - "y": 6, - "w": 18, - "h": 22 + "y": 11, + "w": 20, + "h": 17 }, "frame": { - "x": 146, - "y": 391, + "x": 155, + "y": 660, + "w": 20, + "h": 17 + } + }, + { + "filename": "615s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 154, + "y": 677, + "w": 19, + "h": 20 + } + }, + { + "filename": "599s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 11, + "w": 22, + "h": 16 + }, + "frame": { + "x": 164, + "y": 697, + "w": 22, + "h": 16 + } + }, + { + "filename": "529", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 11, + "w": 21, + "h": 17 + }, + "frame": { + "x": 186, + "y": 353, + "w": 21, + "h": 17 + } + }, + { + "filename": "605s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 9, + "w": 13, + "h": 19 + }, + "frame": { + "x": 173, + "y": 353, + "w": 13, + "h": 19 + } + }, + { + "filename": "610", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 8, "w": 18, - "h": 22 + "h": 20 + }, + "frame": { + "x": 173, + "y": 677, + "w": 18, + "h": 20 + } + }, + { + "filename": "595", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 21, + "h": 16 + }, + "frame": { + "x": 186, + "y": 697, + "w": 21, + "h": 16 } }, { @@ -5211,8 +5736,8 @@ "h": 19 }, "frame": { - "x": 190, - "y": 331, + "x": 165, + "y": 372, "w": 21, "h": 19 } @@ -5232,621 +5757,12 @@ "h": 19 }, "frame": { - "x": 168, - "y": 350, + "x": 186, + "y": 370, "w": 21, "h": 19 } }, - { - "filename": "520", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 164, - "y": 369, - "w": 19, - "h": 20 - } - }, - { - "filename": "520s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 164, - "y": 389, - "w": 19, - "h": 20 - } - }, - { - "filename": "568", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 21, - "h": 18 - }, - "frame": { - "x": 189, - "y": 350, - "w": 21, - "h": 18 - } - }, - { - "filename": "548", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 12, - "h": 18 - }, - "frame": { - "x": 211, - "y": 331, - "w": 12, - "h": 18 - } - }, - { - "filename": "517s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 14, - "w": 15, - "h": 14 - }, - "frame": { - "x": 223, - "y": 335, - "w": 15, - "h": 14 - } - }, - { - "filename": "521s-f", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 18, - "h": 21 - }, - "frame": { - "x": 238, - "y": 347, - "w": 18, - "h": 21 - } - }, - { - "filename": "549", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 17, - "h": 21 - }, - "frame": { - "x": 147, - "y": 413, - "w": 17, - "h": 21 - } - }, - { - "filename": "592", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 164, - "y": 409, - "w": 19, - "h": 20 - } - }, - { - "filename": "549s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 17, - "h": 21 - }, - "frame": { - "x": 147, - "y": 434, - "w": 17, - "h": 21 - } - }, - { - "filename": "592-f", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 164, - "y": 429, - "w": 19, - "h": 20 - } - }, - { - "filename": "627", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 7, - "w": 17, - "h": 21 - }, - "frame": { - "x": 147, - "y": 455, - "w": 17, - "h": 21 - } - }, - { - "filename": "592s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 164, - "y": 449, - "w": 19, - "h": 20 - } - }, - { - "filename": "606s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 15, - "h": 22 - }, - "frame": { - "x": 148, - "y": 476, - "w": 15, - "h": 22 - } - }, - { - "filename": "583", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 7, - "w": 15, - "h": 21 - }, - "frame": { - "x": 148, - "y": 498, - "w": 15, - "h": 21 - } - }, - { - "filename": "498s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 18, - "h": 18 - }, - "frame": { - "x": 148, - "y": 519, - "w": 18, - "h": 18 - } - }, - { - "filename": "592s-f", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 147, - "y": 537, - "w": 19, - "h": 20 - } - }, - { - "filename": "615", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 147, - "y": 557, - "w": 19, - "h": 20 - } - }, - { - "filename": "568s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 21, - "h": 18 - }, - "frame": { - "x": 141, - "y": 577, - "w": 21, - "h": 18 - } - }, - { - "filename": "615s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 141, - "y": 595, - "w": 19, - "h": 20 - } - }, - { - "filename": "583s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 7, - "w": 15, - "h": 21 - }, - "frame": { - "x": 139, - "y": 618, - "w": 15, - "h": 21 - } - }, - { - "filename": "610", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 18, - "h": 20 - }, - "frame": { - "x": 146, - "y": 639, - "w": 18, - "h": 20 - } - }, - { - "filename": "594", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 13, - "h": 22 - }, - "frame": { - "x": 161, - "y": 659, - "w": 13, - "h": 22 - } - }, - { - "filename": "594s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 6, - "w": 13, - "h": 22 - }, - "frame": { - "x": 183, - "y": 369, - "w": 13, - "h": 22 - } - }, - { - "filename": "627s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 7, - "w": 17, - "h": 21 - }, - "frame": { - "x": 183, - "y": 391, - "w": 17, - "h": 21 - } - }, - { - "filename": "610s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 8, - "w": 18, - "h": 20 - }, - "frame": { - "x": 183, - "y": 412, - "w": 18, - "h": 20 - } - }, - { - "filename": "619", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 18, - "h": 19 - }, - "frame": { - "x": 183, - "y": 432, - "w": 18, - "h": 19 - } - }, - { - "filename": "506", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 18, - "h": 18 - }, - "frame": { - "x": 183, - "y": 451, - "w": 18, - "h": 18 - } - }, - { - "filename": "633", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 16, - "h": 20 - }, - "frame": { - "x": 196, - "y": 368, - "w": 16, - "h": 20 - } - }, - { - "filename": "544s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 22, - "h": 16 - }, - "frame": { - "x": 164, - "y": 469, - "w": 22, - "h": 16 - } - }, { "filename": "636", "rotated": false, @@ -5862,14 +5778,14 @@ "h": 19 }, "frame": { - "x": 163, - "y": 485, + "x": 207, + "y": 370, "w": 20, "h": 19 } }, { - "filename": "527s", + "filename": "610s", "rotated": false, "trimmed": true, "sourceSize": { @@ -5877,37 +5793,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, - "y": 13, - "w": 20, - "h": 15 + "x": 11, + "y": 8, + "w": 18, + "h": 20 }, "frame": { - "x": 163, - "y": 504, - "w": 20, - "h": 15 - } - }, - { - "filename": "619s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, + "x": 227, + "y": 370, "w": 18, - "h": 19 - }, - "frame": { - "x": 166, - "y": 519, - "w": 18, - "h": 19 + "h": 20 } }, { @@ -5925,12 +5820,180 @@ "h": 19 }, "frame": { - "x": 166, - "y": 538, + "x": 155, + "y": 391, "w": 20, "h": 19 } }, + { + "filename": "627", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 7, + "w": 17, + "h": 21 + }, + "frame": { + "x": 156, + "y": 410, + "w": 17, + "h": 21 + } + }, + { + "filename": "627s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 7, + "w": 17, + "h": 21 + }, + "frame": { + "x": 156, + "y": 431, + "w": 17, + "h": 21 + } + }, + { + "filename": "542s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 14, + "h": 21 + }, + "frame": { + "x": 175, + "y": 391, + "w": 14, + "h": 21 + } + }, + { + "filename": "504s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 10, + "w": 20, + "h": 18 + }, + "frame": { + "x": 189, + "y": 389, + "w": 20, + "h": 18 + } + }, + { + "filename": "506", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 10, + "w": 18, + "h": 18 + }, + "frame": { + "x": 209, + "y": 389, + "w": 18, + "h": 18 + } + }, + { + "filename": "619", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 18, + "h": 19 + }, + "frame": { + "x": 227, + "y": 390, + "w": 18, + "h": 19 + } + }, + { + "filename": "583", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 7, + "w": 15, + "h": 21 + }, + "frame": { + "x": 173, + "y": 412, + "w": 15, + "h": 21 + } + }, + { + "filename": "578", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 16, + "h": 19 + }, + "frame": { + "x": 173, + "y": 433, + "w": 16, + "h": 19 + } + }, { "filename": "529s", "rotated": false, @@ -5946,75 +6009,12 @@ "h": 17 }, "frame": { - "x": 166, - "y": 557, + "x": 157, + "y": 452, "w": 21, "h": 17 } }, - { - "filename": "501", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 16, - "h": 18 - }, - "frame": { - "x": 186, - "y": 469, - "w": 16, - "h": 18 - } - }, - { - "filename": "608", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 19, - "h": 18 - }, - "frame": { - "x": 183, - "y": 487, - "w": 19, - "h": 18 - } - }, - { - "filename": "546", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 14, - "w": 21, - "h": 14 - }, - "frame": { - "x": 183, - "y": 505, - "w": 21, - "h": 14 - } - }, { "filename": "555-zen", "rotated": false, @@ -6030,323 +6030,8 @@ "h": 17 }, "frame": { - "x": 184, - "y": 519, - "w": 20, - "h": 17 - } - }, - { - "filename": "506s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 18, - "h": 18 - }, - "frame": { - "x": 186, - "y": 536, - "w": 18, - "h": 18 - } - }, - { - "filename": "633s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 16, - "h": 20 - }, - "frame": { - "x": 187, - "y": 554, - "w": 16, - "h": 20 - } - }, - { - "filename": "578", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 16, - "h": 19 - }, - "frame": { - "x": 200, - "y": 388, - "w": 16, - "h": 19 - } - }, - { - "filename": "551", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 13, - "w": 22, - "h": 16 - }, - "frame": { - "x": 216, - "y": 349, - "w": 22, - "h": 16 - } - }, - { - "filename": "551s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 13, - "w": 22, - "h": 16 - }, - "frame": { - "x": 212, - "y": 365, - "w": 22, - "h": 16 - } - }, - { - "filename": "562", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 22, - "h": 16 - }, - "frame": { - "x": 234, - "y": 368, - "w": 22, - "h": 16 - } - }, - { - "filename": "536", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 18, - "h": 18 - }, - "frame": { - "x": 216, - "y": 381, - "w": 18, - "h": 18 - } - }, - { - "filename": "562s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 22, - "h": 16 - }, - "frame": { - "x": 234, - "y": 384, - "w": 22, - "h": 16 - } - }, - { - "filename": "578s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 16, - "h": 19 - }, - "frame": { - "x": 201, - "y": 407, - "w": 16, - "h": 19 - } - }, - { - "filename": "580", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 16, - "h": 19 - }, - "frame": { - "x": 201, - "y": 426, - "w": 16, - "h": 19 - } - }, - { - "filename": "580s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 16, - "h": 19 - }, - "frame": { - "x": 201, - "y": 445, - "w": 16, - "h": 19 - } - }, - { - "filename": "501s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 16, - "h": 18 - }, - "frame": { - "x": 202, - "y": 464, - "w": 16, - "h": 18 - } - }, - { - "filename": "536s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 18, - "h": 18 - }, - "frame": { - "x": 202, - "y": 482, - "w": 18, - "h": 18 - } - }, - { - "filename": "608s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 19, - "h": 18 - }, - "frame": { - "x": 204, - "y": 500, - "w": 19, - "h": 18 - } - }, - { - "filename": "555s-zen", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 20, - "h": 17 - }, - "frame": { - "x": 204, - "y": 518, + "x": 157, + "y": 469, "w": 20, "h": 17 } @@ -6366,12 +6051,222 @@ "h": 16 }, "frame": { - "x": 204, - "y": 535, + "x": 157, + "y": 486, "w": 20, "h": 16 } }, + { + "filename": "608s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 10, + "w": 19, + "h": 18 + }, + "frame": { + "x": 158, + "y": 502, + "w": 19, + "h": 18 + } + }, + { + "filename": "619s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 18, + "h": 19 + }, + "frame": { + "x": 158, + "y": 520, + "w": 18, + "h": 19 + } + }, + { + "filename": "583s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 7, + "w": 15, + "h": 21 + }, + "frame": { + "x": 161, + "y": 539, + "w": 15, + "h": 21 + } + }, + { + "filename": "501", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 10, + "w": 16, + "h": 18 + }, + "frame": { + "x": 178, + "y": 452, + "w": 16, + "h": 18 + } + }, + { + "filename": "633", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 16, + "h": 20 + }, + "frame": { + "x": 177, + "y": 470, + "w": 16, + "h": 20 + } + }, + { + "filename": "633s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 16, + "h": 20 + }, + "frame": { + "x": 177, + "y": 490, + "w": 16, + "h": 20 + } + }, + { + "filename": "501s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 10, + "w": 16, + "h": 18 + }, + "frame": { + "x": 177, + "y": 510, + "w": 16, + "h": 18 + } + }, + { + "filename": "506s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 10, + "w": 18, + "h": 18 + }, + "frame": { + "x": 176, + "y": 528, + "w": 18, + "h": 18 + } + }, + { + "filename": "527s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 13, + "w": 20, + "h": 15 + }, + "frame": { + "x": 176, + "y": 546, + "w": 20, + "h": 15 + } + }, + { + "filename": "566", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 13, + "w": 21, + "h": 15 + }, + "frame": { + "x": 189, + "y": 407, + "w": 21, + "h": 15 + } + }, { "filename": "554", "rotated": false, @@ -6387,35 +6282,14 @@ "h": 15 }, "frame": { - "x": 217, - "y": 399, + "x": 210, + "y": 407, "w": 17, "h": 15 } }, { - "filename": "599", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 22, - "h": 16 - }, - "frame": { - "x": 234, - "y": 400, - "w": 22, - "h": 16 - } - }, - { - "filename": "554s", + "filename": "536", "rotated": false, "trimmed": true, "sourceSize": { @@ -6424,19 +6298,19 @@ }, "spriteSourceSize": { "x": 11, - "y": 13, - "w": 17, - "h": 15 + "y": 10, + "w": 18, + "h": 18 }, "frame": { - "x": 217, - "y": 414, - "w": 17, - "h": 15 + "x": 227, + "y": 409, + "w": 18, + "h": 18 } }, { - "filename": "599s", + "filename": "555s-zen", "rotated": false, "trimmed": true, "sourceSize": { @@ -6444,20 +6318,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 9, + "x": 10, "y": 11, - "w": 22, - "h": 16 + "w": 20, + "h": 17 }, "frame": { - "x": 234, - "y": 416, - "w": 22, - "h": 16 + "x": 189, + "y": 422, + "w": 20, + "h": 17 } }, { - "filename": "570", + "filename": "536s", "rotated": false, "trimmed": true, "sourceSize": { @@ -6465,16 +6339,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 12, - "y": 11, - "w": 16, - "h": 17 + "x": 11, + "y": 10, + "w": 18, + "h": 18 }, "frame": { - "x": 217, - "y": 429, - "w": 16, - "h": 17 + "x": 209, + "y": 422, + "w": 18, + "h": 18 } }, { @@ -6492,14 +6366,14 @@ "h": 18 }, "frame": { - "x": 217, - "y": 446, + "x": 227, + "y": 427, "w": 18, "h": 18 } }, { - "filename": "595", + "filename": "535", "rotated": false, "trimmed": true, "sourceSize": { @@ -6507,20 +6381,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 21, - "h": 16 + "x": 13, + "y": 15, + "w": 14, + "h": 13 }, "frame": { - "x": 235, - "y": 432, - "w": 21, - "h": 16 + "x": 189, + "y": 439, + "w": 14, + "h": 13 } }, { - "filename": "595s", + "filename": "548", "rotated": false, "trimmed": true, "sourceSize": { @@ -6528,15 +6402,78 @@ "h": 30 }, "spriteSourceSize": { - "x": 9, + "x": 14, + "y": 10, + "w": 12, + "h": 18 + }, + "frame": { + "x": 194, + "y": 452, + "w": 12, + "h": 18 + } + }, + { + "filename": "648-aria", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 14, + "h": 21 + }, + "frame": { + "x": 193, + "y": 470, + "w": 14, + "h": 21 + } + }, + { + "filename": "648s-aria", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 14, + "h": 21 + }, + "frame": { + "x": 193, + "y": 491, + "w": 14, + "h": 21 + } + }, + { + "filename": "519", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, "y": 12, - "w": 21, + "w": 16, "h": 16 }, "frame": { - "x": 235, - "y": 448, - "w": 21, + "x": 193, + "y": 512, + "w": 16, "h": 16 } }, @@ -6555,14 +6492,14 @@ "h": 18 }, "frame": { - "x": 218, - "y": 464, + "x": 194, + "y": 528, "w": 18, "h": 18 } }, { - "filename": "541s", + "filename": "519s", "rotated": false, "trimmed": true, "sourceSize": { @@ -6570,15 +6507,57 @@ "h": 30 }, "spriteSourceSize": { - "x": 10, + "x": 12, "y": 12, - "w": 20, + "w": 16, "h": 16 }, "frame": { - "x": 236, - "y": 464, - "w": 20, + "x": 196, + "y": 546, + "w": 16, + "h": 16 + } + }, + { + "filename": "595s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 21, + "h": 16 + }, + "frame": { + "x": 206, + "y": 440, + "w": 21, + "h": 16 + } + }, + { + "filename": "550-blue-striped", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 12, + "w": 18, + "h": 16 + }, + "frame": { + "x": 227, + "y": 445, + "w": 18, "h": 16 } }, @@ -6597,96 +6576,12 @@ "h": 14 }, "frame": { - "x": 236, - "y": 480, + "x": 206, + "y": 456, "w": 20, "h": 14 } }, - { - "filename": "570s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 11, - "w": 16, - "h": 17 - }, - "frame": { - "x": 220, - "y": 482, - "w": 16, - "h": 17 - } - }, - { - "filename": "618s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 14, - "w": 20, - "h": 14 - }, - "frame": { - "x": 236, - "y": 494, - "w": 20, - "h": 14 - } - }, - { - "filename": "605", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 9, - "w": 13, - "h": 19 - }, - "frame": { - "x": 223, - "y": 499, - "w": 13, - "h": 19 - } - }, - { - "filename": "605s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 9, - "w": 13, - "h": 19 - }, - "frame": { - "x": 224, - "y": 518, - "w": 13, - "h": 19 - } - }, { "filename": "557", "rotated": false, @@ -6702,8 +6597,8 @@ "h": 17 }, "frame": { - "x": 237, - "y": 508, + "x": 226, + "y": 461, "w": 19, "h": 17 } @@ -6723,56 +6618,14 @@ "h": 17 }, "frame": { - "x": 237, - "y": 525, + "x": 207, + "y": 470, "w": 19, "h": 17 } }, { - "filename": "607", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 13, - "h": 18 - }, - "frame": { - "x": 224, - "y": 537, - "w": 13, - "h": 18 - } - }, - { - "filename": "543s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 14, - "w": 18, - "h": 14 - }, - "frame": { - "x": 237, - "y": 542, - "w": 18, - "h": 14 - } - }, - { - "filename": "546s", + "filename": "541s", "rotated": false, "trimmed": true, "sourceSize": { @@ -6781,98 +6634,14 @@ }, "spriteSourceSize": { "x": 10, - "y": 14, - "w": 21, - "h": 14 - }, - "frame": { - "x": 166, - "y": 574, - "w": 21, - "h": 14 - } - }, - { - "filename": "519", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, "y": 12, - "w": 16, + "w": 20, "h": 16 }, "frame": { - "x": 187, - "y": 574, - "w": 16, - "h": 16 - } - }, - { - "filename": "566", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 13, - "w": 21, - "h": 15 - }, - "frame": { - "x": 162, - "y": 588, - "w": 21, - "h": 15 - } - }, - { - "filename": "566s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 13, - "w": 21, - "h": 15 - }, - "frame": { - "x": 160, - "y": 603, - "w": 21, - "h": 15 - } - }, - { - "filename": "550-blue-striped", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 12, - "w": 18, - "h": 16 - }, - "frame": { - "x": 154, - "y": 618, - "w": 18, + "x": 207, + "y": 487, + "w": 20, "h": 16 } }, @@ -6891,8 +6660,8 @@ "h": 16 }, "frame": { - "x": 183, - "y": 590, + "x": 227, + "y": 478, "w": 18, "h": 16 } @@ -6912,33 +6681,12 @@ "h": 16 }, "frame": { - "x": 181, - "y": 606, + "x": 227, + "y": 494, "w": 18, "h": 16 } }, - { - "filename": "548s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 12, - "h": 18 - }, - "frame": { - "x": 164, - "y": 634, - "w": 12, - "h": 18 - } - }, { "filename": "550s-blue-striped", "rotated": false, @@ -6954,8 +6702,8 @@ "h": 16 }, "frame": { - "x": 204, - "y": 551, + "x": 209, + "y": 503, "w": 18, "h": 16 } @@ -6975,8 +6723,8 @@ "h": 16 }, "frame": { - "x": 203, - "y": 567, + "x": 227, + "y": 510, "w": 18, "h": 16 } @@ -6996,8 +6744,8 @@ "h": 17 }, "frame": { - "x": 222, - "y": 555, + "x": 212, + "y": 519, "w": 15, "h": 17 } @@ -7017,75 +6765,12 @@ "h": 16 }, "frame": { - "x": 237, - "y": 556, + "x": 227, + "y": 526, "w": 18, "h": 16 } }, - { - "filename": "616", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 13, - "w": 18, - "h": 15 - }, - "frame": { - "x": 221, - "y": 572, - "w": 18, - "h": 15 - } - }, - { - "filename": "519s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 12, - "w": 16, - "h": 16 - }, - "frame": { - "x": 239, - "y": 572, - "w": 16, - "h": 16 - } - }, - { - "filename": "616s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 13, - "w": 18, - "h": 15 - }, - "frame": { - "x": 203, - "y": 583, - "w": 18, - "h": 15 - } - }, { "filename": "540s", "rotated": false, @@ -7101,12 +6786,138 @@ "h": 17 }, "frame": { - "x": 221, - "y": 587, + "x": 212, + "y": 536, "w": 15, "h": 17 } }, + { + "filename": "616", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 13, + "w": 18, + "h": 15 + }, + "frame": { + "x": 227, + "y": 542, + "w": 18, + "h": 15 + } + }, + { + "filename": "517", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 14, + "w": 15, + "h": 14 + }, + "frame": { + "x": 212, + "y": 553, + "w": 15, + "h": 14 + } + }, + { + "filename": "616s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 13, + "w": 18, + "h": 15 + }, + "frame": { + "x": 227, + "y": 557, + "w": 18, + "h": 15 + } + }, + { + "filename": "578s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 16, + "h": 19 + }, + "frame": { + "x": 165, + "y": 620, + "w": 16, + "h": 19 + } + }, + { + "filename": "624", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 8, + "w": 14, + "h": 20 + }, + "frame": { + "x": 169, + "y": 639, + "w": 14, + "h": 20 + } + }, + { + "filename": "574", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 10, + "w": 14, + "h": 18 + }, + "frame": { + "x": 175, + "y": 659, + "w": 14, + "h": 18 + } + }, { "filename": "559", "rotated": false, @@ -7122,12 +6933,327 @@ "h": 16 }, "frame": { - "x": 236, - "y": 588, + "x": 167, + "y": 604, "w": 15, "h": 16 } }, + { + "filename": "566s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 13, + "w": 21, + "h": 15 + }, + "frame": { + "x": 168, + "y": 561, + "w": 21, + "h": 15 + } + }, + { + "filename": "580", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 16, + "h": 19 + }, + "frame": { + "x": 168, + "y": 576, + "w": 16, + "h": 19 + } + }, + { + "filename": "618s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 14, + "w": 20, + "h": 14 + }, + "frame": { + "x": 189, + "y": 562, + "w": 20, + "h": 14 + } + }, + { + "filename": "580s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 16, + "h": 19 + }, + "frame": { + "x": 184, + "y": 576, + "w": 16, + "h": 19 + } + }, + { + "filename": "543", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 14, + "w": 18, + "h": 14 + }, + "frame": { + "x": 209, + "y": 567, + "w": 18, + "h": 14 + } + }, + { + "filename": "543s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 14, + "w": 18, + "h": 14 + }, + "frame": { + "x": 227, + "y": 572, + "w": 18, + "h": 14 + } + }, + { + "filename": "624s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 8, + "w": 14, + "h": 20 + }, + "frame": { + "x": 182, + "y": 595, + "w": 14, + "h": 20 + } + }, + { + "filename": "548s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 10, + "w": 12, + "h": 18 + }, + "frame": { + "x": 196, + "y": 595, + "w": 12, + "h": 18 + } + }, + { + "filename": "517s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 14, + "w": 15, + "h": 14 + }, + "frame": { + "x": 200, + "y": 581, + "w": 15, + "h": 14 + } + }, + { + "filename": "582", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 12, + "w": 12, + "h": 16 + }, + "frame": { + "x": 215, + "y": 581, + "w": 12, + "h": 16 + } + }, + { + "filename": "554s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 13, + "w": 17, + "h": 15 + }, + "frame": { + "x": 227, + "y": 586, + "w": 17, + "h": 15 + } + }, + { + "filename": "570", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 11, + "w": 16, + "h": 17 + }, + "frame": { + "x": 208, + "y": 597, + "w": 16, + "h": 17 + } + }, + { + "filename": "570s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 11, + "w": 16, + "h": 17 + }, + "frame": { + "x": 224, + "y": 601, + "w": 16, + "h": 17 + } + }, + { + "filename": "535s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 15, + "w": 14, + "h": 13 + }, + "frame": { + "x": 182, + "y": 615, + "w": 14, + "h": 13 + } + }, + { + "filename": "582s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 12, + "w": 12, + "h": 16 + }, + "frame": { + "x": 196, + "y": 613, + "w": 12, + "h": 16 + } + }, { "filename": "559s", "rotated": false, @@ -7143,8 +7269,8 @@ "h": 16 }, "frame": { - "x": 201, - "y": 598, + "x": 208, + "y": 614, "w": 15, "h": 16 } @@ -7164,73 +7290,31 @@ "h": 14 }, "frame": { - "x": 199, - "y": 614, - "w": 15, - "h": 14 - } - }, - { - "filename": "577s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 14, - "w": 15, - "h": 14 - }, - "frame": { - "x": 216, - "y": 604, - "w": 15, - "h": 14 - } - }, - { - "filename": "597", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 12, - "w": 15, - "h": 16 - }, - "frame": { - "x": 231, - "y": 604, - "w": 15, - "h": 16 - } - }, - { - "filename": "597s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 12, - "w": 15, - "h": 16 - }, - "frame": { - "x": 214, + "x": 223, "y": 618, "w": 15, - "h": 16 + "h": 14 + } + }, + { + "filename": "602", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 17, + "w": 14, + "h": 11 + }, + "frame": { + "x": 181, + "y": 628, + "w": 14, + "h": 11 } }, { @@ -7248,12 +7332,33 @@ "h": 18 }, "frame": { - "x": 229, - "y": 620, + "x": 183, + "y": 639, "w": 14, "h": 18 } }, + { + "filename": "607", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 10, + "w": 13, + "h": 18 + }, + "frame": { + "x": 189, + "y": 657, + "w": 13, + "h": 18 + } + }, { "filename": "607s", "rotated": false, @@ -7269,12 +7374,96 @@ "h": 18 }, "frame": { - "x": 243, - "y": 620, + "x": 191, + "y": 675, "w": 13, "h": 18 } }, + { + "filename": "524", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 15, + "y": 11, + "w": 11, + "h": 17 + }, + "frame": { + "x": 197, + "y": 629, + "w": 11, + "h": 17 + } + }, + { + "filename": "597", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 12, + "w": 15, + "h": 16 + }, + "frame": { + "x": 208, + "y": 630, + "w": 15, + "h": 16 + } + }, + { + "filename": "602s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 17, + "w": 14, + "h": 11 + }, + "frame": { + "x": 197, + "y": 646, + "w": 14, + "h": 11 + } + }, + { + "filename": "577s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 14, + "w": 15, + "h": 14 + }, + "frame": { + "x": 223, + "y": 632, + "w": 15, + "h": 14 + } + }, { "filename": "613", "rotated": false, @@ -7290,8 +7479,8 @@ "h": 18 }, "frame": { - "x": 176, - "y": 634, + "x": 202, + "y": 657, "w": 14, "h": 18 } @@ -7311,180 +7500,12 @@ "h": 18 }, "frame": { - "x": 174, - "y": 652, + "x": 204, + "y": 675, "w": 14, "h": 18 } }, - { - "filename": "602", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 17, - "w": 14, - "h": 11 - }, - "frame": { - "x": 174, - "y": 670, - "w": 14, - "h": 11 - } - }, - { - "filename": "524", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 15, - "y": 11, - "w": 11, - "h": 17 - }, - "frame": { - "x": 188, - "y": 652, - "w": 11, - "h": 17 - } - }, - { - "filename": "602s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 17, - "w": 14, - "h": 11 - }, - "frame": { - "x": 188, - "y": 669, - "w": 14, - "h": 11 - } - }, - { - "filename": "582", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 12, - "w": 12, - "h": 16 - }, - "frame": { - "x": 202, - "y": 628, - "w": 12, - "h": 16 - } - }, - { - "filename": "588", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 11, - "w": 12, - "h": 17 - }, - "frame": { - "x": 190, - "y": 628, - "w": 12, - "h": 17 - } - }, - { - "filename": "535", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 15, - "w": 14, - "h": 13 - }, - "frame": { - "x": 214, - "y": 634, - "w": 14, - "h": 13 - } - }, - { - "filename": "535s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 15, - "w": 14, - "h": 13 - }, - "frame": { - "x": 228, - "y": 638, - "w": 14, - "h": 13 - } - }, - { - "filename": "590", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 11, - "w": 14, - "h": 17 - }, - "frame": { - "x": 242, - "y": 638, - "w": 14, - "h": 17 - } - }, { "filename": "524s", "rotated": false, @@ -7500,12 +7521,75 @@ "h": 17 }, "frame": { - "x": 199, - "y": 651, + "x": 207, + "y": 693, "w": 11, "h": 17 } }, + { + "filename": "590", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 11, + "w": 14, + "h": 17 + }, + "frame": { + "x": 216, + "y": 646, + "w": 14, + "h": 17 + } + }, + { + "filename": "597s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 12, + "w": 15, + "h": 16 + }, + "frame": { + "x": 230, + "y": 646, + "w": 15, + "h": 16 + } + }, + { + "filename": "588s", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 11, + "w": 12, + "h": 17 + }, + "frame": { + "x": 218, + "y": 663, + "w": 12, + "h": 17 + } + }, { "filename": "590s", "rotated": false, @@ -7521,53 +7605,11 @@ "h": 17 }, "frame": { - "x": 210, - "y": 647, + "x": 230, + "y": 662, "w": 14, "h": 17 } - }, - { - "filename": "588s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 11, - "w": 12, - "h": 17 - }, - "frame": { - "x": 210, - "y": 664, - "w": 12, - "h": 17 - } - }, - { - "filename": "582s", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 12, - "w": 12, - "h": 16 - }, - "frame": { - "x": 224, - "y": 651, - "w": 12, - "h": 16 - } } ] } @@ -7575,6 +7617,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:4b1ede56fa38672ee5e2e5de6f39ff48:58f3f9bd48fa9481c3cd7a0cdebb3e00:20fe181c46701b46ac8f250d40b1bbc1$" + "smartupdate": "$TexturePacker:SmartUpdate:8a278d997d5726b88e2aaa301eb4e4e8:c33243967aadc5b2250e95b079396b1d:20fe181c46701b46ac8f250d40b1bbc1$" } } diff --git a/public/images/pokemon_icons_5.png b/public/images/pokemon_icons_5.png index e0a4ebef303..264120c7499 100644 Binary files a/public/images/pokemon_icons_5.png and b/public/images/pokemon_icons_5.png differ diff --git a/public/images/pokemon_icons_5v.json b/public/images/pokemon_icons_5v.json index 7f5356e7e2a..111cc3ab6ab 100644 --- a/public/images/pokemon_icons_5v.json +++ b/public/images/pokemon_icons_5v.json @@ -4,8 +4,8 @@ "image": "pokemon_icons_5v.png", "format": "RGBA8888", "size": { - "w": 127, - "h": 668 + "w": 123, + "h": 696 }, "scale": 1, "frames": [ @@ -135,6 +135,27 @@ "h": 26 } }, + { + "filename": "635_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 3, + "w": 29, + "h": 25 + }, + "frame": { + "x": 94, + "y": 0, + "w": 29, + "h": 25 + } + }, { "filename": "534_2", "rotated": false, @@ -171,8 +192,8 @@ "h": 25 }, "frame": { - "x": 94, - "y": 0, + "x": 0, + "y": 109, "w": 31, "h": 25 } @@ -214,7 +235,7 @@ }, "frame": { "x": 0, - "y": 109, + "y": 134, "w": 30, "h": 25 } @@ -235,11 +256,32 @@ }, "frame": { "x": 0, - "y": 134, + "y": 159, "w": 30, "h": 25 } }, + { + "filename": "635_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 3, + "w": 29, + "h": 25 + }, + "frame": { + "x": 94, + "y": 25, + "w": 29, + "h": 25 + } + }, { "filename": "645-therian_1", "rotated": false, @@ -256,137 +298,11 @@ }, "frame": { "x": 0, - "y": 159, + "y": 184, "w": 27, "h": 28 } }, - { - "filename": "635_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 29, - "h": 25 - }, - "frame": { - "x": 0, - "y": 187, - "w": 29, - "h": 25 - } - }, - { - "filename": "635_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 29, - "h": 25 - }, - "frame": { - "x": 0, - "y": 212, - "w": 29, - "h": 25 - } - }, - { - "filename": "609_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 29, - "h": 23 - }, - "frame": { - "x": 0, - "y": 237, - "w": 29, - "h": 23 - } - }, - { - "filename": "609_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 29, - "h": 23 - }, - "frame": { - "x": 0, - "y": 260, - "w": 29, - "h": 23 - } - }, - { - "filename": "530_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 29, - "h": 22 - }, - "frame": { - "x": 0, - "y": 283, - "w": 29, - "h": 22 - } - }, - { - "filename": "530_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 29, - "h": 22 - }, - "frame": { - "x": 0, - "y": 305, - "w": 29, - "h": 22 - } - }, { "filename": "533_2", "rotated": false, @@ -403,7 +319,7 @@ }, "frame": { "x": 0, - "y": 327, + "y": 212, "w": 27, "h": 24 } @@ -424,7 +340,7 @@ }, "frame": { "x": 0, - "y": 351, + "y": 236, "w": 27, "h": 24 } @@ -445,7 +361,7 @@ }, "frame": { "x": 0, - "y": 375, + "y": 260, "w": 26, "h": 25 } @@ -466,7 +382,7 @@ }, "frame": { "x": 0, - "y": 400, + "y": 285, "w": 26, "h": 25 } @@ -487,7 +403,7 @@ }, "frame": { "x": 0, - "y": 425, + "y": 310, "w": 25, "h": 25 } @@ -508,7 +424,7 @@ }, "frame": { "x": 0, - "y": 450, + "y": 335, "w": 26, "h": 24 } @@ -529,7 +445,7 @@ }, "frame": { "x": 0, - "y": 474, + "y": 359, "w": 26, "h": 24 } @@ -550,7 +466,7 @@ }, "frame": { "x": 0, - "y": 498, + "y": 383, "w": 28, "h": 23 } @@ -571,13 +487,55 @@ }, "frame": { "x": 0, - "y": 521, + "y": 406, "w": 28, "h": 23 } }, { - "filename": "497_2", + "filename": "609_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 29, + "h": 23 + }, + "frame": { + "x": 0, + "y": 429, + "w": 29, + "h": 23 + } + }, + { + "filename": "609_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 29, + "h": 23 + }, + "frame": { + "x": 0, + "y": 452, + "w": 29, + "h": 23 + } + }, + { + "filename": "530_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -587,18 +545,18 @@ "spriteSourceSize": { "x": 6, "y": 6, - "w": 28, + "w": 29, "h": 22 }, "frame": { "x": 0, - "y": 544, - "w": 28, + "y": 475, + "w": 29, "h": 22 } }, { - "filename": "497_3", + "filename": "530_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -608,13 +566,13 @@ "spriteSourceSize": { "x": 6, "y": 6, - "w": 28, + "w": 29, "h": 22 }, "frame": { "x": 0, - "y": 566, - "w": 28, + "y": 497, + "w": 29, "h": 22 } }, @@ -634,7 +592,7 @@ }, "frame": { "x": 0, - "y": 588, + "y": 519, "w": 29, "h": 22 } @@ -655,7 +613,7 @@ }, "frame": { "x": 0, - "y": 610, + "y": 541, "w": 29, "h": 22 } @@ -676,53 +634,11 @@ }, "frame": { "x": 0, - "y": 632, + "y": 563, "w": 30, "h": 22 } }, - { - "filename": "546_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 14, - "w": 21, - "h": 14 - }, - "frame": { - "x": 0, - "y": 654, - "w": 21, - "h": 14 - } - }, - { - "filename": "546_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 14, - "w": 21, - "h": 14 - }, - "frame": { - "x": 21, - "y": 654, - "w": 21, - "h": 14 - } - }, { "filename": "569_3", "rotated": false, @@ -738,33 +654,12 @@ "h": 22 }, "frame": { - "x": 32, - "y": 80, + "x": 0, + "y": 585, "w": 30, "h": 22 } }, - { - "filename": "579_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 30, - "h": 21 - }, - "frame": { - "x": 31, - "y": 102, - "w": 30, - "h": 21 - } - }, { "filename": "604_2", "rotated": false, @@ -780,96 +675,12 @@ "h": 22 }, "frame": { - "x": 30, - "y": 123, + "x": 0, + "y": 607, "w": 30, "h": 22 } }, - { - "filename": "579_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 30, - "h": 21 - }, - "frame": { - "x": 30, - "y": 145, - "w": 30, - "h": 21 - } - }, - { - "filename": "579_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 30, - "h": 21 - }, - "frame": { - "x": 27, - "y": 166, - "w": 30, - "h": 21 - } - }, - { - "filename": "571_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 29, - "h": 22 - }, - "frame": { - "x": 29, - "y": 187, - "w": 29, - "h": 22 - } - }, - { - "filename": "571_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 29, - "h": 22 - }, - "frame": { - "x": 29, - "y": 209, - "w": 29, - "h": 22 - } - }, { "filename": "604_3", "rotated": false, @@ -885,8 +696,8 @@ "h": 22 }, "frame": { - "x": 29, - "y": 231, + "x": 0, + "y": 629, "w": 30, "h": 22 } @@ -906,12 +717,75 @@ "h": 22 }, "frame": { - "x": 29, - "y": 253, + "x": 0, + "y": 651, "w": 30, "h": 22 } }, + { + "filename": "648-pirouette_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 15, + "h": 23 + }, + "frame": { + "x": 0, + "y": 673, + "w": 15, + "h": 23 + } + }, + { + "filename": "648-pirouette_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 5, + "w": 15, + "h": 23 + }, + "frame": { + "x": 15, + "y": 673, + "w": 15, + "h": 23 + } + }, + { + "filename": "579_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 30, + "h": 21 + }, + "frame": { + "x": 32, + "y": 80, + "w": 30, + "h": 21 + } + }, { "filename": "647-resolute_3", "rotated": false, @@ -927,14 +801,98 @@ "h": 22 }, "frame": { - "x": 29, - "y": 275, + "x": 31, + "y": 101, "w": 30, "h": 22 } }, { - "filename": "593_2", + "filename": "579_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 30, + "h": 21 + }, + "frame": { + "x": 31, + "y": 123, + "w": 30, + "h": 21 + } + }, + { + "filename": "571_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 29, + "h": 22 + }, + "frame": { + "x": 30, + "y": 144, + "w": 29, + "h": 22 + } + }, + { + "filename": "571_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 29, + "h": 22 + }, + "frame": { + "x": 30, + "y": 166, + "w": 29, + "h": 22 + } + }, + { + "filename": "579_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 30, + "h": 21 + }, + "frame": { + "x": 27, + "y": 188, + "w": 30, + "h": 21 + } + }, + { + "filename": "497_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -948,8 +906,29 @@ "h": 22 }, "frame": { - "x": 29, - "y": 297, + "x": 27, + "y": 209, + "w": 28, + "h": 22 + } + }, + { + "filename": "497_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 28, + "h": 22 + }, + "frame": { + "x": 27, + "y": 231, "w": 28, "h": 22 } @@ -969,14 +948,14 @@ "h": 20 }, "frame": { - "x": 29, - "y": 319, + "x": 27, + "y": 253, "w": 28, "h": 20 } }, { - "filename": "593_3", + "filename": "593_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -990,8 +969,8 @@ "h": 22 }, "frame": { - "x": 27, - "y": 339, + "x": 26, + "y": 273, "w": 28, "h": 22 } @@ -1011,14 +990,14 @@ "h": 20 }, "frame": { - "x": 27, - "y": 361, + "x": 26, + "y": 295, "w": 28, "h": 20 } }, { - "filename": "596_2", + "filename": "496_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -1026,58 +1005,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 28, - "h": 22 - }, - "frame": { - "x": 26, - "y": 381, - "w": 28, - "h": 22 - } - }, - { - "filename": "596_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 28, - "h": 22 - }, - "frame": { - "x": 26, - "y": 403, - "w": 28, - "h": 22 - } - }, - { - "filename": "593-f_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 27, - "h": 22 + "x": 9, + "y": 8, + "w": 22, + "h": 20 }, "frame": { "x": 25, - "y": 425, - "w": 27, - "h": 22 + "y": 315, + "w": 22, + "h": 20 } }, { @@ -1096,13 +1033,13 @@ }, "frame": { "x": 26, - "y": 447, + "y": 335, "w": 22, "h": 26 } }, { - "filename": "586-spring_1", + "filename": "518_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -1111,15 +1048,15 @@ }, "spriteSourceSize": { "x": 9, - "y": 4, + "y": 6, "w": 23, - "h": 24 + "h": 22 }, "frame": { "x": 26, - "y": 473, + "y": 361, "w": 23, - "h": 24 + "h": 22 } }, { @@ -1138,11 +1075,32 @@ }, "frame": { "x": 28, - "y": 497, + "y": 383, "w": 22, "h": 26 } }, + { + "filename": "496_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 22, + "h": 20 + }, + "frame": { + "x": 28, + "y": 409, + "w": 22, + "h": 20 + } + }, { "filename": "640_2", "rotated": false, @@ -1158,8 +1116,8 @@ "h": 26 }, "frame": { - "x": 28, - "y": 523, + "x": 29, + "y": 429, "w": 21, "h": 26 } @@ -1179,12 +1137,33 @@ "h": 26 }, "frame": { - "x": 28, - "y": 549, + "x": 29, + "y": 455, "w": 21, "h": 26 } }, + { + "filename": "586-spring_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 4, + "w": 23, + "h": 24 + }, + "frame": { + "x": 29, + "y": 481, + "w": 23, + "h": 24 + } + }, { "filename": "586-summer_1", "rotated": false, @@ -1201,7 +1180,7 @@ }, "frame": { "x": 29, - "y": 575, + "y": 505, "w": 23, "h": 24 } @@ -1222,7 +1201,7 @@ }, "frame": { "x": 29, - "y": 599, + "y": 529, "w": 23, "h": 24 } @@ -1243,263 +1222,11 @@ }, "frame": { "x": 30, - "y": 623, + "y": 553, "w": 22, "h": 24 } }, - { - "filename": "552_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 25, - "h": 21 - }, - "frame": { - "x": 42, - "y": 647, - "w": 25, - "h": 21 - } - }, - { - "filename": "593-f_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 27, - "h": 22 - }, - "frame": { - "x": 94, - "y": 25, - "w": 27, - "h": 22 - } - }, - { - "filename": "593-f_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 27, - "h": 22 - }, - "frame": { - "x": 67, - "y": 26, - "w": 27, - "h": 22 - } - }, - { - "filename": "634_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 62, - "y": 48, - "w": 26, - "h": 22 - } - }, - { - "filename": "634_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 26, - "h": 22 - }, - "frame": { - "x": 62, - "y": 70, - "w": 26, - "h": 22 - } - }, - { - "filename": "552_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 7, - "w": 25, - "h": 21 - }, - "frame": { - "x": 62, - "y": 92, - "w": 25, - "h": 21 - } - }, - { - "filename": "611_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 25, - "h": 21 - }, - "frame": { - "x": 61, - "y": 113, - "w": 25, - "h": 21 - } - }, - { - "filename": "620_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 60, - "y": 134, - "w": 25, - "h": 22 - } - }, - { - "filename": "611_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 25, - "h": 21 - }, - "frame": { - "x": 60, - "y": 156, - "w": 25, - "h": 21 - } - }, - { - "filename": "620_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 58, - "y": 177, - "w": 25, - "h": 22 - } - }, - { - "filename": "647-ordinary_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 58, - "y": 199, - "w": 25, - "h": 22 - } - }, - { - "filename": "647-ordinary_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 6, - "w": 25, - "h": 22 - }, - "frame": { - "x": 59, - "y": 221, - "w": 25, - "h": 22 - } - }, { "filename": "649-burn_3", "rotated": false, @@ -1515,8 +1242,8 @@ "h": 24 }, "frame": { - "x": 59, - "y": 243, + "x": 30, + "y": 577, "w": 22, "h": 24 } @@ -1536,8 +1263,8 @@ "h": 24 }, "frame": { - "x": 59, - "y": 267, + "x": 30, + "y": 601, "w": 22, "h": 24 } @@ -1557,138 +1284,12 @@ "h": 24 }, "frame": { - "x": 88, - "y": 48, + "x": 30, + "y": 625, "w": 22, "h": 24 } }, - { - "filename": "549_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 17, - "h": 21 - }, - "frame": { - "x": 110, - "y": 47, - "w": 17, - "h": 21 - } - }, - { - "filename": "496_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 22, - "h": 20 - }, - "frame": { - "x": 88, - "y": 72, - "w": 22, - "h": 20 - } - }, - { - "filename": "549_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 7, - "w": 17, - "h": 21 - }, - "frame": { - "x": 110, - "y": 68, - "w": 17, - "h": 21 - } - }, - { - "filename": "518_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 87, - "y": 92, - "w": 23, - "h": 22 - } - }, - { - "filename": "518_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 23, - "h": 22 - }, - "frame": { - "x": 86, - "y": 114, - "w": 23, - "h": 22 - } - }, - { - "filename": "585-autumn_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 6, - "w": 18, - "h": 22 - }, - "frame": { - "x": 109, - "y": 114, - "w": 18, - "h": 22 - } - }, { "filename": "649-douse_2", "rotated": false, @@ -1704,56 +1305,14 @@ "h": 24 }, "frame": { - "x": 85, - "y": 136, + "x": 30, + "y": 649, "w": 22, "h": 24 } }, { - "filename": "560_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 20, - "h": 21 - }, - "frame": { - "x": 107, - "y": 136, - "w": 20, - "h": 21 - } - }, - { - "filename": "560_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 20, - "h": 21 - }, - "frame": { - "x": 107, - "y": 157, - "w": 20, - "h": 21 - } - }, - { - "filename": "496_3", + "filename": "518_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -1762,15 +1321,456 @@ }, "spriteSourceSize": { "x": 9, - "y": 8, - "w": 22, - "h": 20 + "y": 6, + "w": 23, + "h": 22 }, "frame": { - "x": 85, - "y": 160, + "x": 30, + "y": 673, + "w": 23, + "h": 22 + } + }, + { + "filename": "593_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 28, + "h": 22 + }, + "frame": { + "x": 63, + "y": 26, + "w": 28, + "h": 22 + } + }, + { + "filename": "596_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 28, + "h": 22 + }, + "frame": { + "x": 62, + "y": 48, + "w": 28, + "h": 22 + } + }, + { + "filename": "596_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 28, + "h": 22 + }, + "frame": { + "x": 62, + "y": 70, + "w": 28, + "h": 22 + } + }, + { + "filename": "593-f_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 27, + "h": 22 + }, + "frame": { + "x": 90, + "y": 50, + "w": 27, + "h": 22 + } + }, + { + "filename": "593-f_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 27, + "h": 22 + }, + "frame": { + "x": 90, + "y": 72, + "w": 27, + "h": 22 + } + }, + { + "filename": "593-f_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 27, + "h": 22 + }, + "frame": { + "x": 62, + "y": 92, + "w": 27, + "h": 22 + } + }, + { + "filename": "634_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 61, + "y": 114, + "w": 26, + "h": 22 + } + }, + { + "filename": "634_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 26, + "h": 22 + }, + "frame": { + "x": 89, + "y": 94, + "w": 26, + "h": 22 + } + }, + { + "filename": "552_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 25, + "h": 21 + }, + "frame": { + "x": 87, + "y": 116, + "w": 25, + "h": 21 + } + }, + { + "filename": "552_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 7, + "w": 25, + "h": 21 + }, + "frame": { + "x": 61, + "y": 136, + "w": 25, + "h": 21 + } + }, + { + "filename": "620_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 59, + "y": 157, + "w": 25, + "h": 22 + } + }, + { + "filename": "611_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 25, + "h": 21 + }, + "frame": { + "x": 86, + "y": 137, + "w": 25, + "h": 21 + } + }, + { + "filename": "611_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 25, + "h": 21 + }, + "frame": { + "x": 84, + "y": 158, + "w": 25, + "h": 21 + } + }, + { + "filename": "542_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 14, + "h": 21 + }, + "frame": { + "x": 109, + "y": 158, + "w": 14, + "h": 21 + } + }, + { + "filename": "548_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 10, + "w": 12, + "h": 18 + }, + "frame": { + "x": 111, + "y": 137, + "w": 12, + "h": 18 + } + }, + { + "filename": "620_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 59, + "y": 179, + "w": 25, + "h": 22 + } + }, + { + "filename": "647-ordinary_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 84, + "y": 179, + "w": 25, + "h": 22 + } + }, + { + "filename": "542_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 14, + "h": 21 + }, + "frame": { + "x": 109, + "y": 179, + "w": 14, + "h": 21 + } + }, + { + "filename": "648-aria_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 14, + "h": 21 + }, + "frame": { + "x": 109, + "y": 200, + "w": 14, + "h": 21 + } + }, + { + "filename": "647-ordinary_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 6, + "w": 25, + "h": 22 + }, + "frame": { + "x": 57, + "y": 201, + "w": 25, + "h": 22 + } + }, + { + "filename": "531_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 6, "w": 22, - "h": 20 + "h": 22 + }, + "frame": { + "x": 82, + "y": 201, + "w": 22, + "h": 22 } }, { @@ -1788,8 +1788,8 @@ "h": 24 }, "frame": { - "x": 83, - "y": 180, + "x": 55, + "y": 223, "w": 22, "h": 24 } @@ -1809,54 +1809,12 @@ "h": 24 }, "frame": { - "x": 105, - "y": 180, + "x": 55, + "y": 247, "w": 22, "h": 24 } }, - { - "filename": "632_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 12, - "w": 24, - "h": 16 - }, - "frame": { - "x": 83, - "y": 204, - "w": 24, - "h": 16 - } - }, - { - "filename": "560_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 7, - "w": 20, - "h": 21 - }, - "frame": { - "x": 107, - "y": 204, - "w": 20, - "h": 21 - } - }, { "filename": "649-shock_3", "rotated": false, @@ -1872,33 +1830,12 @@ "h": 24 }, "frame": { - "x": 84, - "y": 220, + "x": 77, + "y": 223, "w": 22, "h": 24 } }, - { - "filename": "547_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 21, - "h": 22 - }, - "frame": { - "x": 106, - "y": 225, - "w": 21, - "h": 22 - } - }, { "filename": "649_2", "rotated": false, @@ -1914,8 +1851,8 @@ "h": 24 }, "frame": { - "x": 81, - "y": 244, + "x": 77, + "y": 247, "w": 22, "h": 24 } @@ -1935,8 +1872,8 @@ "h": 19 }, "frame": { - "x": 103, - "y": 247, + "x": 99, + "y": 223, "w": 24, "h": 19 } @@ -1956,12 +1893,54 @@ "h": 19 }, "frame": { - "x": 103, - "y": 266, + "x": 99, + "y": 242, "w": 24, "h": 19 } }, + { + "filename": "632_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 12, + "w": 24, + "h": 16 + }, + "frame": { + "x": 99, + "y": 261, + "w": 24, + "h": 16 + } + }, + { + "filename": "592-f_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 47, + "y": 315, + "w": 19, + "h": 20 + } + }, { "filename": "649_3", "rotated": false, @@ -1977,75 +1956,12 @@ "h": 24 }, "frame": { - "x": 81, - "y": 268, + "x": 48, + "y": 335, "w": 22, "h": 24 } }, - { - "filename": "632_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 8, - "y": 12, - "w": 24, - "h": 16 - }, - "frame": { - "x": 103, - "y": 285, - "w": 24, - "h": 16 - } - }, - { - "filename": "648-pirouette_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 15, - "h": 23 - }, - "frame": { - "x": 110, - "y": 89, - "w": 15, - "h": 23 - } - }, - { - "filename": "531_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 6, - "w": 22, - "h": 22 - }, - "frame": { - "x": 59, - "y": 291, - "w": 22, - "h": 22 - } - }, { "filename": "531_3", "rotated": false, @@ -2061,8 +1977,8 @@ "h": 22 }, "frame": { - "x": 81, - "y": 292, + "x": 49, + "y": 359, "w": 22, "h": 22 } @@ -2082,8 +1998,8 @@ "h": 22 }, "frame": { - "x": 57, - "y": 313, + "x": 50, + "y": 381, "w": 22, "h": 22 } @@ -2103,14 +2019,14 @@ "h": 22 }, "frame": { - "x": 79, - "y": 314, + "x": 50, + "y": 403, "w": 22, "h": 22 } }, { - "filename": "544_2", + "filename": "547_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -2119,57 +2035,15 @@ }, "spriteSourceSize": { "x": 9, - "y": 12, - "w": 22, - "h": 16 + "y": 6, + "w": 21, + "h": 22 }, "frame": { - "x": 103, - "y": 301, - "w": 22, - "h": 16 - } - }, - { - "filename": "572_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 22, - "h": 19 - }, - "frame": { - "x": 101, - "y": 317, - "w": 22, - "h": 19 - } - }, - { - "filename": "544_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 22, - "h": 16 - }, - "frame": { - "x": 57, - "y": 335, - "w": 22, - "h": 16 + "x": 50, + "y": 425, + "w": 21, + "h": 22 } }, { @@ -2187,14 +2061,14 @@ "h": 22 }, "frame": { - "x": 55, - "y": 351, + "x": 50, + "y": 447, "w": 21, "h": 22 } }, { - "filename": "551_2", + "filename": "494_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -2202,20 +2076,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 13, - "w": 22, - "h": 16 + "x": 11, + "y": 6, + "w": 18, + "h": 22 }, "frame": { - "x": 79, - "y": 336, - "w": 22, - "h": 16 + "x": 52, + "y": 469, + "w": 18, + "h": 22 } }, { - "filename": "551_3", + "filename": "494_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -2223,41 +2097,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 8, - "y": 13, - "w": 22, - "h": 16 + "x": 11, + "y": 6, + "w": 18, + "h": 22 }, "frame": { - "x": 101, - "y": 336, - "w": 22, - "h": 16 + "x": 52, + "y": 491, + "w": 18, + "h": 22 } }, { - "filename": "572_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 9, - "w": 22, - "h": 19 - }, - "frame": { - "x": 76, - "y": 352, - "w": 22, - "h": 19 - } - }, - { - "filename": "603_2", + "filename": "585-autumn_1", "rotated": false, "trimmed": true, "sourceSize": { @@ -2266,78 +2119,15 @@ }, "spriteSourceSize": { "x": 10, - "y": 9, - "w": 21, - "h": 19 + "y": 6, + "w": 18, + "h": 22 }, "frame": { - "x": 98, - "y": 352, - "w": 21, - "h": 19 - } - }, - { - "filename": "529_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 21, - "h": 17 - }, - "frame": { - "x": 55, - "y": 373, - "w": 21, - "h": 17 - } - }, - { - "filename": "603_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 9, - "w": 21, - "h": 19 - }, - "frame": { - "x": 76, - "y": 371, - "w": 21, - "h": 19 - } - }, - { - "filename": "568_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 21, - "h": 18 - }, - "frame": { - "x": 97, - "y": 371, - "w": 21, - "h": 18 + "x": 52, + "y": 513, + "w": 18, + "h": 22 } }, { @@ -2355,8 +2145,8 @@ "h": 22 }, "frame": { - "x": 54, - "y": 390, + "x": 52, + "y": 535, "w": 18, "h": 22 } @@ -2376,96 +2166,12 @@ "h": 22 }, "frame": { - "x": 72, - "y": 390, + "x": 52, + "y": 557, "w": 18, "h": 22 } }, - { - "filename": "562_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 22, - "h": 16 - }, - "frame": { - "x": 54, - "y": 412, - "w": 22, - "h": 16 - } - }, - { - "filename": "568_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 10, - "w": 21, - "h": 18 - }, - "frame": { - "x": 52, - "y": 428, - "w": 21, - "h": 18 - } - }, - { - "filename": "495_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 20, - "h": 17 - }, - "frame": { - "x": 76, - "y": 412, - "w": 20, - "h": 17 - } - }, - { - "filename": "529_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 21, - "h": 17 - }, - "frame": { - "x": 73, - "y": 429, - "w": 21, - "h": 17 - } - }, { "filename": "585-winter_1", "rotated": false, @@ -2481,14 +2187,14 @@ "h": 22 }, "frame": { - "x": 90, - "y": 390, + "x": 52, + "y": 579, "w": 18, "h": 22 } }, { - "filename": "592-f_1", + "filename": "560_1", "rotated": false, "trimmed": true, "sourceSize": { @@ -2497,15 +2203,57 @@ }, "spriteSourceSize": { "x": 10, - "y": 8, - "w": 19, - "h": 20 + "y": 7, + "w": 20, + "h": 21 }, "frame": { - "x": 108, - "y": 389, - "w": 19, - "h": 20 + "x": 52, + "y": 601, + "w": 20, + "h": 21 + } + }, + { + "filename": "560_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 20, + "h": 21 + }, + "frame": { + "x": 52, + "y": 622, + "w": 20, + "h": 21 + } + }, + { + "filename": "560_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 7, + "w": 20, + "h": 21 + }, + "frame": { + "x": 52, + "y": 643, + "w": 20, + "h": 21 } }, { @@ -2523,14 +2271,14 @@ "h": 20 }, "frame": { - "x": 108, - "y": 409, + "x": 53, + "y": 664, "w": 19, "h": 20 } }, { - "filename": "548_1", + "filename": "632_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -2538,20 +2286,20 @@ "h": 30 }, "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 12, - "h": 18 + "x": 8, + "y": 12, + "w": 24, + "h": 16 }, "frame": { - "x": 96, - "y": 412, - "w": 12, - "h": 18 + "x": 55, + "y": 271, + "w": 24, + "h": 16 } }, { - "filename": "592-f_3", + "filename": "495_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -2560,19 +2308,103 @@ }, "spriteSourceSize": { "x": 10, - "y": 8, - "w": 19, - "h": 20 + "y": 11, + "w": 20, + "h": 17 }, "frame": { - "x": 108, - "y": 429, - "w": 19, - "h": 20 + "x": 79, + "y": 271, + "w": 20, + "h": 17 } }, { - "filename": "542_2", + "filename": "572_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 9, + "w": 22, + "h": 19 + }, + "frame": { + "x": 54, + "y": 287, + "w": 22, + "h": 19 + } + }, + { + "filename": "572_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 9, + "w": 22, + "h": 19 + }, + "frame": { + "x": 76, + "y": 288, + "w": 22, + "h": 19 + } + }, + { + "filename": "544_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 22, + "h": 16 + }, + "frame": { + "x": 99, + "y": 277, + "w": 22, + "h": 16 + } + }, + { + "filename": "544_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 22, + "h": 16 + }, + "frame": { + "x": 98, + "y": 293, + "w": 22, + "h": 16 + } + }, + { + "filename": "602_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -2581,141 +2413,15 @@ }, "spriteSourceSize": { "x": 13, - "y": 7, + "y": 17, "w": 14, - "h": 21 + "h": 11 }, "frame": { - "x": 94, - "y": 430, + "x": 53, + "y": 684, "w": 14, - "h": 21 - } - }, - { - "filename": "592_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 108, - "y": 449, - "w": 19, - "h": 20 - } - }, - { - "filename": "648-pirouette_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 5, - "w": 15, - "h": 23 - }, - "frame": { - "x": 48, - "y": 447, - "w": 15, - "h": 23 - } - }, - { - "filename": "592_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 19, - "h": 20 - }, - "frame": { - "x": 63, - "y": 446, - "w": 19, - "h": 20 - } - }, - { - "filename": "548_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 12, - "h": 18 - }, - "frame": { - "x": 82, - "y": 446, - "w": 12, - "h": 18 - } - }, - { - "filename": "542_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 14, - "h": 21 - }, - "frame": { - "x": 94, - "y": 451, - "w": 14, - "h": 21 - } - }, - { - "filename": "608_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 19, - "h": 18 - }, - "frame": { - "x": 108, - "y": 469, - "w": 19, - "h": 18 + "h": 11 } }, { @@ -2733,8 +2439,197 @@ "h": 22 }, "frame": { - "x": 49, - "y": 470, + "x": 71, + "y": 425, + "w": 15, + "h": 22 + } + }, + { + "filename": "606_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 15, + "h": 22 + }, + "frame": { + "x": 71, + "y": 447, + "w": 15, + "h": 22 + } + }, + { + "filename": "549_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 7, + "w": 17, + "h": 21 + }, + "frame": { + "x": 70, + "y": 469, + "w": 17, + "h": 21 + } + }, + { + "filename": "549_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 7, + "w": 17, + "h": 21 + }, + "frame": { + "x": 70, + "y": 490, + "w": 17, + "h": 21 + } + }, + { + "filename": "592-f_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 70, + "y": 511, + "w": 19, + "h": 20 + } + }, + { + "filename": "592_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 70, + "y": 531, + "w": 19, + "h": 20 + } + }, + { + "filename": "592_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 19, + "h": 20 + }, + "frame": { + "x": 70, + "y": 551, + "w": 19, + "h": 20 + } + }, + { + "filename": "603_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 9, + "w": 21, + "h": 19 + }, + "frame": { + "x": 70, + "y": 571, + "w": 21, + "h": 19 + } + }, + { + "filename": "602_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 17, + "w": 14, + "h": 11 + }, + "frame": { + "x": 70, + "y": 590, + "w": 14, + "h": 11 + } + }, + { + "filename": "606_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 6, + "w": 15, + "h": 22 + }, + "frame": { + "x": 72, + "y": 601, "w": 15, "h": 22 } @@ -2754,180 +2649,12 @@ "h": 20 }, "frame": { - "x": 64, - "y": 466, + "x": 72, + "y": 623, "w": 18, "h": 20 } }, - { - "filename": "548_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 14, - "y": 10, - "w": 12, - "h": 18 - }, - "frame": { - "x": 82, - "y": 464, - "w": 12, - "h": 18 - } - }, - { - "filename": "648-aria_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 14, - "h": 21 - }, - "frame": { - "x": 94, - "y": 472, - "w": 14, - "h": 21 - } - }, - { - "filename": "608_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 10, - "w": 19, - "h": 18 - }, - "frame": { - "x": 108, - "y": 487, - "w": 19, - "h": 18 - } - }, - { - "filename": "606_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 15, - "h": 22 - }, - "frame": { - "x": 50, - "y": 492, - "w": 15, - "h": 22 - } - }, - { - "filename": "606_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 6, - "w": 15, - "h": 22 - }, - "frame": { - "x": 65, - "y": 486, - "w": 15, - "h": 22 - } - }, - { - "filename": "648-aria_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 7, - "w": 14, - "h": 21 - }, - "frame": { - "x": 80, - "y": 486, - "w": 14, - "h": 21 - } - }, - { - "filename": "602_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 17, - "w": 14, - "h": 11 - }, - "frame": { - "x": 94, - "y": 493, - "w": 14, - "h": 11 - } - }, - { - "filename": "495_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 11, - "w": 20, - "h": 17 - }, - "frame": { - "x": 50, - "y": 514, - "w": 20, - "h": 17 - } - }, { "filename": "610_3", "rotated": false, @@ -2943,12 +2670,138 @@ "h": 20 }, "frame": { - "x": 49, - "y": 531, + "x": 72, + "y": 643, "w": 18, "h": 20 } }, + { + "filename": "603_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 9, + "w": 21, + "h": 19 + }, + "frame": { + "x": 72, + "y": 663, + "w": 21, + "h": 19 + } + }, + { + "filename": "546_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 14, + "w": 21, + "h": 14 + }, + "frame": { + "x": 72, + "y": 682, + "w": 21, + "h": 14 + } + }, + { + "filename": "568_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 10, + "w": 21, + "h": 18 + }, + "frame": { + "x": 66, + "y": 307, + "w": 21, + "h": 18 + } + }, + { + "filename": "551_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 13, + "w": 22, + "h": 16 + }, + "frame": { + "x": 87, + "y": 309, + "w": 22, + "h": 16 + } + }, + { + "filename": "648-aria_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 7, + "w": 14, + "h": 21 + }, + "frame": { + "x": 109, + "y": 309, + "w": 14, + "h": 21 + } + }, + { + "filename": "568_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 10, + "w": 21, + "h": 18 + }, + "frame": { + "x": 70, + "y": 325, + "w": 21, + "h": 18 + } + }, { "filename": "619_2", "rotated": false, @@ -2964,159 +2817,12 @@ "h": 19 }, "frame": { - "x": 49, - "y": 551, + "x": 91, + "y": 325, "w": 18, "h": 19 } }, - { - "filename": "633_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 16, - "h": 20 - }, - "frame": { - "x": 52, - "y": 570, - "w": 16, - "h": 20 - } - }, - { - "filename": "633_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 8, - "w": 16, - "h": 20 - }, - "frame": { - "x": 52, - "y": 590, - "w": 16, - "h": 20 - } - }, - { - "filename": "578_1", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 16, - "h": 19 - }, - "frame": { - "x": 52, - "y": 610, - "w": 16, - "h": 19 - } - }, - { - "filename": "622_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 18, - "h": 18 - }, - "frame": { - "x": 52, - "y": 629, - "w": 18, - "h": 18 - } - }, - { - "filename": "578_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 16, - "h": 19 - }, - "frame": { - "x": 70, - "y": 508, - "w": 16, - "h": 19 - } - }, - { - "filename": "578_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 9, - "w": 16, - "h": 19 - }, - "frame": { - "x": 86, - "y": 507, - "w": 16, - "h": 19 - } - }, - { - "filename": "562_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 22, - "h": 16 - }, - "frame": { - "x": 102, - "y": 505, - "w": 22, - "h": 16 - } - }, { "filename": "595_2", "rotated": false, @@ -3132,14 +2838,14 @@ "h": 16 }, "frame": { - "x": 102, - "y": 521, + "x": 70, + "y": 343, "w": 21, "h": 16 } }, { - "filename": "570_2", + "filename": "495_3", "rotated": false, "trimmed": true, "sourceSize": { @@ -3147,36 +2853,15 @@ "h": 30 }, "spriteSourceSize": { - "x": 12, + "x": 10, "y": 11, - "w": 16, + "w": 20, "h": 17 }, "frame": { - "x": 86, - "y": 526, - "w": 16, - "h": 17 - } - }, - { - "filename": "570_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 12, - "y": 11, - "w": 16, - "h": 17 - }, - "frame": { - "x": 70, - "y": 527, - "w": 16, + "x": 71, + "y": 359, + "w": 20, "h": 17 } }, @@ -3195,159 +2880,12 @@ "h": 19 }, "frame": { - "x": 67, - "y": 544, + "x": 91, + "y": 344, "w": 18, "h": 19 } }, - { - "filename": "622_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 10, - "w": 18, - "h": 18 - }, - "frame": { - "x": 68, - "y": 563, - "w": 18, - "h": 18 - } - }, - { - "filename": "541_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 12, - "w": 20, - "h": 16 - }, - "frame": { - "x": 68, - "y": 581, - "w": 20, - "h": 16 - } - }, - { - "filename": "541_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 10, - "y": 12, - "w": 20, - "h": 16 - }, - "frame": { - "x": 68, - "y": 597, - "w": 20, - "h": 16 - } - }, - { - "filename": "595_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 9, - "y": 12, - "w": 21, - "h": 16 - }, - "frame": { - "x": 68, - "y": 613, - "w": 21, - "h": 16 - } - }, - { - "filename": "540_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 11, - "w": 15, - "h": 17 - }, - "frame": { - "x": 70, - "y": 629, - "w": 15, - "h": 17 - } - }, - { - "filename": "543_2", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 11, - "y": 14, - "w": 18, - "h": 14 - }, - "frame": { - "x": 102, - "y": 537, - "w": 18, - "h": 14 - } - }, - { - "filename": "602_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 17, - "w": 14, - "h": 11 - }, - "frame": { - "x": 88, - "y": 543, - "w": 14, - "h": 11 - } - }, { "filename": "605_1", "rotated": false, @@ -3363,12 +2901,96 @@ "h": 19 }, "frame": { - "x": 67, - "y": 647, + "x": 109, + "y": 330, "w": 13, "h": 19 } }, + { + "filename": "608_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 10, + "w": 19, + "h": 18 + }, + "frame": { + "x": 72, + "y": 376, + "w": 19, + "h": 18 + } + }, + { + "filename": "608_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 10, + "w": 19, + "h": 18 + }, + "frame": { + "x": 72, + "y": 394, + "w": 19, + "h": 18 + } + }, + { + "filename": "622_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 10, + "w": 18, + "h": 18 + }, + "frame": { + "x": 91, + "y": 363, + "w": 18, + "h": 18 + } + }, + { + "filename": "622_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 10, + "w": 18, + "h": 18 + }, + "frame": { + "x": 91, + "y": 381, + "w": 18, + "h": 18 + } + }, { "filename": "605_2", "rotated": false, @@ -3384,33 +3006,12 @@ "h": 19 }, "frame": { - "x": 80, - "y": 646, + "x": 109, + "y": 349, "w": 13, "h": 19 } }, - { - "filename": "540_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 11, - "w": 15, - "h": 17 - }, - "frame": { - "x": 85, - "y": 629, - "w": 15, - "h": 17 - } - }, { "filename": "605_3", "rotated": false, @@ -3426,12 +3027,327 @@ "h": 19 }, "frame": { - "x": 93, - "y": 646, + "x": 109, + "y": 368, "w": 13, "h": 19 } }, + { + "filename": "529_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 11, + "w": 21, + "h": 17 + }, + "frame": { + "x": 91, + "y": 399, + "w": 21, + "h": 17 + } + }, + { + "filename": "529_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 11, + "w": 21, + "h": 17 + }, + "frame": { + "x": 86, + "y": 416, + "w": 21, + "h": 17 + } + }, + { + "filename": "633_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 16, + "h": 20 + }, + "frame": { + "x": 107, + "y": 416, + "w": 16, + "h": 20 + } + }, + { + "filename": "595_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 21, + "h": 16 + }, + "frame": { + "x": 86, + "y": 433, + "w": 21, + "h": 16 + } + }, + { + "filename": "633_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 8, + "w": 16, + "h": 20 + }, + "frame": { + "x": 107, + "y": 436, + "w": 16, + "h": 20 + } + }, + { + "filename": "546_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 14, + "w": 21, + "h": 14 + }, + "frame": { + "x": 86, + "y": 449, + "w": 21, + "h": 14 + } + }, + { + "filename": "578_1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 16, + "h": 19 + }, + "frame": { + "x": 107, + "y": 456, + "w": 16, + "h": 19 + } + }, + { + "filename": "541_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 12, + "w": 20, + "h": 16 + }, + "frame": { + "x": 87, + "y": 463, + "w": 20, + "h": 16 + } + }, + { + "filename": "578_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 16, + "h": 19 + }, + "frame": { + "x": 107, + "y": 475, + "w": 16, + "h": 19 + } + }, + { + "filename": "541_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 10, + "y": 12, + "w": 20, + "h": 16 + }, + "frame": { + "x": 87, + "y": 479, + "w": 20, + "h": 16 + } + }, + { + "filename": "551_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 8, + "y": 13, + "w": 22, + "h": 16 + }, + "frame": { + "x": 87, + "y": 495, + "w": 22, + "h": 16 + } + }, + { + "filename": "562_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 22, + "h": 16 + }, + "frame": { + "x": 89, + "y": 511, + "w": 22, + "h": 16 + } + }, + { + "filename": "562_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 9, + "y": 12, + "w": 22, + "h": 16 + }, + "frame": { + "x": 89, + "y": 527, + "w": 22, + "h": 16 + } + }, + { + "filename": "578_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 9, + "w": 16, + "h": 19 + }, + "frame": { + "x": 89, + "y": 543, + "w": 16, + "h": 19 + } + }, + { + "filename": "543_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 11, + "y": 14, + "w": 18, + "h": 14 + }, + "frame": { + "x": 105, + "y": 543, + "w": 18, + "h": 14 + } + }, { "filename": "543_3", "rotated": false, @@ -3447,12 +3363,54 @@ "h": 14 }, "frame": { - "x": 102, - "y": 551, + "x": 105, + "y": 557, "w": 18, "h": 14 } }, + { + "filename": "548_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 10, + "w": 12, + "h": 18 + }, + "frame": { + "x": 111, + "y": 494, + "w": 12, + "h": 18 + } + }, + { + "filename": "548_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 14, + "y": 10, + "w": 12, + "h": 18 + }, + "frame": { + "x": 111, + "y": 512, + "w": 12, + "h": 18 + } + }, { "filename": "607_2", "rotated": false, @@ -3468,14 +3426,14 @@ "h": 18 }, "frame": { - "x": 89, - "y": 554, + "x": 91, + "y": 562, "w": 13, "h": 18 } }, { - "filename": "517_2", + "filename": "570_2", "rotated": false, "trimmed": true, "sourceSize": { @@ -3483,16 +3441,16 @@ "h": 30 }, "spriteSourceSize": { - "x": 13, - "y": 14, - "w": 15, - "h": 14 + "x": 12, + "y": 11, + "w": 16, + "h": 17 }, "frame": { - "x": 102, - "y": 565, - "w": 15, - "h": 14 + "x": 104, + "y": 571, + "w": 16, + "h": 17 } }, { @@ -3510,12 +3468,117 @@ "h": 18 }, "frame": { - "x": 88, - "y": 572, + "x": 91, + "y": 580, "w": 13, "h": 18 } }, + { + "filename": "570_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 12, + "y": 11, + "w": 16, + "h": 17 + }, + "frame": { + "x": 87, + "y": 598, + "w": 16, + "h": 17 + } + }, + { + "filename": "517_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 14, + "w": 15, + "h": 14 + }, + "frame": { + "x": 104, + "y": 588, + "w": 15, + "h": 14 + } + }, + { + "filename": "517_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 14, + "w": 15, + "h": 14 + }, + "frame": { + "x": 103, + "y": 602, + "w": 15, + "h": 14 + } + }, + { + "filename": "540_2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 11, + "w": 15, + "h": 17 + }, + "frame": { + "x": 90, + "y": 616, + "w": 15, + "h": 17 + } + }, + { + "filename": "540_3", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 13, + "y": 11, + "w": 15, + "h": 17 + }, + "frame": { + "x": 90, + "y": 633, + "w": 15, + "h": 17 + } + }, { "filename": "559_1", "rotated": false, @@ -3531,8 +3594,8 @@ "h": 16 }, "frame": { - "x": 88, - "y": 590, + "x": 105, + "y": 616, "w": 15, "h": 16 } @@ -3552,8 +3615,8 @@ "h": 16 }, "frame": { - "x": 89, - "y": 606, + "x": 105, + "y": 632, "w": 15, "h": 16 } @@ -3573,33 +3636,12 @@ "h": 16 }, "frame": { - "x": 103, - "y": 579, + "x": 105, + "y": 648, "w": 15, "h": 16 } }, - { - "filename": "517_3", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 13, - "y": 14, - "w": 15, - "h": 14 - }, - "frame": { - "x": 104, - "y": 595, - "w": 15, - "h": 14 - } - }, { "filename": "577_1", "rotated": false, @@ -3615,8 +3657,8 @@ "h": 14 }, "frame": { - "x": 104, - "y": 609, + "x": 93, + "y": 664, "w": 15, "h": 14 } @@ -3636,8 +3678,8 @@ "h": 14 }, "frame": { - "x": 100, - "y": 623, + "x": 108, + "y": 664, "w": 15, "h": 14 } @@ -3657,8 +3699,8 @@ "h": 14 }, "frame": { - "x": 106, - "y": 637, + "x": 93, + "y": 678, "w": 15, "h": 14 } @@ -3669,6 +3711,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:018cb8e5f06a9ed9edd0bdc8721daa73:985d20f8fcceb349f1b7fba26ba674e8:f1931bc28ee7f32dba7543723757cf2a$" + "smartupdate": "$TexturePacker:SmartUpdate:982d6d8f8bd84ab35fcc0559c4fe5188:e14c2b4fa19e2d528ab6fda3d5a817e6:f1931bc28ee7f32dba7543723757cf2a$" } } diff --git a/public/images/pokemon_icons_5v.png b/public/images/pokemon_icons_5v.png index 0f4099b575f..d82ea5cc881 100644 Binary files a/public/images/pokemon_icons_5v.png and b/public/images/pokemon_icons_5v.png differ diff --git a/public/images/trainer/aqua_admin_f.json b/public/images/trainer/aqua_admin_f.json new file mode 100644 index 00000000000..35e6e43edc3 --- /dev/null +++ b/public/images/trainer/aqua_admin_f.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "aqua_admin_f.png", + "format": "RGBA8888", + "size": { + "w": 80, + "h": 80 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + }, + "frame": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:efd07ff3ed1e610150a4b8ca18974343:d9b85b9eb11182e9e4669e2bd8b08694:72b7b50231708a9486d5f315824e4df1$" + } +} diff --git a/public/images/trainer/aqua_admin_f.png b/public/images/trainer/aqua_admin_f.png new file mode 100644 index 00000000000..505dce1b110 Binary files /dev/null and b/public/images/trainer/aqua_admin_f.png differ diff --git a/public/images/trainer/aqua_admin_m.json b/public/images/trainer/aqua_admin_m.json new file mode 100644 index 00000000000..f52412623cc --- /dev/null +++ b/public/images/trainer/aqua_admin_m.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "aqua_admin_m.png", + "format": "RGBA8888", + "size": { + "w": 80, + "h": 80 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + }, + "frame": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:831f5748dad92911b10a1cb358ee2dae:a3bf81bbaa3b49cad5e0e549cf94563b:bb6befc9383c9c08837183ae2a7a80c1$" + } +} \ No newline at end of file diff --git a/public/images/trainer/aqua_admin_m.png b/public/images/trainer/aqua_admin_m.png new file mode 100644 index 00000000000..a4f7893e565 Binary files /dev/null and b/public/images/trainer/aqua_admin_m.png differ diff --git a/public/images/trainer/flare_admin_f.json b/public/images/trainer/flare_admin_f.json new file mode 100644 index 00000000000..1e39a3fcb03 --- /dev/null +++ b/public/images/trainer/flare_admin_f.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "flare_admin_f.png", + "format": "RGBA8888", + "size": { + "w": 80, + "h": 80 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + }, + "frame": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:831f5748dad92911b10a1cb358ee2dae:a3bf81bbaa3b49cad5e0e549cf94563b:bb6befc9383c9c08837183ae2a7a80c1$" + } +} \ No newline at end of file diff --git a/public/images/trainer/flare_admin_f.png b/public/images/trainer/flare_admin_f.png new file mode 100644 index 00000000000..14d8abdaa39 Binary files /dev/null and b/public/images/trainer/flare_admin_f.png differ diff --git a/public/images/trainer/flare_admin_m.json b/public/images/trainer/flare_admin_m.json new file mode 100644 index 00000000000..4228fac6af0 --- /dev/null +++ b/public/images/trainer/flare_admin_m.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "flare_admin_m.png", + "format": "RGBA8888", + "size": { + "w": 80, + "h": 80 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + }, + "frame": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:c30bf82452209a923f4becf13d275a9a:a6355b09f92c9c0388d0b919010f587f:0638dbf213f8a974eb5af76eb1e5ddeb$" + } +} diff --git a/public/images/trainer/flare_admin_m.png b/public/images/trainer/flare_admin_m.png new file mode 100644 index 00000000000..f431c20a479 Binary files /dev/null and b/public/images/trainer/flare_admin_m.png differ diff --git a/public/images/trainer/galactic_admin_f.json b/public/images/trainer/galactic_admin_f.json new file mode 100644 index 00000000000..eae1da8fff1 --- /dev/null +++ b/public/images/trainer/galactic_admin_f.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "galactic_admin_f.png", + "format": "RGBA8888", + "size": { + "w": 80, + "h": 80 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + }, + "frame": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:831f5748dad92911b10a1cb358ee2dae:a3bf81bbaa3b49cad5e0e549cf94563b:bb6befc9383c9c08837183ae2a7a80c1$" + } +} \ No newline at end of file diff --git a/public/images/trainer/galactic_admin_f.png b/public/images/trainer/galactic_admin_f.png new file mode 100644 index 00000000000..ca7af064bc8 Binary files /dev/null and b/public/images/trainer/galactic_admin_f.png differ diff --git a/public/images/trainer/galactic_admin_m.json b/public/images/trainer/galactic_admin_m.json new file mode 100644 index 00000000000..f404c2247e9 --- /dev/null +++ b/public/images/trainer/galactic_admin_m.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "galactic_admin_m.png", + "format": "RGBA8888", + "size": { + "w": 80, + "h": 80 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + }, + "frame": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:3012867f03f02c4ee67a8ab3ad5a000e:77a5f60f1adc158664b3b2ee17bf30fe:7e8259b5177c0a76e5d02d6bdc66affe$" + } +} diff --git a/public/images/trainer/galactic_admin_m.png b/public/images/trainer/galactic_admin_m.png new file mode 100644 index 00000000000..cb59227c7a7 Binary files /dev/null and b/public/images/trainer/galactic_admin_m.png differ diff --git a/public/images/trainer/magma_admin_f.json b/public/images/trainer/magma_admin_f.json new file mode 100644 index 00000000000..95e00803df4 --- /dev/null +++ b/public/images/trainer/magma_admin_f.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "magma_admin_f.png", + "format": "RGBA8888", + "size": { + "w": 80, + "h": 80 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + }, + "frame": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:831f5748dad92911b10a1cb358ee2dae:a3bf81bbaa3b49cad5e0e549cf94563b:bb6befc9383c9c08837183ae2a7a80c1$" + } +} \ No newline at end of file diff --git a/public/images/trainer/magma_admin_f.png b/public/images/trainer/magma_admin_f.png new file mode 100644 index 00000000000..979fe6ae837 Binary files /dev/null and b/public/images/trainer/magma_admin_f.png differ diff --git a/public/images/trainer/magma_admin_m.json b/public/images/trainer/magma_admin_m.json new file mode 100644 index 00000000000..977e911eb69 --- /dev/null +++ b/public/images/trainer/magma_admin_m.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "magma_admin_m.png", + "format": "RGBA8888", + "size": { + "w": 80, + "h": 80 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + }, + "frame": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:f63ad48affc076f60fae78992c96a2bf:80928b32710abcb28c07c6fc5a425d99:3b961d8852b62aaf24ceb2030c036515$" + } +} diff --git a/public/images/trainer/magma_admin_m.png b/public/images/trainer/magma_admin_m.png new file mode 100644 index 00000000000..93e3a17539d Binary files /dev/null and b/public/images/trainer/magma_admin_m.png differ diff --git a/public/images/trainer/plasma_sage.json b/public/images/trainer/plasma_sage.json new file mode 100644 index 00000000000..05e75141ec0 --- /dev/null +++ b/public/images/trainer/plasma_sage.json @@ -0,0 +1,2120 @@ +{ + "textures": [ + { + "image": "plasma_sage.png", + "format": "RGBA8888", + "size": { + "w": 250, + "h": 250 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 11, + "y": 1, + "w": 56, + "h": 79 + }, + "frame": { + "x": 1, + "y": 1, + "w": 56, + "h": 79 + } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 11, + "y": 1, + "w": 56, + "h": 79 + }, + "frame": { + "x": 1, + "y": 1, + "w": 56, + "h": 79 + } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 11, + "y": 1, + "w": 56, + "h": 79 + }, + "frame": { + "x": 1, + "y": 1, + "w": 56, + "h": 79 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 11, + "y": 1, + "w": 56, + "h": 79 + }, + "frame": { + "x": 1, + "y": 1, + "w": 56, + "h": 79 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 13, + "y": 2, + "w": 55, + "h": 78 + }, + "frame": { + "x": 1, + "y": 82, + "w": 55, + "h": 78 + } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 14, + "y": 2, + "w": 54, + "h": 78 + }, + "frame": { + "x": 59, + "y": 1, + "w": 54, + "h": 78 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 14, + "y": 2, + "w": 54, + "h": 78 + }, + "frame": { + "x": 59, + "y": 1, + "w": 54, + "h": 78 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 16, + "y": 3, + "w": 53, + "h": 77 + }, + "frame": { + "x": 1, + "y": 162, + "w": 53, + "h": 77 + } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 16, + "y": 4, + "w": 53, + "h": 76 + }, + "frame": { + "x": 115, + "y": 1, + "w": 53, + "h": 76 + } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 16, + "y": 4, + "w": 53, + "h": 76 + }, + "frame": { + "x": 115, + "y": 1, + "w": 53, + "h": 76 + } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 16, + "y": 4, + "w": 53, + "h": 76 + }, + "frame": { + "x": 115, + "y": 1, + "w": 53, + "h": 76 + } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 16, + "y": 4, + "w": 53, + "h": 76 + }, + "frame": { + "x": 115, + "y": 1, + "w": 53, + "h": 76 + } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 16, + "y": 4, + "w": 53, + "h": 76 + }, + "frame": { + "x": 115, + "y": 1, + "w": 53, + "h": 76 + } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 16, + "y": 4, + "w": 53, + "h": 76 + }, + "frame": { + "x": 115, + "y": 1, + "w": 53, + "h": 76 + } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 16, + "y": 4, + "w": 53, + "h": 76 + }, + "frame": { + "x": 115, + "y": 1, + "w": 53, + "h": 76 + } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 20, + "y": 3, + "w": 49, + "h": 77 + }, + "frame": { + "x": 170, + "y": 1, + "w": 49, + "h": 77 + } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 20, + "y": 2, + "w": 47, + "h": 78 + }, + "frame": { + "x": 58, + "y": 82, + "w": 47, + "h": 78 + } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 56, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0019.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 56, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 107, + "y": 81, + "w": 46, + "h": 80 + } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 104, + "y": 163, + "w": 46, + "h": 80 + } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0024.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0025.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0026.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0027.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0028.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0029.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0030.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0031.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0032.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0033.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 155, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0034.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 203, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0035.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 203, + "y": 80, + "w": 46, + "h": 80 + } + }, + { + "filename": "0036.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 46, + "h": 80 + }, + "frame": { + "x": 152, + "y": 163, + "w": 46, + "h": 80 + } + }, + { + "filename": "0037.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0038.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0039.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0040.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0041.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0042.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0043.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0044.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0045.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0046.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0047.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0048.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0049.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0050.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0051.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0052.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0053.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0054.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0055.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0056.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0057.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0058.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0059.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0060.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0061.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0062.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0063.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0064.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0065.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0066.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0067.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0068.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0069.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0070.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0071.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0072.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0073.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0074.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0075.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0076.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0077.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0078.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0079.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0080.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0081.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0082.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0083.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0084.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0085.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0086.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0087.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0088.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0089.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0090.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0091.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0092.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0093.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0094.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0095.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0096.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0097.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0098.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0099.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + }, + { + "filename": "0100.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 21, + "y": 1, + "w": 46, + "h": 79 + }, + "frame": { + "x": 200, + "y": 162, + "w": 46, + "h": 79 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:98df2be457c75de554b8ce6c2f5ff582:93e2cb242dc211e2485f87e4db93af88:0c38bc008e5ede7b6331c02b8220846f$" + } +} \ No newline at end of file diff --git a/public/images/trainer/plasma_sage.png b/public/images/trainer/plasma_sage.png new file mode 100644 index 00000000000..6c866562989 Binary files /dev/null and b/public/images/trainer/plasma_sage.png differ diff --git a/public/images/trainer/rocket_admin_f.json b/public/images/trainer/rocket_admin_f.json new file mode 100644 index 00000000000..7c154785ba3 --- /dev/null +++ b/public/images/trainer/rocket_admin_f.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "rocket_admin_f.png", + "format": "RGBA8888", + "size": { + "w": 80, + "h": 80 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + }, + "frame": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:831f5748dad92911b10a1cb358ee2dae:a3bf81bbaa3b49cad5e0e549cf94563b:bb6befc9383c9c08837183ae2a7a80c1$" + } +} \ No newline at end of file diff --git a/public/images/trainer/rocket_admin_f.png b/public/images/trainer/rocket_admin_f.png new file mode 100644 index 00000000000..0244538d91e Binary files /dev/null and b/public/images/trainer/rocket_admin_f.png differ diff --git a/public/images/trainer/rocket_admin_m.json b/public/images/trainer/rocket_admin_m.json new file mode 100644 index 00000000000..a1ad82dd9a2 --- /dev/null +++ b/public/images/trainer/rocket_admin_m.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "rocket_admin_m.png", + "format": "RGBA8888", + "size": { + "w": 80, + "h": 80 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + }, + "frame": { + "x": 0, + "y": 0, + "w": 80, + "h": 80 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:831f5748dad92911b10a1cb358ee2dae:a3bf81bbaa3b49cad5e0e549cf94563b:bb6befc9383c9c08837183ae2a7a80c1$" + } +} diff --git a/public/images/trainer/rocket_admin_m.png b/public/images/trainer/rocket_admin_m.png new file mode 100644 index 00000000000..5dcc4ff286e Binary files /dev/null and b/public/images/trainer/rocket_admin_m.png differ diff --git a/src/@types/i18next.d.ts b/src/@types/i18next.d.ts index f3a63d6f4ec..a1cf70d91d5 100644 --- a/src/@types/i18next.d.ts +++ b/src/@types/i18next.d.ts @@ -1,4 +1,4 @@ -import { enConfig } from "#app/locales/en/config.js"; +import { type enConfig } from "#app/locales/en/config.js"; // Module declared to make referencing keys in the localization files type-safe. declare module "i18next" { diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 19f8dad862e..f54ff92e324 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1,6 +1,6 @@ import Phaser from "phaser"; import UI from "./ui/ui"; -import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, MovePhase, TitlePhase, SwitchPhase } from "./phases"; +import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, MovePhase, TitlePhase, SwitchPhase, SummonPhase, ToggleDoublePositionPhase } from "./phases"; import Pokemon, { PlayerPokemon, EnemyPokemon } from "./field/pokemon"; import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies } from "./data/pokemon-species"; import { Constructor } from "#app/utils"; @@ -14,7 +14,7 @@ import { Arena, ArenaBase } from "./field/arena"; import { GameData } from "./system/game-data"; import { TextStyle, addTextObject, getTextColor } from "./ui/text"; import { allMoves } from "./data/move"; -import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getPartyLuckValue } from "./modifier/modifier-type"; +import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getModifierType, getPartyLuckValue, modifierTypes } from "./modifier/modifier-type"; import AbilityBar from "./ui/ability-bar"; import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, IncrementMovePriorityAbAttr, PostBattleInitAbAttr, applyAbAttrs, applyPostBattleInitAbAttrs } from "./data/ability"; import { allAbilities } from "./data/ability"; @@ -68,6 +68,8 @@ import { UiTheme } from "#enums/ui-theme"; import { TimedEventManager } from "#app/timed-event-manager.js"; import i18next from "i18next"; import {TrainerType} from "#enums/trainer-type"; +import { battleSpecDialogue } from "./data/dialogue"; +import { LoadingScene } from "./loading-scene"; export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1"; @@ -230,7 +232,7 @@ export default class BattleScene extends SceneBase { private fieldOverlay: Phaser.GameObjects.Rectangle; private shopOverlay: Phaser.GameObjects.Rectangle; private shopOverlayShown: boolean = false; - private shopOverlayOpacity: number = .80; + private shopOverlayOpacity: number = .8; public modifiers: PersistentModifier[]; private enemyModifiers: PersistentModifier[]; @@ -319,6 +321,7 @@ export default class BattleScene extends SceneBase { } create() { + this.scene.remove(LoadingScene.KEY); initGameSpeed.apply(this); this.inputController = new InputsController(this); this.uiInputs = new UiInputs(this, this.inputController); @@ -369,7 +372,7 @@ export default class BattleScene extends SceneBase { this.fieldUI = fieldUI; - const transition = (this.make as any).rexTransitionImagePack({ + const transition = this.make.rexTransitionImagePack({ x: 0, y: 0, scale: 6, @@ -377,11 +380,14 @@ export default class BattleScene extends SceneBase { origin: { x: 0, y: 0 } }, true); + //@ts-ignore (the defined types in the package are incromplete...) transition.transit({ mode: "blinds", ease: "Cubic.easeInOut", duration: 1250, - oncomplete: () => transition.destroy() + }); + transition.once("complete", () => { + transition.destroy(); }); this.add.existing(transition); @@ -1056,7 +1062,7 @@ export default class BattleScene extends SceneBase { playerField.forEach(p => applyAbAttrs(DoubleBattleChanceAbAttr, p, null, doubleChance)); doubleTrainer = !Utils.randSeedInt(doubleChance.value); // Add a check that special trainers can't be double except for tate and liza - they should use the normal double chance - if (trainerConfigs[trainerType].trainerTypeDouble && !(trainerType === TrainerType.TATE || trainerType === TrainerType.LIZA)) { + if (trainerConfigs[trainerType].trainerTypeDouble && ![ TrainerType.TATE, TrainerType.LIZA ].includes(trainerType)) { doubleTrainer = false; } } @@ -1133,7 +1139,7 @@ export default class BattleScene extends SceneBase { } if (resetArenaState) { this.arena.resetArenaEffects(); - playerField.forEach((_, p) => this.unshiftPhase(new ReturnPhase(this, p))); + playerField.forEach((_, p) => this.pushPhase(new ReturnPhase(this, p))); for (const pokemon of this.getParty()) { // Only trigger form change when Eiscue is in Noice form @@ -1146,7 +1152,7 @@ export default class BattleScene extends SceneBase { applyPostBattleInitAbAttrs(PostBattleInitAbAttr, pokemon); } - this.unshiftPhase(new ShowTrainerPhase(this)); + this.pushPhase(new ShowTrainerPhase(this)); } for (const pokemon of this.getParty()) { @@ -1786,8 +1792,10 @@ export default class BattleScene extends SceneBase { return 13.950; case "battle_johto_champion": //B2W2 Johto Champion Battle return 23.498; - case "battle_hoenn_champion": //B2W2 Hoenn Champion Battle + case "battle_hoenn_champion_g5": //B2W2 Hoenn Champion Battle return 11.328; + case "battle_hoenn_champion_g6": //ORAS Hoenn Champion Battle + return 11.762; case "battle_sinnoh_champion": //B2W2 Sinnoh Champion Battle return 12.235; case "battle_champion_alder": //BW Unova Champion Battle @@ -2619,4 +2627,33 @@ export default class BattleScene extends SceneBase { }; (window as any).gameInfo = gameInfo; } + + /** + * Initialized the 2nd phase of the final boss (e.g. form-change for Eternatus) + * @param pokemon The (enemy) pokemon + */ + initFinalBossPhaseTwo(pokemon: Pokemon): void { + if (pokemon instanceof EnemyPokemon && pokemon.isBoss() && !pokemon.formIndex && pokemon.bossSegmentIndex < 1) { + this.fadeOutBgm(Utils.fixedInt(2000), false); + this.ui.showDialogue(battleSpecDialogue[BattleSpec.FINAL_BOSS].firstStageWin, pokemon.species.name, null, () => { + this.addEnemyModifier(getModifierType(modifierTypes.MINI_BLACK_HOLE).newModifier(pokemon) as PersistentModifier, false, true); + pokemon.generateAndPopulateMoveset(1); + this.setFieldScale(0.75); + this.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); + this.currentBattle.double = true; + const availablePartyMembers = this.getParty().filter((p) => p.isAllowedInBattle()); + if (availablePartyMembers.length > 1) { + this.pushPhase(new ToggleDoublePositionPhase(this, true)); + if (!availablePartyMembers[1].isOnField()) { + this.pushPhase(new SummonPhase(this, 1)); + } + } + + this.shiftPhase(); + }); + return; + } + + this.shiftPhase(); + } } diff --git a/src/battle.ts b/src/battle.ts index b8df7635472..e8a1323fc4c 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -294,7 +294,7 @@ export default class Battle { if (pokemon.species.speciesId === Species.TAPU_KOKO || pokemon.species.speciesId === Species.TAPU_LELE || pokemon.species.speciesId === Species.TAPU_BULU || pokemon.species.speciesId === Species.TAPU_FINI) { return "battle_legendary_tapu"; } - if (pokemon.species.speciesId === Species.COSMOG || pokemon.species.speciesId === Species.COSMOEM || pokemon.species.speciesId === Species.SOLGALEO || pokemon.species.speciesId === Species.LUNALA) { + if ([ Species.COSMOG, Species.COSMOEM, Species.SOLGALEO, Species.LUNALA ].includes(pokemon.species.speciesId)) { return "battle_legendary_sol_lun"; } if (pokemon.species.speciesId === Species.NECROZMA) { @@ -308,7 +308,7 @@ export default class Battle { return "battle_legendary_ultra_nec"; } } - if (pokemon.species.speciesId === Species.NIHILEGO || pokemon.species.speciesId === Species.BUZZWOLE || pokemon.species.speciesId === Species.PHEROMOSA || pokemon.species.speciesId === Species.XURKITREE || pokemon.species.speciesId === Species.CELESTEELA || pokemon.species.speciesId === Species.KARTANA || pokemon.species.speciesId === Species.GUZZLORD || pokemon.species.speciesId === Species.POIPOLE || pokemon.species.speciesId === Species.NAGANADEL || pokemon.species.speciesId === Species.STAKATAKA || pokemon.species.speciesId === Species.BLACEPHALON) { + if ([ Species.NIHILEGO, Species.BUZZWOLE, Species.PHEROMOSA, Species.XURKITREE, Species.CELESTEELA, Species.KARTANA, Species.GUZZLORD, Species.POIPOLE, Species.NAGANADEL, Species.STAKATAKA, Species.BLACEPHALON ].includes(pokemon.species.speciesId)) { return "battle_legendary_ub"; } if (pokemon.species.speciesId === Species.ZACIAN || pokemon.species.speciesId === Species.ZAMAZENTA) { @@ -425,7 +425,13 @@ export class FixedBattleConfig { } } -function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): GetTrainerFunc { +/** + * Helper function to generate a random trainer for evil team trainers and the elite 4/champion + * @param trainerPool The TrainerType or list of TrainerTypes that can possibly be generated + * @param randomGender whether or not to randomly (50%) generate a female trainer (for use with evil team grunts) + * @returns the generated trainer + */ +function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], randomGender: boolean = false): GetTrainerFunc { return (scene: BattleScene) => { const rand = Utils.randSeedInt(trainerPool.length); const trainerTypes: TrainerType[] = []; @@ -435,11 +441,20 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): Get : trainerPoolEntry; trainerTypes.push(trainerType); } - // If the trainer type has a double variant, there's a 33% chance of it being a double battle (for now we only allow tate&liza to be double) - if (trainerConfigs[trainerTypes[rand]].trainerTypeDouble && (trainerTypes[rand] === TrainerType.TATE || trainerTypes[rand] === TrainerType.LIZA)) { - return new Trainer(scene, trainerTypes[rand], Utils.randSeedInt(3) ? TrainerVariant.DOUBLE : TrainerVariant.DEFAULT); + let trainerGender = TrainerVariant.DEFAULT; + if (randomGender) { + trainerGender = (Utils.randInt(2) === 0) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT; } - return new Trainer(scene, trainerTypes[rand], TrainerVariant.DEFAULT); + + /* 1/3 chance for evil team grunts to be double battles */ + const evilTeamGrunts = [TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT]; + const isEvilTeamGrunt = evilTeamGrunts.includes(trainerTypes[rand]); + + if (trainerConfigs[trainerTypes[rand]].hasDouble && isEvilTeamGrunt) { + return new Trainer(scene, trainerTypes[rand], (Utils.randInt(3) === 0) ? TrainerVariant.DOUBLE : trainerGender); + } + + return new Trainer(scene, trainerTypes[rand], trainerGender); }; } @@ -449,7 +464,8 @@ export interface FixedBattleConfigs { /** * Youngster/Lass on 5 * Rival on 8, 55, 95, 145, 195 - * Evil team grunts on 35, 62, 64, 66, 112, 114 + * Evil team grunts on 35, 62, 64, and 112 + * Evil team admin on 66 and 114 * Evil leader on 115, 165 * E4 on 182, 184, 186, 188 * Champion on 190 @@ -462,21 +478,21 @@ export const classicFixedBattles: FixedBattleConfigs = { [25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), [35]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) - .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT ])), + .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT ], true)), [55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), [62]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) - .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT ])), + .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT ], true)), [64]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) - .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT ])), + .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT ], true)), [66]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) - .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT ])), + .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_ADMIN, TrainerType.MAGMA_ADMIN, TrainerType.AQUA_ADMIN, TrainerType.GALACTIC_ADMIN, TrainerType.PLASMA_SAGE, TrainerType.FLARE_ADMIN ], true)), [95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), [112]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) - .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT ])), + .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT ], true)), [114]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) - .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT ])), + .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_ADMIN, TrainerType.MAGMA_ADMIN, TrainerType.AQUA_ADMIN, TrainerType.GALACTIC_ADMIN, TrainerType.PLASMA_SAGE, TrainerType.FLARE_ADMIN ], true)), [115]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35) .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE ])), [145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) diff --git a/src/data/ability.ts b/src/data/ability.ts index 40461f72e97..9e77013ff13 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -1,4 +1,4 @@ -import Pokemon, { HitResult, PokemonMove } from "../field/pokemon"; +import Pokemon, { HitResult, PlayerPokemon, PokemonMove } from "../field/pokemon"; import { Type } from "./type"; import { Constructor } from "#app/utils"; import * as Utils from "../utils"; @@ -286,7 +286,7 @@ export class BlockItemTheftAbAttr extends AbAttr { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) { return i18next.t("abilityTriggers:blockItemTheft", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - abilityName: abilityName, + abilityName }); } } @@ -405,7 +405,7 @@ export class TypeImmunityHealAbAttr extends TypeImmunityAbAttr { if (!simulated) { const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name; pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), - Math.max(Math.floor(pokemon.getMaxHp() / 4), 1), i18next.t("abilityTriggers:typeImmunityHeal", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName}), true)); + Math.max(Math.floor(pokemon.getMaxHp() / 4), 1), i18next.t("abilityTriggers:typeImmunityHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true)); } } return true; @@ -485,7 +485,7 @@ export class NonSuperEffectiveImmunityAbAttr extends TypeImmunityAbAttr { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { return i18next.t("abilityTriggers:nonSuperEffectiveImmunity", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - abilityName: abilityName, + abilityName }); } } @@ -777,7 +777,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { return i18next.t("abilityTriggers:postDefendTypeChange", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - abilityName: abilityName, + abilityName, typeName: i18next.t(`pokemonInfo:Type.${Type[pokemon.getTypes(true)[0]]}`) }); } @@ -901,7 +901,7 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { return i18next.t("abilityTriggers:postDefendContactDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - abilityName: abilityName, + abilityName }); } } @@ -941,14 +941,19 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr { export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr { private weatherType: WeatherType; + protected condition: PokemonDefendCondition | null; - constructor(weatherType: WeatherType) { + constructor(weatherType: WeatherType, condition?: PokemonDefendCondition) { super(); this.weatherType = weatherType; + this.condition = condition ?? null; } applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { + if (this.condition !== null && !this.condition(pokemon, attacker, move)) { + return false; + } if (!pokemon.scene.arena.weather?.isImmutable()) { return pokemon.scene.arena.trySetWeather(this.weatherType, true); } @@ -999,7 +1004,7 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { return i18next.t("abilityTriggers:postDefendAbilityGive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - abilityName: abilityName, + abilityName }); } } @@ -1083,9 +1088,8 @@ export class MoveEffectChanceMultiplierAbAttr extends AbAttr { * [1]: {@linkcode Moves } Move used by the ability user. */ apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { - //Disable showAbility during getTargetBenefitScore - const showAbility = args[4]; - this.showAbility = showAbility; + // Disable showAbility during getTargetBenefitScore + this.showAbility = args[4]; if ((args[0] as Utils.NumberHolder).value <= 0 || (args[1] as Move).id === Moves.ORDER_UP) { return false; } @@ -1532,23 +1536,50 @@ export class BattleStatMultiplierAbAttr extends AbAttr { } export class PostAttackAbAttr extends AbAttr { + private attackCondition: PokemonAttackCondition; + + /** The default attackCondition requires that the selected move is a damaging move */ + constructor(attackCondition: PokemonAttackCondition = (user, target, move) => (move.category !== MoveCategory.STATUS)) { + super(); + + this.attackCondition = attackCondition; + } + + /** + * Please override {@link applyPostAttackAfterMoveTypeCheck} instead of this method. By default, this method checks that the move used is a damaging attack before + * applying the effect of any inherited class. This can be changed by providing a different {@link attackCondition} to the constructor. See {@link ConfusionOnStatusEffectAbAttr} + * for an example of an effect that does not require a damaging move. + */ applyPostAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean | Promise { + // When attackRequired is true, we require the move to be an attack move and to deal damage before checking secondary requirements. + // If attackRequired is false, we always defer to the secondary requirements. + if (this.attackCondition(pokemon, defender, move)) { + return this.applyPostAttackAfterMoveTypeCheck(pokemon, passive, defender, move, hitResult, args); + } else { + return false; + } + } + + /** + * This method is only called after {@link applyPostAttack} has already been applied. Use this for handling checks specific to the ability in question. + */ + applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean | Promise { return false; } } export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr { - private condition: PokemonAttackCondition; + private stealCondition: PokemonAttackCondition; - constructor(condition?: PokemonAttackCondition) { + constructor(stealCondition?: PokemonAttackCondition) { super(); - this.condition = condition; + this.stealCondition = stealCondition; } - applyPostAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): Promise { + applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): Promise { return new Promise(resolve => { - if (hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, defender, move))) { + if (hitResult < HitResult.NO_EFFECT && (!this.stealCondition || this.stealCondition(pokemon, defender, move))) { const heldItems = this.getTargetHeldItems(defender).filter(i => i.isTransferrable); if (heldItems.length) { const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; @@ -1584,7 +1615,7 @@ export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr { this.effects = effects; } - applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { + applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { /**Status inflicted by abilities post attacking are also considered additional effects.*/ if (!attacker.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && pokemon !== attacker && (!this.contactRequired || move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance && !pokemon.status) { const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; @@ -1615,7 +1646,7 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr { this.effects = effects; } - applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { + applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { /**Battler tags inflicted by abilities post attacking are also considered additional effects.*/ if (!attacker.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && pokemon !== attacker && (!this.contactRequired || move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance(attacker, pokemon, move) && !pokemon.status) { const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; @@ -1797,7 +1828,7 @@ export class IntimidateImmunityAbAttr extends AbAttr { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { return i18next.t("abilityTriggers:intimidateImmunity", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - abilityName: abilityName, + abilityName }); } } @@ -2148,6 +2179,49 @@ export class PostSummonCopyAbilityAbAttr extends PostSummonAbAttr { } } +/** + * Removes supplied status effects from the user's field. + */ +export class PostSummonUserFieldRemoveStatusEffectAbAttr extends PostSummonAbAttr { + private statusEffect: StatusEffect[]; + + /** + * @param statusEffect - The status effects to be removed from the user's field. + */ + constructor(...statusEffect: StatusEffect[]) { + super(false); + + this.statusEffect = statusEffect; + } + + /** + * Removes supplied status effect from the user's field when user of the ability is summoned. + * + * @param pokemon - The Pokémon that triggered the ability. + * @param passive - n/a + * @param args - n/a + * @returns A boolean or a promise that resolves to a boolean indicating the result of the ability application. + */ + applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise { + const party = pokemon instanceof PlayerPokemon ? pokemon.scene.getPlayerField() : pokemon.scene.getEnemyField(); + const allowedParty = party.filter(p => p.isAllowedInBattle()); + + if (allowedParty.length < 1) { + return false; + } + + for (const pokemon of allowedParty) { + if (this.statusEffect.includes(pokemon.status?.effect)) { + pokemon.scene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon))); + pokemon.resetStatus(false); + pokemon.updateInfo(); + } + } + + return true; + } +} + /** Attempt to copy the stat changes on an ally pokemon */ export class PostSummonCopyAllyStatsAbAttr extends PostSummonAbAttr { @@ -2354,8 +2428,8 @@ export class ProtectStatAbAttr extends PreStatChangeAbAttr { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { return i18next.t("abilityTriggers:protectStat", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - abilityName: abilityName, - statName: this.protectedStat !== undefined ? getBattleStatName(this.protectedStat) : "stats", // TODO : Change "stats" to i18next.t("battle:stats") after PR#2600 merged to 'main' + abilityName, + statName: this.protectedStat !== undefined ? getBattleStatName(this.protectedStat) : i18next.t("battle:stats") }); } } @@ -2372,7 +2446,8 @@ export class ConfusionOnStatusEffectAbAttr extends PostAttackAbAttr { private effects: StatusEffect[]; constructor(...effects: StatusEffect[]) { - super(); + /** This effect does not require a damaging move */ + super((user, target, move) => true); this.effects = effects; } /** @@ -2385,7 +2460,7 @@ export class ConfusionOnStatusEffectAbAttr extends PostAttackAbAttr { * @param args [0] {@linkcode StatusEffect} applied by move * @returns true if defender is confused */ - applyPostAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { + applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { if (this.effects.indexOf(args[0]) > -1 && !defender.isFainted()) { return defender.addTag(BattlerTagType.CONFUSED, pokemon.randSeedInt(3,2), move.id, defender.id); } @@ -2399,17 +2474,33 @@ export class PreSetStatusAbAttr extends AbAttr { } } -export class StatusEffectImmunityAbAttr extends PreSetStatusAbAttr { +/** + * Provides immunity to status effects to specified targets. + */ +export class PreSetStatusEffectImmunityAbAttr extends PreSetStatusAbAttr { private immuneEffects: StatusEffect[]; + /** + * @param immuneEffects - The status effects to which the Pokémon is immune. + */ constructor(...immuneEffects: StatusEffect[]) { super(); this.immuneEffects = immuneEffects; } + /** + * Applies immunity to supplied status effects. + * + * @param pokemon - The Pokémon to which the status is being applied. + * @param passive - n/a + * @param effect - The status effect being applied. + * @param cancelled - A holder for a boolean value indicating if the status application was cancelled. + * @param args - n/a + * @returns A boolean indicating the result of the status application. + */ applyPreSetStatus(pokemon: Pokemon, passive: boolean, effect: StatusEffect, cancelled: Utils.BooleanHolder, args: any[]): boolean { - if (!this.immuneEffects.length || this.immuneEffects.indexOf(effect) > -1) { + if (this.immuneEffects.length < 1 || this.immuneEffects.includes(effect)) { cancelled.value = true; return true; } @@ -2421,24 +2512,40 @@ export class StatusEffectImmunityAbAttr extends PreSetStatusAbAttr { return this.immuneEffects.length ? i18next.t("abilityTriggers:statusEffectImmunityWithName", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - abilityName: abilityName, + abilityName, statusEffectName: getStatusEffectDescriptor(args[0] as StatusEffect) }) : i18next.t("abilityTriggers:statusEffectImmunity", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - abilityName: abilityName, + abilityName }); } } +/** + * Provides immunity to status effects to the user. + * @extends PreSetStatusEffectImmunityAbAttr + */ +export class StatusEffectImmunityAbAttr extends PreSetStatusEffectImmunityAbAttr { } + +/** + * Provides immunity to status effects to the user's field. + * @extends PreSetStatusEffectImmunityAbAttr + */ +export class UserFieldStatusEffectImmunityAbAttr extends PreSetStatusEffectImmunityAbAttr { } + export class PreApplyBattlerTagAbAttr extends AbAttr { applyPreApplyBattlerTag(pokemon: Pokemon, passive: boolean, tag: BattlerTag, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise { return false; } } -export class BattlerTagImmunityAbAttr extends PreApplyBattlerTagAbAttr { +/** + * Provides immunity to BattlerTags {@linkcode BattlerTag} to specified targets. + */ +export class PreApplyBattlerTagImmunityAbAttr extends PreApplyBattlerTagAbAttr { private immuneTagType: BattlerTagType; + private battlerTag: BattlerTag; constructor(immuneTagType: BattlerTagType) { super(); @@ -2449,6 +2556,7 @@ export class BattlerTagImmunityAbAttr extends PreApplyBattlerTagAbAttr { applyPreApplyBattlerTag(pokemon: Pokemon, passive: boolean, tag: BattlerTag, cancelled: Utils.BooleanHolder, args: any[]): boolean { if (tag.tagType === this.immuneTagType) { cancelled.value = true; + this.battlerTag = tag; return true; } @@ -2458,12 +2566,24 @@ export class BattlerTagImmunityAbAttr extends PreApplyBattlerTagAbAttr { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { return i18next.t("abilityTriggers:battlerTagImmunity", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - abilityName: abilityName, - battlerTagName: (args[0] as BattlerTag).getDescriptor() + abilityName, + battlerTagName: this.battlerTag.getDescriptor() }); } } +/** + * Provides immunity to BattlerTags {@linkcode BattlerTag} to the user. + * @extends PreApplyBattlerTagImmunityAbAttr + */ +export class BattlerTagImmunityAbAttr extends PreApplyBattlerTagImmunityAbAttr { } + +/** + * Provides immunity to BattlerTags {@linkcode BattlerTag} to the user's field. + * @extends PreApplyBattlerTagImmunityAbAttr + */ +export class UserFieldBattlerTagImmunityAbAttr extends PreApplyBattlerTagImmunityAbAttr { } + export class BlockCritAbAttr extends AbAttr { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { (args[0] as Utils.BooleanHolder).value = true; @@ -2844,7 +2964,7 @@ export class PostWeatherLapseHealAbAttr extends PostWeatherLapseAbAttr { const scene = pokemon.scene; const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name; scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.getBattlerIndex(), - Math.max(Math.floor(pokemon.getMaxHp() / (16 / this.healFactor)), 1), i18next.t("abilityTriggers:postWeatherLapseHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }), true)); + Math.max(Math.floor(pokemon.getMaxHp() / (16 / this.healFactor)), 1), i18next.t("abilityTriggers:postWeatherLapseHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true)); return true; } @@ -2863,8 +2983,11 @@ export class PostWeatherLapseDamageAbAttr extends PostWeatherLapseAbAttr { applyPostWeatherLapse(pokemon: Pokemon, passive: boolean, weather: Weather, args: any[]): boolean { const scene = pokemon.scene; + if (pokemon.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { + return false; + } const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name; - scene.queueMessage(i18next.t("abilityTriggers:postWeatherLapseDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName })); + scene.queueMessage(i18next.t("abilityTriggers:postWeatherLapseDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName })); pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / (16 / this.damageFactor)), HitResult.OTHER); return true; } @@ -2938,7 +3061,7 @@ export class PostTurnStatusHealAbAttr extends PostTurnAbAttr { const scene = pokemon.scene; const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name; scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.getBattlerIndex(), - Math.max(Math.floor(pokemon.getMaxHp() / 8), 1), i18next.t("abilityTriggers:poisonHeal", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName}), true)); + Math.max(Math.floor(pokemon.getMaxHp() / 8), 1), i18next.t("abilityTriggers:poisonHeal", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName }), true)); return true; } } @@ -3031,10 +3154,11 @@ export class PostTurnLootAbAttr extends PostTurnAbAttr { ) as BerryModifier | undefined; if (!berryModifier) { + const newBerry = new BerryModifier(chosenBerry, pokemon.id, chosenBerryType, 1); if (pokemon.isPlayer()) { - pokemon.scene.addModifier(new BerryModifier(chosenBerry, pokemon.id, chosenBerryType, 1)); + pokemon.scene.addModifier(newBerry); } else { - pokemon.scene.addEnemyModifier(new BerryModifier(chosenBerry, pokemon.id, chosenBerryType, 1)); + pokemon.scene.addEnemyModifier(newBerry); } } else if (berryModifier.stackCount < berryModifier.getMaxHeldItemCount(pokemon)) { berryModifier.stackCount++; @@ -3095,7 +3219,7 @@ export class PostTurnHealAbAttr extends PostTurnAbAttr { const scene = pokemon.scene; const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name; scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.getBattlerIndex(), - Math.max(Math.floor(pokemon.getMaxHp() / 16), 1), i18next.t("abilityTriggers:postTurnHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }), true)); + Math.max(Math.floor(pokemon.getMaxHp() / 16), 1), i18next.t("abilityTriggers:postTurnHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true)); return true; } @@ -3139,7 +3263,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr { applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise { let hadEffect: boolean = false; for (const opp of pokemon.getOpponents()) { - if (opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) { + if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { opp.damageAndUpdate(Math.floor(Math.max(1, opp.getMaxHp() / 8)), HitResult.OTHER); pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", {pokemonName: getPokemonNameWithAffix(opp)})); hadEffect = true; @@ -3347,7 +3471,7 @@ export class HealFromBerryUseAbAttr extends AbAttr { pokemon.scene, pokemon.getBattlerIndex(), Math.max(Math.floor(pokemon.getMaxHp() * this.healPercent), 1), - i18next.t("abilityTriggers:healFromBerryUse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }), + i18next.t("abilityTriggers:healFromBerryUse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true ) ); @@ -3422,7 +3546,7 @@ export class ArenaTrapAbAttr extends CheckTrappedAbAttr { } getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { - return i18next.t("abilityTriggers:arenaTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }); + return i18next.t("abilityTriggers:arenaTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }); } } @@ -3528,7 +3652,7 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr { if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { const cancelled = new Utils.BooleanHolder(false); pokemon.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled)); - if (cancelled.value) { + if (cancelled.value || attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { return false; } attacker.damageAndUpdate(Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); @@ -3540,7 +3664,7 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr { } getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { - return i18next.t("abilityTriggers:postFaintContactDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }); + return i18next.t("abilityTriggers:postFaintContactDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }); } } @@ -3560,7 +3684,7 @@ export class PostFaintHPDamageAbAttr extends PostFaintAbAttr { } getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { - return i18next.t("abilityTriggers:postFaintHpDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }); + return i18next.t("abilityTriggers:postFaintHpDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }); } } @@ -3918,7 +4042,7 @@ export class IceFaceBlockPhysicalAbAttr extends ReceivedMoveDamageMultiplierAbAt * @returns {string} - The trigger message. */ getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { - return i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName }); + return i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName }); } } @@ -3993,7 +4117,7 @@ async function applyAbAttrsInternal( pokemon.scene.setPhaseQueueSplice(); let result = applyFunc(attr, passive); - // TODO Remove this when promises get reworked PR#924 + // TODO Remove this when promises get reworked if (result instanceof Promise) { result = await result; } @@ -4184,7 +4308,7 @@ export const allAbilities = [ new Ability(Abilities.NONE, 3) ]; export function initAbilities() { allAbilities.push( new Ability(Abilities.STENCH, 3) - .attr(PostAttackApplyBattlerTagAbAttr, false, (user, target, move) => (move.category !== MoveCategory.STATUS && !move.hasAttr(FlinchAttr)) ? 10 : 0, BattlerTagType.FLINCHED), + .attr(PostAttackApplyBattlerTagAbAttr, false, (user, target, move) => !move.hasAttr(FlinchAttr) ? 10 : 0, BattlerTagType.FLINCHED), new Ability(Abilities.DRIZZLE, 3) .attr(PostSummonWeatherChangeAbAttr, WeatherType.RAIN) .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.RAIN), @@ -4719,10 +4843,10 @@ export function initAbilities() { new Ability(Abilities.REFRIGERATE, 6) .attr(MoveTypeChangeAttr, Type.ICE, 1.2, (user, target, move) => move.type === Type.NORMAL), new Ability(Abilities.SWEET_VEIL, 6) - .attr(StatusEffectImmunityAbAttr, StatusEffect.SLEEP) - .attr(BattlerTagImmunityAbAttr, BattlerTagType.DROWSY) + .attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.SLEEP) + .attr(UserFieldBattlerTagImmunityAbAttr, BattlerTagType.DROWSY) .ignorable() - .partial(), + .partial(), // Mold Breaker ally should not be affected by Sweet Veil new Ability(Abilities.STANCE_CHANGE, 6) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) @@ -4973,7 +5097,7 @@ export function initAbilities() { .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.SOUND_BASED), 0.5) .ignorable(), new Ability(Abilities.SAND_SPIT, 8) - .attr(PostDefendWeatherChangeAbAttr, WeatherType.SANDSTORM), + .attr(PostDefendWeatherChangeAbAttr, WeatherType.SANDSTORM, (target, user, move) => move.category !== MoveCategory.STATUS), new Ability(Abilities.ICE_SCALES, 8) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.category === MoveCategory.SPECIAL, 0.5) .ignorable(), @@ -5017,7 +5141,8 @@ export function initAbilities() { .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonNeutralizingGas", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })) .partial(), new Ability(Abilities.PASTEL_VEIL, 8) - .attr(StatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) + .attr(PostSummonUserFieldRemoveStatusEffectAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) + .attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) .ignorable(), new Ability(Abilities.HUNGER_SWITCH, 8) .attr(PostTurnFormChangeAbAttr, p => p.getFormKey ? 0 : 1) diff --git a/src/data/api-generator.script.ts b/src/data/api-generator.script.ts deleted file mode 100644 index f4a72a24c76..00000000000 --- a/src/data/api-generator.script.ts +++ /dev/null @@ -1,689 +0,0 @@ -import { MainClient, NamedAPIResource } from "pokenode-ts"; -import { MoveTarget, allMoves } from "./move"; -import * as Utils from "../utils"; -import fs from "vite-plugin-fs/browser"; -import PokemonSpecies, { PokemonForm, SpeciesFormKey, allSpecies } from "./pokemon-species"; -import { GrowthRate } from "./exp"; -import { Type } from "./type"; -import { allAbilities } from "./ability"; -import { pokemonFormLevelMoves } from "./pokemon-level-moves"; -import { tmSpecies } from "./tms"; -import { Abilities } from "#enums/abilities"; -import { Moves } from "#enums/moves"; -import { Species } from "#enums/species"; - -const targetMap = { - "specific-move": MoveTarget.ATTACKER, - "selected-pokemon-me-first": MoveTarget.NEAR_ENEMY, - "ally": MoveTarget.NEAR_ALLY, - "users-field": MoveTarget.USER_SIDE, - "user-or-ally": MoveTarget.USER_OR_NEAR_ALLY, - "opponents-field": MoveTarget.ENEMY_SIDE, - "user": MoveTarget.USER, - "random-opponent": MoveTarget.RANDOM_NEAR_ENEMY, - "all-other-pokemon": MoveTarget.ALL_NEAR_OTHERS, - "selected-pokemon": MoveTarget.NEAR_OTHER, - "all-opponents": MoveTarget.ALL_NEAR_ENEMIES, - "entire-field": MoveTarget.BOTH_SIDES, - "user-and-allies": MoveTarget.USER_AND_ALLIES, - "all-pokemon": MoveTarget.ALL, - "all-allies": MoveTarget.NEAR_ALLY, - "fainting-pokemon": MoveTarget.NEAR_OTHER -}; - -const generationMap = { - "generation-i": 1, - "generation-ii": 2, - "generation-iii": 3, - "generation-iv": 4, - "generation-v": 5, - "generation-vi": 6, - "generation-vii": 7, - "generation-viii": 8, - "generation-ix": 9 -}; - -const growthRateMap = { - "slow-then-very-fast": GrowthRate.ERRATIC, - "fast": GrowthRate.FAST, - "medium": GrowthRate.MEDIUM_FAST, - "medium-slow": GrowthRate.MEDIUM_SLOW, - "slow": GrowthRate.SLOW, - "fast-then-very-slow": GrowthRate.FLUCTUATING -}; - -const regionalForms = [ "alola", "galar", "hisui", "paldea" ]; - -const ignoredForms = [ "gmax", "totem", "cap", "starter" ]; - -const generationDexNumbers = { - 1: 151, - 2: 251, - 3: 386, - 4: 494, - 5: 649, - 6: 721, - 7: 809, - 8: 905, - 9: 1010 -}; - -const versions = [ "scarlet-violet", "sword-shield", "sun-moon" ]; - -type LevelMove = [level: integer, moveId: integer]; - -interface SpeciesLevelMoves { - [key: string]: LevelMove[] -} - -interface FormLevelMoves { - [key: integer]: LevelMove[] -} - -interface SpeciesFormLevelMoves { - [key: string]: FormLevelMoves -} - -interface TmSpecies { - [key: string]: Array -} - -export async function printPokemon() { - const api = new MainClient(); - - const useExistingTmList = true; - - let enumStr = "export enum Species {\n"; - let pokemonSpeciesStr = "\tallSpecies.push(\n"; - const speciesLevelMoves: SpeciesLevelMoves = {}; - const speciesFormLevelMoves: SpeciesFormLevelMoves = {}; - const moveTmSpecies: TmSpecies = {}; - - let pokemonArr: NamedAPIResource[] = []; - - const offset = 0; - const pokemonResponse = await api.pokemon.listPokemons(offset, 2000); - - pokemonArr = pokemonResponse.results; - - const types = Utils.getEnumKeys(Type).map(t => t.toLowerCase()); - const abilities = Utils.getEnumKeys(Abilities).map(a => a.toLowerCase().replace(/\_/g, "-")); - - const pokemonSpeciesList: PokemonSpecies[] = []; - - for (const p of pokemonArr) { - const pokemon = await api.pokemon.getPokemonByName(p.name); - - let region: string = ""; - - if (pokemon.id > 10000) { - const dexIdMatch = /\/(\d+)\//.exec(pokemon.species.url); - if (!dexIdMatch) { - continue; - } - - const matchingSpecies = pokemonSpeciesList[parseInt(dexIdMatch[1]) - 1]; - - if (!matchingSpecies) { - continue; - } - - const speciesKey = (matchingSpecies as any).key as string; - - const formName = pokemon.name.slice(speciesKey.length + 1); - - if (ignoredForms.filter(f => formName.indexOf(f) > -1).length) { - continue; - } - - const shortFormName = formName.indexOf("-") > -1 - ? formName.slice(0, formName.indexOf("-")) - : formName; - - if (regionalForms.indexOf(shortFormName) > -1) { - region = shortFormName.toUpperCase(); - } else { - const formBaseStats: integer[] = []; - let formBaseTotal = 0; - // Assume correct stat order in API result - for (const stat of pokemon.stats) { - formBaseStats.push(stat.base_stat); - formBaseTotal += stat.base_stat; - } - - const [ formType1, formType2 ] = [ types.indexOf(pokemon.types.find(t => t.slot === 1).type.name), types.indexOf(pokemon.types.find(t => t.slot === 2)?.type.name) ]; - const [ formAbility1, formAbility2, formAbilityHidden ] = [ - Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 1)?.ability.name), 0), - Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 2)?.ability.name), 0), - Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 3)?.ability.name), 0) - ]; - - const pokemonForm = new PokemonForm(formName, formName, formType1 as Type, formType2 > -1 ? formType2 as Type : null, pokemon.height / 10, pokemon.weight / 10, - formAbility1 as Abilities, formAbility2 as Abilities, formAbilityHidden as Abilities, formBaseTotal, formBaseStats[0], formBaseStats[1], formBaseStats[2], formBaseStats[3], formBaseStats[4], formBaseStats[5], - matchingSpecies.catchRate, matchingSpecies.baseFriendship, matchingSpecies.baseExp, matchingSpecies.genderDiffs); - pokemonForm.speciesId = matchingSpecies.speciesId; - pokemonForm.formIndex = matchingSpecies.forms.length; - pokemonForm.generation = matchingSpecies.generation; - - let moveVer: string; - - if (!speciesFormLevelMoves.hasOwnProperty(speciesKey)) { - speciesFormLevelMoves[speciesKey] = []; - } - speciesFormLevelMoves[speciesKey][pokemonForm.formIndex] = []; - - for (const version of versions) { - if (pokemon.moves.find(m => m.version_group_details.find(v => v.version_group.name === version && v.move_learn_method.name === "level-up"))) { - moveVer = version; - break; - } - } - - if (moveVer) { - pokemon.moves.forEach(moveData => { - moveData.version_group_details.filter(v => versions.indexOf(v.version_group.name) > -1).forEach(verData => { - const isMoveVer = verData.version_group.name === moveVer; - - const moveName = moveData.move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_"); - const moveId = Math.max(Utils.getEnumKeys(Moves).indexOf(moveName), 0); - - const learnMethod = verData.move_learn_method.name; - - if (isMoveVer && learnMethod === "level-up") { - speciesFormLevelMoves[speciesKey][pokemonForm.formIndex].push([ verData.level_learned_at, moveId ]); - } - - if ([ "machine", "tutor" ].indexOf(learnMethod) > -1 || (useExistingTmList && tmSpecies.hasOwnProperty(moveId as Moves) && learnMethod === "level-up")) { - if (!moveTmSpecies.hasOwnProperty(moveId)) { - moveTmSpecies[moveId] = []; - } - const speciesIndex = moveTmSpecies[moveId].findIndex(s => s[0] === speciesKey); - if (speciesIndex === -1) { - moveTmSpecies[moveId].push([ speciesKey, formName ]); - } else { - (moveTmSpecies[moveId][speciesIndex] as string[]).push(formName); - } - } - }); - }); - - if (JSON.stringify(speciesLevelMoves[speciesKey]) === JSON.stringify(speciesFormLevelMoves[speciesKey][pokemonForm.formIndex])) { - delete speciesFormLevelMoves[speciesKey][pokemonForm.formIndex]; - if (!Object.keys(speciesFormLevelMoves[speciesKey]).length) { - delete speciesFormLevelMoves[speciesKey]; - } - } - } - - matchingSpecies.forms.push(pokemonForm); - continue; - } - } - - const species = await api.pokemon.getPokemonSpeciesByName(pokemon.species.name); - - let speciesKey = species.name.toUpperCase().replace(/\-/g, "_"); - - const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === speciesKey); - - let dexId = species.id; - - if (region) { - dexId += (regionalForms.indexOf(region.toLowerCase()) + 1) * 2000; - speciesKey = `${region}_${speciesKey}`; - } - - let generationIndex = 0; - - if (!region) { - while (++generationIndex < 9 && dexId > generationDexNumbers[generationIndex]) {} - } else { - generationIndex = regionalForms.indexOf(region.toLowerCase()) + 6; - } - - const baseStats: integer[] = []; - let baseTotal = 0; - // Assume correct stat order in API result - for (const stat of pokemon.stats) { - baseStats.push(stat.base_stat); - baseTotal += stat.base_stat; - } - - console.log(pokemon); - - const [ type1, type2 ] = [ types.indexOf(pokemon.types.find(t => t.slot === 1).type.name), types.indexOf(pokemon.types.find(t => t.slot === 2)?.type.name) ]; - const [ ability1, ability2, abilityHidden ] = [ - Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 1)?.ability.name), 0), - Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 2)?.ability.name), 0), - Math.max(abilities.indexOf(pokemon.abilities.find(a => a.slot === 3)?.ability.name), 0) - ]; - - const pokemonSpecies = new PokemonSpecies(dexId, generationIndex, species.is_legendary && baseTotal < 660, species.is_legendary && baseTotal >= 660, species.is_mythical, - species.genera.find(g => g.language.name === "en")?.genus, type1 as Type, type2 > -1 ? type2 as Type : null, pokemon.height / 10, pokemon.weight / 10, ability1 as Abilities, ability2 as Abilities, abilityHidden as Abilities, - baseTotal, baseStats[0], baseStats[1], baseStats[2], baseStats[3], baseStats[4], baseStats[5], species.capture_rate, species.base_happiness, pokemon.base_experience, growthRateMap[species.growth_rate.name], - species.gender_rate < 9 ? 100 - (species.gender_rate * 12.5) : null, species.has_gender_differences, species.forms_switchable); - - (pokemonSpecies as any).key = speciesKey; - - pokemonSpeciesList.push(pokemonSpecies); - - let moveVer: string; - - speciesLevelMoves[speciesKey] = []; - - for (const version of versions) { - if (pokemon.moves.find(m => m.version_group_details.find(v => v.version_group.name === version && v.move_learn_method.name === "level-up"))) { - moveVer = version; - break; - } - } - - const speciesTmMoves: integer[] = []; - - if (moveVer) { - pokemon.moves.forEach(moveData => { - const verData = moveData.version_group_details.find(v => v.version_group.name === moveVer); - if (!verData) { - return; - } - - const moveName = moveData.move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_"); - const moveId = Math.max(Utils.getEnumKeys(Moves).indexOf(moveName), 0); - - switch (verData.move_learn_method.name) { - case "level-up": - speciesLevelMoves[speciesKey].push([ verData.level_learned_at, moveId ]); - break; - case "machine": - case "tutor": - if (moveId > 0) { - if (!moveTmSpecies.hasOwnProperty(moveId)) { - moveTmSpecies[moveId] = []; - } - if (moveTmSpecies[moveId].indexOf(speciesKey) === -1) { - moveTmSpecies[moveId].push(speciesKey); - } - speciesTmMoves.push(moveId); - } - break; - } - }); - } - - for (const f of pokemon.forms) { - const form = await api.pokemon.getPokemonFormByName(f.name); - const formIndex = pokemonSpecies.forms.length; - - const matchingForm = matchingExistingSpecies && matchingExistingSpecies.forms.length > formIndex - ? matchingExistingSpecies.forms.find(f2 => f2.formKey === form.form_name || f2.formName === form.form_name) || matchingExistingSpecies.forms[formIndex] - : null; - const formName = matchingForm - ? matchingForm.formName - : form.form_names.find(fn => fn.language.name === "en")?.name || form.form_name; - const formKey = matchingForm - ? matchingForm.formKey - : form.form_name; - - const [ formType1, formType2 ] = [ types.indexOf(form.types.find(t => t.slot === 1).type.name), types.indexOf(form.types.find(t => t.slot === 2)?.type.name) ]; - const pokemonForm = new PokemonForm(formName, formKey, formType1 as Type, formType2 > -1 ? formType2 as Type : null, - pokemonSpecies.height, pokemonSpecies.weight, pokemonSpecies.ability1, pokemonSpecies.ability2, pokemonSpecies.abilityHidden, baseTotal, baseStats[0], baseStats[1], baseStats[2], baseStats[3], baseStats[4], baseStats[5], - pokemonSpecies.catchRate, pokemonSpecies.baseFriendship, pokemonSpecies.baseExp, pokemonSpecies.genderDiffs); - pokemonForm.speciesId = pokemonSpecies.speciesId; - pokemonForm.formIndex = formIndex; - pokemonForm.generation = pokemonSpecies.generation; - - if (!pokemonForm.formIndex && speciesTmMoves.length) { - for (const moveId of speciesTmMoves) { - const speciesIndex = moveTmSpecies[moveId].findIndex(s => s === speciesKey); - moveTmSpecies[moveId][speciesIndex] = [ - speciesKey, - formKey - ]; - } - } - - pokemonSpecies.forms.push(pokemonForm); - } - - console.log(pokemonSpecies.name, pokemonSpecies); - } - - for (const pokemonSpecies of pokemonSpeciesList) { - const speciesKey = (pokemonSpecies as any).key as string; - - enumStr += ` ${speciesKey}${pokemonSpecies.speciesId >= 2000 ? ` = ${pokemonSpecies.speciesId}` : ""},\n`; - pokemonSpeciesStr += ` new PokemonSpecies(Species.${speciesKey}, "${pokemonSpecies.name}", ${pokemonSpecies.generation}, ${pokemonSpecies.subLegendary}, ${pokemonSpecies.legendary}, ${pokemonSpecies.mythical}, "${pokemonSpecies.species}", Type.${Type[pokemonSpecies.type1]}, ${pokemonSpecies.type2 ? `Type.${Type[pokemonSpecies.type2]}` : "null"}, ${pokemonSpecies.height}, ${pokemonSpecies.weight}, Abilities.${Abilities[pokemonSpecies.ability1]}, Abilities.${Abilities[pokemonSpecies.ability2]}, Abilities.${Abilities[pokemonSpecies.abilityHidden]}, ${pokemonSpecies.baseTotal}, ${pokemonSpecies.baseStats[0]}, ${pokemonSpecies.baseStats[1]}, ${pokemonSpecies.baseStats[2]}, ${pokemonSpecies.baseStats[3]}, ${pokemonSpecies.baseStats[4]}, ${pokemonSpecies.baseStats[5]}, ${pokemonSpecies.catchRate}, ${pokemonSpecies.baseFriendship}, ${pokemonSpecies.baseExp}, GrowthRate.${GrowthRate[pokemonSpecies.growthRate]}, ${pokemonSpecies.malePercent}, ${pokemonSpecies.genderDiffs}`; - if (pokemonSpecies.forms.length > 1) { - pokemonSpeciesStr += `, ${pokemonSpecies.canChangeForm},`; - for (const form of pokemonSpecies.forms) { - pokemonSpeciesStr += `\n new PokemonForm("${form.formName}", "${form.formName}", Type.${Type[form.type1]}, ${form.type2 ? `Type.${Type[form.type2]}` : "null"}, ${form.height}, ${form.weight}, Abilities.${Abilities[form.ability1]}, Abilities.${Abilities[form.ability2]}, Abilities.${Abilities[form.abilityHidden]}, ${form.baseTotal}, ${form.baseStats[0]}, ${form.baseStats[1]}, ${form.baseStats[2]}, ${form.baseStats[3]}, ${form.baseStats[4]}, ${form.baseStats[5]}, ${form.catchRate}, ${form.baseFriendship}, ${form.baseExp}${form.genderDiffs ? ", true" : ""}),`; - } - pokemonSpeciesStr += "\n "; - } - pokemonSpeciesStr += "),\n"; - } - - let speciesLevelMovesStr = "export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {\n"; - let speciesFormLevelMovesStr = "export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {\n"; - let tmSpeciesStr = "export const tmSpecies: TmSpecies = {\n"; - - for (const species of Object.keys(speciesLevelMoves)) { - speciesLevelMovesStr += ` [Species.${species}]: [\n`; - - const orderedLevelMoves = speciesLevelMoves[species].sort((a: LevelMove, b: LevelMove) => { - if (a[0] !== b[0]) { - return a[0] < b[0] ? -1 : 1; - } - return a[1] < b[1] ? -1 : 1; - }); - - for (const lm of orderedLevelMoves) { - speciesLevelMovesStr += ` [ ${lm[0]}, Moves.${Moves[lm[1]]} ],\n`; - } - - speciesLevelMovesStr += " ],\n"; - } - - for (const species of Object.keys(speciesFormLevelMoves)) { - speciesFormLevelMovesStr += ` [Species.${species}]: {\n`; - - for (const f of Object.keys(speciesFormLevelMoves[species])) { - speciesFormLevelMovesStr += ` ${f}: [\n`; - - const orderedLevelMoves = speciesFormLevelMoves[species][f].sort((a: LevelMove, b: LevelMove) => { - if (a[0] !== b[0]) { - return a[0] < b[0] ? -1 : 1; - } - return a[1] < b[1] ? -1 : 1; - }); - - for (const lm of orderedLevelMoves) { - speciesFormLevelMovesStr += ` [ ${lm[0]}, Moves.${Moves[lm[1]]} ],\n`; - } - - speciesFormLevelMovesStr += " ],\n"; - } - - speciesFormLevelMovesStr += " },\n"; - } - - for (const moveId of Object.keys(moveTmSpecies)) { - tmSpeciesStr += ` [Moves.${Moves[parseInt(moveId)]}]: [\n`; - for (const species of moveTmSpecies[moveId]) { - if (typeof species === "string") { - tmSpeciesStr += ` Species.${species},\n`; - } else { - const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === species[0]); - const forms = (species as string[]).slice(1); - if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length)) { - tmSpeciesStr += ` Species.${species[0]},\n`; - } else { - tmSpeciesStr += ` [\n Species.${species[0]},\n`; - for (const form of forms) { - tmSpeciesStr += ` '${form}',\n`; - } - tmSpeciesStr += " ],\n"; - } - } - } - tmSpeciesStr += " ],\n"; - } - - enumStr += "\n};"; - pokemonSpeciesStr += " );"; - speciesLevelMovesStr += "\n};"; - speciesFormLevelMovesStr += "\n};"; - tmSpeciesStr += "\n};"; - - console.log(enumStr); - console.log(pokemonSpeciesStr); - console.log(speciesLevelMovesStr); - console.log(speciesFormLevelMovesStr); - console.log(tmSpeciesStr); - - console.log(moveTmSpecies); -} - -export async function printAbilities() { - const replaceText = true; - - let abilityContent: string = await fs.readFile("./src/data/ability.ts"); - - const api = new MainClient(); - - let enumStr = "export enum Abilities {\n NONE,"; - let abilityStr = " allAbilities.push("; - - abilityContent = abilityContent.slice(abilityContent.indexOf(abilityStr)); - - let abilities: NamedAPIResource[] = []; - const offset = 0; - const abilitiesResponse = await api.pokemon.listAbilities(offset, 2000); - abilities = abilitiesResponse.results; - - for (const a of abilities) { - const ability = await api.pokemon.getAbilityByName(a.name); - const abilityEnumName = ability.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_"); - enumStr += `\n ${abilityEnumName},`; - console.log(ability.name, ability); - - const matchingLineIndex = abilityContent.search(new RegExp(`new Ability\\\(Abilities.${abilityEnumName},`)); - let matchingLine = matchingLineIndex > -1 ? abilityContent.slice(matchingLineIndex) : null; - if (matchingLine) { - matchingLine = matchingLine.slice(0, matchingLine.search(/,(?: \/\/.*?)?(?:\r)?\n[ \t]+(?:new|\);)/)); - } - - let abilityName = ability.names.find(ln => ln.language.name === "en").name; - [ "N", "P" ].every(s => { - if (!matchingLine || matchingLine.indexOf(` (${s})`) > -1) { - abilityName += ` (${s})`; - return false; - } - return true; - }); - - let flavorText: string; - if (!matchingLine || replaceText) { - for (const version of versions) { - if ((flavorText = ability.flavor_text_entries.find(fte => fte.language.name === "en" && fte.version_group.name === version)?.flavor_text) || "") { - if (flavorText.indexOf("forgotten") > -1) { - continue; - } - break; - } - } - } else if (matchingLine) { - flavorText = allAbilities[ability.id].description; - } - abilityStr += `\n new Ability(Abilities.${abilityEnumName}, "${abilityName}", "${flavorText?.replace(/\n/g, "\\n").replace(/ /g, " ").replace(/’/g, "'") || ""}", ${generationMap[ability.generation.name]})`; - if (matchingLine && matchingLine.length > 1) { - const newLineIndex = matchingLine.indexOf("\n"); - if (newLineIndex > -1) { - abilityStr += matchingLine.slice(newLineIndex); - } - } - abilityStr += ","; - } - - enumStr += "\n};"; - abilityStr += "\n);"; - - console.log(enumStr); - console.log(abilityStr); -} - -export async function printMoves() { - const replaceText = true; - - let moveContent: string = await fs.readFile("./src/data/move.ts"); - - const api = new MainClient(); - - let enumStr = "export enum Moves {\n NONE,"; - let moveStr = " allMoves.push("; - - moveContent = moveContent.slice(moveContent.indexOf(moveStr)); - - let moves: NamedAPIResource[] = []; - const offset = 0; - const movesResponse = await api.move.listMoves(offset, 2000); - moves = movesResponse.results; - - console.log(moves); - - for (const m of moves) { - const move = await api.move.getMoveByName(m.name); - const moveEnumName = move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_"); - enumStr += `\n ${moveEnumName},`; - console.log(move.name, move); - - const matchingLineIndex = moveContent.search(new RegExp(`new (?:Attack|(?:Self)?Status)Move\\\(Moves.${Moves[move.id]},`)); - let matchingLine = matchingLineIndex > -1 ? moveContent.slice(matchingLineIndex) : null; - if (matchingLine) { - matchingLine = matchingLine.slice(0, matchingLine.search(/,(?: \/\/.*?)?(?:\r)?\n[ \t]+(?:new|\);)/)); - } - - let moveName = move.names.find(ln => ln.language.name === "en").name; - [ "N", "P" ].every(s => { - if (!matchingLine || matchingLine.indexOf(` (${s})`) > -1) { - moveName += ` (${s})`; - return false; - } - return true; - }); - - let flavorText: string; - if (!matchingLine || replaceText) { - for (const version of versions) { - if ((flavorText = move.flavor_text_entries.find(fte => fte.language.name === "en" && fte.version_group.name === version)?.flavor_text) || "") { - if (flavorText.indexOf("forgotten") > -1) { - continue; - } - break; - } - } - } else if (matchingLine) { - flavorText = allMoves[move.id].effect; - } - const moveTarget = targetMap[move.target.name]; - moveStr += `\n new ${move.damage_class.name !== "status" ? "Attack" : (moveTarget === MoveTarget.USER ? "Self" : "") + "Status"}Move(Moves.${moveEnumName}, "${moveName}", Type.${move.type.name.toUpperCase()}${move.damage_class.name !== "status" ? `, MoveCategory.${move.damage_class.name.toUpperCase()}` : ""}${move.damage_class.name !== "status" ? `, ${move.power || -1}` : ""}, ${move.accuracy || -1}, ${move.pp}, "${flavorText?.replace(/\n/g, "\\n").replace(/ /g, " ").replace(/’/g, "'") || ""}", ${move.effect_chance || -1}, ${move.priority}, ${generationMap[move.generation.name]})`; - const expectedTarget = move.damage_class.name !== "status" || moveTarget !== MoveTarget.USER ? MoveTarget.NEAR_OTHER : MoveTarget.USER; - if (matchingLine && matchingLine.length > 1) { - const newLineIndex = matchingLine.indexOf("\n"); - if (newLineIndex > -1) { - console.log(matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, ""), newLineIndex); - moveStr += matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, ""); - } - } - if (moveTarget !== expectedTarget) { - moveStr += `\n .target(MoveTarget.${MoveTarget[moveTarget]})`; - } - moveStr += ","; - } - - enumStr += "\n};"; - moveStr += "\n);"; - - console.log(enumStr); - console.log(moveStr); -} - -export async function printTmSpecies() { - const moveTmSpecies: TmSpecies = {}; - - const api = new MainClient(); - - const moveIds = Object.keys(tmSpecies).map(k => parseInt(k) as Moves); - - for (const moveId of moveIds) { - const move = await api.move.getMoveById(moveId); - - moveTmSpecies[moveId] = []; - - for (const species of move.learned_by_pokemon) { - const dexIdMatch = /\/(\d+)\//.exec(species.url); - if (!dexIdMatch) { - continue; - } - - const dexId = parseInt(dexIdMatch[1]); - - let matchingSpecies: PokemonSpecies; - let formKey = ""; - - console.log(species.name); - - if (dexId < 10000) { - matchingSpecies = allSpecies[dexId - 1]; - } else { - const pokemon = await api.pokemon.getPokemonById(dexId); - - const speciesDexIdMatch = /\/(\d+)\//.exec(pokemon.species.url); - if (!speciesDexIdMatch) { - continue; - } - - const speciesDexId = parseInt(speciesDexIdMatch[1]); - - const speciesKey = Species[allSpecies[speciesDexId - 1].speciesId]; - - formKey = species.name.slice(speciesKey.length + 1); - - const regionKey = regionalForms.find(r => formKey.indexOf(r) > -1); - - if (regionKey) { - formKey = formKey.slice(regionKey.length + 1); - matchingSpecies = allSpecies.find(s => Species[s.speciesId] === `${regionKey.toUpperCase()}_${speciesKey}`); - } else { - matchingSpecies = allSpecies[speciesDexId - 1]; - } - } - - if (!matchingSpecies) { - console.log("NO MATCH", species.name); - continue; - } - - const speciesKey = Species[matchingSpecies.speciesId]; - - const matchingIndex = moveTmSpecies[moveId].findIndex(s => Array.isArray(s) ? s[0] === speciesKey : s === speciesKey); - - if (matchingIndex === -1) { - moveTmSpecies[moveId].push(!formKey ? speciesKey : [ speciesKey, formKey ]); - } else { - if (!Array.isArray(moveTmSpecies[moveId][matchingIndex])) { - moveTmSpecies[moveId][matchingIndex] = [ moveTmSpecies[moveId][matchingIndex] as string, "" ]; - } - (moveTmSpecies[moveId][matchingIndex] as string[]).push(formKey); - } - } - } - - let tmSpeciesStr = "export const tmSpecies: TmSpecies = {\n"; - - for (const moveId of Object.keys(moveTmSpecies)) { - tmSpeciesStr += ` [Moves.${Moves[parseInt(moveId)]}]: [\n`; - for (const species of moveTmSpecies[moveId]) { - if (typeof species === "string") { - tmSpeciesStr += ` Species.${species},\n`; - } else { - const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === species[0]); - const forms = (species as string[]).slice(1); - if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length)) { - tmSpeciesStr += ` Species.${species[0]},\n`; - } else { - tmSpeciesStr += ` [\n Species.${species[0]},\n`; - for (const form of forms) { - tmSpeciesStr += ` '${form}',\n`; - } - tmSpeciesStr += " ],\n"; - } - } - } - tmSpeciesStr += " ],\n"; - } - - tmSpeciesStr += "\n};"; - - console.log(tmSpeciesStr); -} diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index d678f36c802..fd72ab21026 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -2,7 +2,7 @@ import { Arena } from "../field/arena"; import { Type } from "./type"; import * as Utils from "../utils"; import { MoveCategory, allMoves, MoveTarget } from "./move"; -import { getPokemonMessage, getPokemonNameWithAffix } from "../messages"; +import { getPokemonNameWithAffix } from "../messages"; import Pokemon, { HitResult, PokemonMove } from "../field/pokemon"; import { MoveEffectPhase, PokemonHealPhase, ShowAbilityPhase, StatChangePhase } from "../phases"; import { StatusEffect } from "./status-effect"; @@ -46,7 +46,7 @@ export abstract class ArenaTag { onRemove(arena: Arena, quiet: boolean = false): void { if (!quiet) { - arena.scene.queueMessage(`${this.getMoveName()}\'s effect wore off${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`); + arena.scene.queueMessage(i18next.t(`arenaTag:arenaOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`, { moveName: this.getMoveName() })); } } @@ -77,14 +77,14 @@ export class MistTag extends ArenaTag { const source = arena.scene.getPokemonById(this.sourceId); if (!quiet) { - arena.scene.queueMessage(getPokemonMessage(source, "'s team became\nshrouded in mist!")); + arena.scene.queueMessage(i18next.t("arenaTag:mistOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) })); } } apply(arena: Arena, args: any[]): boolean { (args[0] as Utils.BooleanHolder).value = true; - arena.scene.queueMessage("The mist prevented\nthe lowering of stats!"); + arena.scene.queueMessage(i18next.t("arenaTag:mistApply")); return true; } @@ -144,7 +144,7 @@ class ReflectTag extends WeakenMoveScreenTag { onAdd(arena: Arena, quiet: boolean = false): void { if (!quiet) { - arena.scene.queueMessage(`Reflect reduced the damage of physical moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`); + arena.scene.queueMessage(i18next.t(`arenaTag:reflectOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`)); } } } @@ -160,7 +160,7 @@ class LightScreenTag extends WeakenMoveScreenTag { onAdd(arena: Arena, quiet: boolean = false): void { if (!quiet) { - arena.scene.queueMessage(`Light Screen reduced the damage of special moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`); + arena.scene.queueMessage(i18next.t(`arenaTag:lightScreenOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`)); } } } @@ -176,7 +176,7 @@ class AuroraVeilTag extends WeakenMoveScreenTag { onAdd(arena: Arena, quiet: boolean = false): void { if (!quiet) { - arena.scene.queueMessage(`Aurora Veil reduced the damage of moves${this.side === ArenaTagSide.PLAYER ? "\non your side" : this.side === ArenaTagSide.ENEMY ? "\non the foe's side" : ""}.`); + arena.scene.queueMessage(i18next.t(`arenaTag:auroraVeilOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`)); } } } @@ -198,7 +198,7 @@ abstract class ConditionalProtectTag extends ArenaTag { } onAdd(arena: Arena): void { - arena.scene.queueMessage(`${super.getMoveName()} protected${this.side === ArenaTagSide.PLAYER ? " your" : this.side === ArenaTagSide.ENEMY ? " the\nopposing" : ""} team!`); + arena.scene.queueMessage(i18next.t(`arenaTag:conditionalProtectOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`, { moveName: super.getMoveName() })); } // Removes default message for effect removal @@ -223,7 +223,7 @@ abstract class ConditionalProtectTag extends ArenaTag { && this.protectConditionFunc(...args.slice(2))) { (args[0] as Utils.BooleanHolder).value = true; new CommonBattleAnim(CommonAnim.PROTECT, target).play(arena.scene); - arena.scene.queueMessage(`${super.getMoveName()} protected ${getPokemonMessage(target, "!")}`); + arena.scene.queueMessage(i18next.t("arenaTag:conditionalProtectApply", { moveName: super.getMoveName(), pokemonNameWithAffix: getPokemonNameWithAffix(target) })); return true; } return false; @@ -281,7 +281,7 @@ class MatBlockTag extends ConditionalProtectTag { onAdd(arena: Arena) { const source = arena.scene.getPokemonById(this.sourceId); - arena.scene.queueMessage(getPokemonMessage(source, " intends to flip up a mat\nand block incoming attacks!")); + arena.scene.queueMessage(i18next.t("arenaTag:matBlockOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) })); } } @@ -319,7 +319,7 @@ class WishTag extends ArenaTag { onAdd(arena: Arena): void { const user = arena.scene.getPokemonById(this.sourceId); this.battlerIndex = user.getBattlerIndex(); - this.triggerMessage = getPokemonMessage(user, "'s wish\ncame true!"); + this.triggerMessage = i18next.t("arenaTag:wishTagOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(user) }); this.healHp = Math.max(Math.floor(user.getMaxHp() / 2), 1); } @@ -373,11 +373,11 @@ class MudSportTag extends WeakenMoveTypeTag { } onAdd(arena: Arena): void { - arena.scene.queueMessage("Electricity's power was weakened!"); + arena.scene.queueMessage(i18next.t("arenaTag:mudSportOnAdd")); } onRemove(arena: Arena): void { - arena.scene.queueMessage("The effects of Mud Sport\nhave faded."); + arena.scene.queueMessage(i18next.t("arenaTag:mudSportOnRemove")); } } @@ -391,11 +391,11 @@ class WaterSportTag extends WeakenMoveTypeTag { } onAdd(arena: Arena): void { - arena.scene.queueMessage("Fire's power was weakened!"); + arena.scene.queueMessage(i18next.t("arenaTag:waterSportOnAdd")); } onRemove(arena: Arena): void { - arena.scene.queueMessage("The effects of Water Sport\nhave faded."); + arena.scene.queueMessage(i18next.t("arenaTag:waterSportOnRemove")); } } @@ -463,7 +463,7 @@ class SpikesTag extends ArenaTrapTag { const source = arena.scene.getPokemonById(this.sourceId); if (!quiet) { - arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${source.getOpponentDescriptor()}'s feet!`); + arena.scene.queueMessage(i18next.t("arenaTag:spikesOnAdd", { moveName: this.getMoveName(), opponentDesc: source.getOpponentDescriptor() })); } } @@ -476,7 +476,7 @@ class SpikesTag extends ArenaTrapTag { const damageHpRatio = 1 / (10 - 2 * this.layers); const damage = Math.ceil(pokemon.getMaxHp() * damageHpRatio); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is hurt\nby the spikes!")); + pokemon.scene.queueMessage(i18next.t("arenaTag:spikesActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.damageAndUpdate(damage, HitResult.OTHER); if (pokemon.turnData) { pokemon.turnData.damageTaken += damage; @@ -508,7 +508,7 @@ class ToxicSpikesTag extends ArenaTrapTag { const source = arena.scene.getPokemonById(this.sourceId); if (!quiet) { - arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${source.getOpponentDescriptor()}'s feet!`); + arena.scene.queueMessage(i18next.t("arenaTag:toxicSpikesOnAdd", { moveName: this.getMoveName(), opponentDesc: source.getOpponentDescriptor() })); } } @@ -523,12 +523,12 @@ class ToxicSpikesTag extends ArenaTrapTag { if (pokemon.isOfType(Type.POISON)) { this.neutralized = true; if (pokemon.scene.arena.removeTag(this.tagType)) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` absorbed the ${this.getMoveName()}!`)); + pokemon.scene.queueMessage(i18next.t("arenaTag:toxicSpikesActivateTrapPoison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: this.getMoveName() })); return true; } } else if (!pokemon.status) { const toxic = this.layers > 1; - if (pokemon.trySetStatus(!toxic ? StatusEffect.POISON : StatusEffect.TOXIC, true, null, 0, `the ${this.getMoveName()}`)) { + if (pokemon.trySetStatus(!toxic ? StatusEffect.POISON : StatusEffect.TOXIC, true, null, 0, this.getMoveName())) { return true; } } @@ -590,7 +590,7 @@ class StealthRockTag extends ArenaTrapTag { const source = arena.scene.getPokemonById(this.sourceId); if (!quiet) { - arena.scene.queueMessage(`Pointed stones float in the air\naround ${source.getOpponentDescriptor()}!`); + arena.scene.queueMessage(i18next.t("arenaTag:stealthRockOnAdd", { opponentDesc: source.getOpponentDescriptor() })); } } @@ -635,7 +635,7 @@ class StealthRockTag extends ArenaTrapTag { if (damageHpRatio) { const damage = Math.ceil(pokemon.getMaxHp() * damageHpRatio); - pokemon.scene.queueMessage(`Pointed stones dug into\n${getPokemonNameWithAffix(pokemon)}!`); + pokemon.scene.queueMessage(i18next.t("arenaTag:stealthRockActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.damageAndUpdate(damage, HitResult.OTHER); if (pokemon.turnData) { pokemon.turnData.damageTaken += damage; @@ -663,12 +663,9 @@ class StickyWebTag extends ArenaTrapTag { onAdd(arena: Arena, quiet: boolean = false): void { super.onAdd(arena); - - // does not seem to be used anywhere - // eslint-disable-next-line @typescript-eslint/no-unused-vars const source = arena.scene.getPokemonById(this.sourceId); if (!quiet) { - arena.scene.queueMessage(`A ${this.getMoveName()} has been laid out on the ground around the opposing team!`); + arena.scene.queueMessage(i18next.t("arenaTag:stickyWebOnAdd", { moveName: this.getMoveName(), opponentDesc: source.getOpponentDescriptor() })); } } @@ -677,7 +674,7 @@ class StickyWebTag extends ArenaTrapTag { const cancelled = new Utils.BooleanHolder(false); applyAbAttrs(ProtectStatAbAttr, pokemon, cancelled); if (!cancelled.value) { - pokemon.scene.queueMessage(`The opposing ${pokemon.getNameToRender()} was caught in a sticky web!`); + pokemon.scene.queueMessage(i18next.t("arenaTag:stickyWebActivateTrap", { pokemonName: pokemon.getNameToRender() })); const statLevels = new Utils.NumberHolder(-1); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [BattleStat.SPD], statLevels.value)); } @@ -705,11 +702,11 @@ export class TrickRoomTag extends ArenaTag { } onAdd(arena: Arena): void { - arena.scene.queueMessage(getPokemonMessage(arena.scene.getPokemonById(this.sourceId), " twisted\nthe dimensions!")); + arena.scene.queueMessage(i18next.t("arenaTag:trickRoomOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(arena.scene.getPokemonById(this.sourceId)) })); } onRemove(arena: Arena): void { - arena.scene.queueMessage("The twisted dimensions\nreturned to normal!"); + arena.scene.queueMessage(i18next.t("arenaTag:trickRoomOnRemove")); } } @@ -724,7 +721,7 @@ export class GravityTag extends ArenaTag { } onAdd(arena: Arena): void { - arena.scene.queueMessage("Gravity intensified!"); + arena.scene.queueMessage(i18next.t("arenaTag:gravityOnAdd")); arena.scene.getField(true).forEach((pokemon) => { if (pokemon !== null) { pokemon.removeTag(BattlerTagType.MAGNET_RISEN); @@ -733,7 +730,7 @@ export class GravityTag extends ArenaTag { } onRemove(arena: Arena): void { - arena.scene.queueMessage("Gravity returned to normal!"); + arena.scene.queueMessage(i18next.t("arenaTag:gravityOnRemove")); } } @@ -749,7 +746,7 @@ class TailwindTag extends ArenaTag { onAdd(arena: Arena, quiet: boolean = false): void { if (!quiet) { - arena.scene.queueMessage(`The Tailwind blew from behind${this.side === ArenaTagSide.PLAYER ? "\nyour" : this.side === ArenaTagSide.ENEMY ? "\nthe opposing" : ""} team!`); + arena.scene.queueMessage(i18next.t(`arenaTag:tailwindOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`)); } const source = arena.scene.getPokemonById(this.sourceId); @@ -771,7 +768,7 @@ class TailwindTag extends ArenaTag { onRemove(arena: Arena, quiet: boolean = false): void { if (!quiet) { - arena.scene.queueMessage(`${this.side === ArenaTagSide.PLAYER ? "Your" : this.side === ArenaTagSide.ENEMY ? "The opposing" : ""} team's Tailwind petered out!`); + arena.scene.queueMessage(i18next.t(`arenaTag:tailwindOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`)); } } } @@ -786,11 +783,11 @@ class HappyHourTag extends ArenaTag { } onAdd(arena: Arena): void { - arena.scene.queueMessage("Everyone is caught up in the happy atmosphere!"); + arena.scene.queueMessage(i18next.t("arenaTag:happyHourOnAdd")); } onRemove(arena: Arena): void { - arena.scene.queueMessage("The atmosphere returned to normal."); + arena.scene.queueMessage(i18next.t("arenaTag:happyHourOnRemove")); } } diff --git a/src/data/battle-stat.ts b/src/data/battle-stat.ts index 47f52b46d94..d70e6655f8c 100644 --- a/src/data/battle-stat.ts +++ b/src/data/battle-stat.ts @@ -1,4 +1,4 @@ -import i18next, {ParseKeys} from "i18next"; +import i18next, { ParseKeys } from "i18next"; export enum BattleStat { ATK, @@ -32,7 +32,7 @@ export function getBattleStatName(stat: BattleStat) { } } -export function getBattleStatLevelChangeDescription(pokemonNameWithAffix: string, stats: string, levels: integer, up: boolean, count: integer = 1) { +export function getBattleStatLevelChangeDescription(pokemonNameWithAffix: string, stats: string, levels: integer, up: boolean, count: number = 1) { const stringKey = (() => { if (up) { switch (levels) { diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 2755fd0bbbe..94df265ff5e 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -31,14 +31,14 @@ export enum BattlerTagLapseType { export class BattlerTag { public tagType: BattlerTagType; - public lapseType: BattlerTagLapseType[]; + public lapseTypes: BattlerTagLapseType[]; public turnCount: number; public sourceMove: Moves; public sourceId?: number; constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType | BattlerTagLapseType[], turnCount: number, sourceMove: Moves, sourceId?: number) { this.tagType = tagType; - this.lapseType = typeof lapseType === "number" ? [ lapseType ] : lapseType; + this.lapseTypes = Array.isArray(lapseType) ? lapseType : [ lapseType ]; this.turnCount = turnCount; this.sourceMove = sourceMove; this.sourceId = sourceId; @@ -497,12 +497,6 @@ export class FrenzyTag extends BattlerTag { } } -export class ChargingTag extends BattlerTag { - constructor(sourceMove: Moves, sourceId: number) { - super(BattlerTagType.CHARGING, BattlerTagLapseType.CUSTOM, 1, sourceMove, sourceId); - } -} - export class EncoreTag extends BattlerTag { public moveId: Moves; @@ -650,8 +644,7 @@ export class OctolockTag extends TrappedTag { } canAdd(pokemon: Pokemon): boolean { - const isOctolocked = pokemon.getTag(BattlerTagType.OCTOLOCK); - return !isOctolocked; + return !pokemon.getTag(BattlerTagType.OCTOLOCK); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -1414,30 +1407,6 @@ export class CritBoostTag extends BattlerTag { } } -export class AlwaysCritTag extends BattlerTag { - constructor(sourceMove: Moves) { - super(BattlerTagType.ALWAYS_CRIT, BattlerTagLapseType.TURN_END, 2, sourceMove); - } -} - -export class IgnoreAccuracyTag extends BattlerTag { - constructor(sourceMove: Moves) { - super(BattlerTagType.IGNORE_ACCURACY, BattlerTagLapseType.TURN_END, 2, sourceMove); - } -} - -export class AlwaysGetHitTag extends BattlerTag { - constructor(sourceMove: Moves) { - super(BattlerTagType.ALWAYS_GET_HIT, BattlerTagLapseType.PRE_MOVE, 1, sourceMove); - } -} - -export class ReceiveDoubleDamageTag extends BattlerTag { - constructor(sourceMove: Moves) { - super(BattlerTagType.RECEIVE_DOUBLE_DAMAGE, BattlerTagLapseType.PRE_MOVE, 1, sourceMove); - } -} - export class SaltCuredTag extends BattlerTag { private sourceIndex: number; @@ -1628,8 +1597,8 @@ export class StockpilingTag extends BattlerTag { super.loadTag(source); this.stockpiledCount = source.stockpiledCount || 0; this.statChangeCounts = { - [BattleStat.DEF]: source.statChangeCounts?.[BattleStat.DEF] || 0, - [BattleStat.SPDEF]: source.statChangeCounts?.[BattleStat.SPDEF] || 0, + [ BattleStat.DEF ]: source.statChangeCounts?.[ BattleStat.DEF ] ?? 0, + [ BattleStat.SPDEF ]: source.statChangeCounts?.[ BattleStat.SPDEF ] ?? 0, }; } @@ -1697,7 +1666,7 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source case BattlerTagType.FRENZY: return new FrenzyTag(turnCount, sourceMove, sourceId); case BattlerTagType.CHARGING: - return new ChargingTag(sourceMove, sourceId); + return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, 1, sourceMove, sourceId); case BattlerTagType.ENCORE: return new EncoreTag(sourceId); case BattlerTagType.HELPING_HAND: @@ -1770,17 +1739,15 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source case BattlerTagType.CRIT_BOOST: return new CritBoostTag(tagType, sourceMove); case BattlerTagType.ALWAYS_CRIT: - return new AlwaysCritTag(sourceMove); + case BattlerTagType.IGNORE_ACCURACY: + return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, 2, sourceMove); case BattlerTagType.NO_CRIT: return new BattlerTag(tagType, BattlerTagLapseType.AFTER_MOVE, turnCount, sourceMove); - case BattlerTagType.IGNORE_ACCURACY: - return new IgnoreAccuracyTag(sourceMove); case BattlerTagType.ALWAYS_GET_HIT: - return new AlwaysGetHitTag(sourceMove); case BattlerTagType.RECEIVE_DOUBLE_DAMAGE: - return new ReceiveDoubleDamageTag(sourceMove); + return new BattlerTag(tagType, BattlerTagLapseType.PRE_MOVE, 1, sourceMove); case BattlerTagType.BYPASS_SLEEP: - return new BattlerTag(BattlerTagType.BYPASS_SLEEP, BattlerTagLapseType.TURN_END, turnCount, sourceMove); + return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, turnCount, sourceMove); case BattlerTagType.IGNORE_FLYING: return new GroundedTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); case BattlerTagType.ROOSTED: diff --git a/src/data/biomes.ts b/src/data/biomes.ts index 782826d8695..479e0994cb6 100644 --- a/src/data/biomes.ts +++ b/src/data/biomes.ts @@ -17,8 +17,6 @@ export function getBiomeName(biome: Biome | -1) { return i18next.t("biome:GRASS"); case Biome.RUINS: return i18next.t("biome:RUINS"); - case Biome.ABYSS: - return i18next.t("biome:ABYSS"); case Biome.END: return i18next.t("biome:END"); default: diff --git a/src/data/challenge.ts b/src/data/challenge.ts index ad8c312bdf6..7bea68e36c7 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -17,6 +17,9 @@ import { Gender } from "./gender"; import { pokemonEvolutions } from "./pokemon-evolutions"; import { pokemonFormChanges } from "./pokemon-forms"; +/** A constant for the default max cost of the starting party before a run */ +const DEFAULT_PARTY_MAX_COST = 10; + /** * An enum for all the challenge types. The parameter entries on these describe the * parameters to use when calling the applyChallenges function. @@ -403,14 +406,7 @@ export class SingleGenerationChallenge extends Challenge { } applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false, checkEvolutions?: boolean): boolean { - /** - * We have special code below for victini because it is classed as a generation 4 pokemon in the code - * despite being a generation 5 pokemon. This is due to UI constraints, the starter select screen has - * no more room for pokemon so victini is put in the gen 4 section instead. This code just overrides the - * normal generation check to correctly treat victini as gen 5. - */ - const starterGeneration = pokemon.speciesId === Species.VICTINI ? 5 : pokemon.generation; - const generations = [starterGeneration]; + const generations = [pokemon.generation]; const checkPokemonEvolutions = checkEvolutions ?? true as boolean; if (soft) { const speciesToCheck = [pokemon.speciesId]; @@ -689,11 +685,11 @@ export class LowerStarterMaxCostChallenge extends Challenge { if (overrideValue === undefined) { overrideValue = this.value; } - return (10 - overrideValue).toString(); + return (DEFAULT_PARTY_MAX_COST - overrideValue).toString(); } applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder): boolean { - if (speciesStarters[pokemon.speciesId] > 10 - this.value) { + if (speciesStarters[pokemon.speciesId] > DEFAULT_PARTY_MAX_COST - this.value) { valid.value = false; return true; } @@ -723,7 +719,7 @@ export class LowerStarterPointsChallenge extends Challenge { if (overrideValue === undefined) { overrideValue = this.value; } - return (10 - overrideValue).toString(); + return (DEFAULT_PARTY_MAX_COST - overrideValue).toString(); } applyStarterPoints(points: Utils.NumberHolder): boolean { diff --git a/src/data/dialogue.ts b/src/data/dialogue.ts index ec3358b1a77..4386515c953 100644 --- a/src/data/dialogue.ts +++ b/src/data/dialogue.ts @@ -459,6 +459,20 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { ] } ], + [TrainerType.ROCKET_ADMIN]: [ + { + encounter: [ + "dialogue:rocket_admin.encounter.1", + "dialogue:rocket_admin.encounter.2", + "dialogue:rocket_admin.encounter.3", + ], + victory: [ + "dialogue:rocket_admin.victory.1", + "dialogue:rocket_admin.victory.2", + "dialogue:rocket_admin.victory.3", + ] + } + ], [TrainerType.MAGMA_GRUNT]: [ { encounter: [ @@ -469,6 +483,20 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { ] } ], + [TrainerType.MAGMA_ADMIN]: [ + { + encounter: [ + "dialogue:magma_admin.encounter.1", + "dialogue:magma_admin.encounter.2", + "dialogue:magma_admin.encounter.3", + ], + victory: [ + "dialogue:magma_admin.victory.1", + "dialogue:magma_admin.victory.2", + "dialogue:magma_admin.victory.3", + ] + } + ], [TrainerType.AQUA_GRUNT]: [ { encounter: [ @@ -479,6 +507,20 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { ] } ], + [TrainerType.AQUA_ADMIN]: [ + { + encounter: [ + "dialogue:aqua_admin.encounter.1", + "dialogue:aqua_admin.encounter.2", + "dialogue:aqua_admin.encounter.3", + ], + victory: [ + "dialogue:aqua_admin.victory.1", + "dialogue:aqua_admin.victory.2", + "dialogue:aqua_admin.victory.3", + ] + } + ], [TrainerType.GALACTIC_GRUNT]: [ { encounter: [ @@ -489,6 +531,20 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { ] } ], + [TrainerType.GALACTIC_ADMIN]: [ + { + encounter: [ + "dialogue:galactic_admin.encounter.1", + "dialogue:galactic_admin.encounter.2", + "dialogue:galactic_admin.encounter.3", + ], + victory: [ + "dialogue:galactic_admin.victory.1", + "dialogue:galactic_admin.victory.2", + "dialogue:galactic_admin.victory.3", + ] + } + ], [TrainerType.PLASMA_GRUNT]: [ { encounter: [ @@ -499,6 +555,20 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { ] } ], + [TrainerType.PLASMA_SAGE]: [ + { + encounter: [ + "dialogue:plasma_sage.encounter.1", + "dialogue:plasma_sage.encounter.2", + "dialogue:plasma_sage.encounter.3", + ], + victory: [ + "dialogue:plasma_sage.victory.1", + "dialogue:plasma_sage.victory.2", + "dialogue:plasma_sage.victory.3", + ] + } + ], [TrainerType.FLARE_GRUNT]: [ { encounter: [ @@ -509,6 +579,20 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { ] } ], + [TrainerType.FLARE_ADMIN]: [ + { + encounter: [ + "dialogue:flare_admin.encounter.1", + "dialogue:flare_admin.encounter.2", + "dialogue:flare_admin.encounter.3", + ], + victory: [ + "dialogue:flare_admin.victory.1", + "dialogue:flare_admin.victory.2", + "dialogue:flare_admin.victory.3", + ] + } + ], [TrainerType.ROCKET_BOSS_GIOVANNI_1]: [ { encounter: [ diff --git a/src/data/egg-moves.ts b/src/data/egg-moves.ts index 64e75113dbc..1f893a0c522 100644 --- a/src/data/egg-moves.ts +++ b/src/data/egg-moves.ts @@ -438,7 +438,7 @@ export const speciesEggMoves = { [Species.CHEWTLE]: [ Moves.FIRE_FANG, Moves.ACCELEROCK, Moves.SHELL_SMASH, Moves.FISHIOUS_REND ], [Species.YAMPER]: [ Moves.ICE_FANG, Moves.SWORDS_DANCE, Moves.THUNDER_FANG, Moves.ZIPPY_ZAP ], [Species.ROLYCOLY]: [ Moves.BITTER_BLADE, Moves.BODY_PRESS, Moves.BULK_UP, Moves.DIAMOND_STORM ], - [Species.APPLIN]: [ Moves.DRAGON_CHEER, Moves.DRAGON_HAMMER, Moves.FLOWER_TRICK, Moves.STRENGTH_SAP ], + [Species.APPLIN]: [ Moves.MATCHA_GOTCHA, Moves.DRAGON_HAMMER, Moves.FLOWER_TRICK, Moves.STRENGTH_SAP ], [Species.SILICOBRA]: [ Moves.SHORE_UP, Moves.SHED_TAIL, Moves.STONE_EDGE, Moves.PRECIPICE_BLADES ], [Species.CRAMORANT]: [ Moves.APPLE_ACID, Moves.SURF, Moves.SCORCHING_SANDS, Moves.OBLIVION_WING ], [Species.ARROKUDA]: [ Moves.SUPERCELL_SLAM, Moves.KNOCK_OFF, Moves.ICE_SPINNER, Moves.FILLET_AWAY ], diff --git a/src/data/egg.ts b/src/data/egg.ts index bf4d6577dd7..a7a1b167238 100644 --- a/src/data/egg.ts +++ b/src/data/egg.ts @@ -66,7 +66,7 @@ export interface IEggOptions { export class Egg { //// - // #region Privat properties + // #region Private properties //// private _id: number; @@ -182,7 +182,7 @@ export class Egg { } //// - // #region Public methodes + // #region Public methods //// public isManaphyEgg(): boolean { @@ -212,7 +212,7 @@ export class Egg { let abilityIndex = undefined; if (pokemonSpecies.abilityHidden && (this._overrideHiddenAbility || (this._sourceType === EggSourceType.SAME_SPECIES_EGG && !Utils.randSeedInt(SAME_SPECIES_EGG_HA_RATE)))) { - abilityIndex = pokemonSpecies.ability2 ? 2 : 1; + abilityIndex = 2; } // This function has way to many optional parameters @@ -281,7 +281,7 @@ export class Egg { //// //// - // #region Private methodes + // #region Private methods //// private rollEggMoveIndex() { diff --git a/src/data/move.ts b/src/data/move.ts index 4d0b53ec29f..082bbb13aa2 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -2,7 +2,7 @@ import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./ import { BattleEndPhase, MoveEndPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases"; import { BattleStat, getBattleStatName } from "./battle-stat"; import { EncoreTag, HelpingHandTag, SemiInvulnerableTag, StockpilingTag, TypeBoostTag } from "./battler-tags"; -import { getPokemonMessage, getPokemonNameWithAffix } from "../messages"; +import { getPokemonNameWithAffix } from "../messages"; import Pokemon, { AttackMoveResult, EnemyPokemon, HitResult, MoveResult, PlayerPokemon, PokemonMove, TurnMove } from "../field/pokemon"; import { StatusEffect, getStatusEffectHealText, isNonVolatileStatusEffect, getNonVolatileStatusEffects} from "./status-effect"; import { getTypeResistances, Type } from "./type"; @@ -13,10 +13,9 @@ import { ArenaTagSide, ArenaTrapTag, WeakenMoveTypeTag } from "./arena-tag"; import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, BlockItemTheftAbAttr, applyPostAttackAbAttrs, ConfusionOnStatusEffectAbAttr, HealFromBerryUseAbAttr, IgnoreProtectOnContactAbAttr, IgnoreMoveEffectsAbAttr, applyPreDefendAbAttrs, MoveEffectChanceMultiplierAbAttr, WonderSkinAbAttr, applyPreAttackAbAttrs, MoveTypeChangeAttr, UserFieldMoveTypePowerBoostAbAttr, FieldMoveTypePowerBoostAbAttr, AllyMoveCategoryPowerBoostAbAttr, VariableMovePowerAbAttr } from "./ability"; import { allAbilities } from "./ability"; import { PokemonHeldItemModifier, BerryModifier, PreserveBerryModifier, PokemonMoveAccuracyBoosterModifier, AttackTypeBoosterModifier, PokemonMultiHitModifier } from "../modifier/modifier"; -import { BattlerIndex } from "../battle"; +import { BattlerIndex, BattleType } from "../battle"; import { Stat } from "./pokemon-stat"; import { TerrainType } from "./terrain"; -import { SpeciesFormChangeActiveTrigger } from "./pokemon-forms"; import { ModifierPoolType } from "#app/modifier/modifier-type"; import { Command } from "../ui/command-ui-handler"; import i18next from "i18next"; @@ -718,9 +717,13 @@ export default class Move implements Localizable { * @returns The calculated power of the move. */ calculateBattlePower(source: Pokemon, target: Pokemon): number { - const power = new Utils.NumberHolder(this.power); + if (this.category === MoveCategory.STATUS) { + return -1; + } + const power = new Utils.NumberHolder(this.power); const typeChangeMovePowerMultiplier = new Utils.NumberHolder(1); + applyPreAttackAbAttrs(MoveTypeChangeAttr, source, target, this, typeChangeMovePowerMultiplier); const sourceTeraType = source.getTeraType(); @@ -974,7 +977,9 @@ export class MoveEffectAttr extends MoveAttr { getMoveChance(user: Pokemon, target: Pokemon, move: Move, selfEffect?: Boolean, showAbility?: Boolean): integer { const moveChance = new Utils.NumberHolder(move.chance); applyAbAttrs(MoveEffectChanceMultiplierAbAttr, user, null, moveChance, move, target, selfEffect, showAbility); - applyPreDefendAbAttrs(IgnoreMoveEffectsAbAttr,target,user,null,null, moveChance); + if (!selfEffect) { + applyPreDefendAbAttrs(IgnoreMoveEffectsAbAttr, target, user, null, null, moveChance); + } return moveChance.value; } } @@ -1221,7 +1226,7 @@ export class RecoilAttr extends MoveEffectAttr { } user.damageAndUpdate(recoilDamage, HitResult.OTHER, false, true, true); - user.scene.queueMessage(getPokemonMessage(user, " is hit\nwith recoil!")); + user.scene.queueMessage(i18next.t("moveTriggers:hitWithRecoil", {pokemonName: getPokemonNameWithAffix(user)})); user.turnData.damageTaken += recoilDamage; return true; @@ -1333,7 +1338,7 @@ export class HalfSacrificialAttr extends MoveEffectAttr { applyAbAttrs(BlockNonDirectDamageAbAttr, user, cancelled); if (!cancelled.value) { user.damageAndUpdate(Math.ceil(user.getMaxHp()/2), HitResult.OTHER, false, true, true); - user.scene.queueMessage(getPokemonMessage(user, " cut its own HP to power up its move!")); // Queue recoil message + user.scene.queueMessage(i18next.t("moveTriggers:cutHpPowerUpMove", {pokemonName: getPokemonNameWithAffix(user)})); // Queue recoil message } return true; } @@ -1383,7 +1388,7 @@ export class HealAttr extends MoveEffectAttr { */ addHealPhase(target: Pokemon, healRatio: number) { target.scene.unshiftPhase(new PokemonHealPhase(target.scene, target.getBattlerIndex(), - Math.max(Math.floor(target.getMaxHp() * healRatio), 1), getPokemonMessage(target, " \nhad its HP restored."), true, !this.showAnim)); + Math.max(Math.floor(target.getMaxHp() * healRatio), 1), i18next.t("moveTriggers:healHp", {pokemonName: getPokemonNameWithAffix(target)}), true, !this.showAnim)); } getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { @@ -1430,6 +1435,39 @@ export class PartyStatusCureAttr extends MoveEffectAttr { } } +/** + * Applies damage to the target's ally equal to 1/16 of that ally's max HP. + * @extends MoveEffectAttr + */ +export class FlameBurstAttr extends MoveEffectAttr { + /** + * @param user - n/a + * @param target - The target Pokémon. + * @param move - n/a + * @param args - n/a + * @returns A boolean indicating whether the effect was successfully applied. + */ + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise { + const targetAlly = target.getAlly(); + const cancelled = new Utils.BooleanHolder(false); + + if (targetAlly) { + applyAbAttrs(BlockNonDirectDamageAbAttr, targetAlly, cancelled); + } + + if (cancelled.value || !targetAlly) { + return false; + } + + targetAlly.damageAndUpdate(Math.max(1, Math.floor(1/16 * targetAlly.getMaxHp())), HitResult.OTHER); + return true; + } + + getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { + return target.getAlly() ? -5 : 0; + } +} + export class SacrificialFullRestoreAttr extends SacrificialAttr { constructor() { super(); @@ -1444,7 +1482,7 @@ export class SacrificialFullRestoreAttr extends SacrificialAttr { const maxPartyMemberHp = user.scene.getParty().map(p => p.getMaxHp()).reduce((maxHp: integer, hp: integer) => Math.max(hp, maxHp), 0); user.scene.pushPhase(new PokemonHealPhase(user.scene, user.getBattlerIndex(), - maxPartyMemberHp, getPokemonMessage(user, "'s Healing Wish\nwas granted!"), true, false, false, true), true); + maxPartyMemberHp, i18next.t("moveTriggers:sacrificialFullRestore", {pokemonName: getPokemonNameWithAffix(user)}), true, false, false, true), true); return true; } @@ -1637,9 +1675,14 @@ export class HitHealAttr extends MoveEffectAttr { message = i18next.t("battle:regainHealth", {pokemonName: getPokemonNameWithAffix(user)}); } if (reverseDrain) { - user.turnData.damageTaken += healAmount; - healAmount = healAmount * -1; - message = null; + if (user.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { + healAmount = 0; + message = null; + } else { + user.turnData.damageTaken += healAmount; + healAmount = healAmount * -1; + message = null; + } } user.scene.unshiftPhase(new PokemonHealPhase(user.scene, user.getBattlerIndex(), healAmount, message, false, true)); return true; @@ -1774,13 +1817,10 @@ export class MultiHitAttr extends MoveAttr { } case MultiHitType._2: return 2; - break; case MultiHitType._3: return 3; - break; case MultiHitType._10: return 10; - break; case MultiHitType.BEAT_UP: const party = user.isPlayer() ? user.scene.getParty() : user.scene.getEnemyParty(); // No status means the ally pokemon can contribute to Beat Up @@ -1874,7 +1914,7 @@ export class PsychoShiftEffectAttr extends MoveEffectAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const statusToApply: StatusEffect = user.status?.effect; + const statusToApply: StatusEffect = user.status?.effect ?? (user.hasAbility(Abilities.COMATOSE) ? StatusEffect.SLEEP : undefined); if (target.status) { return false; @@ -1882,7 +1922,9 @@ export class PsychoShiftEffectAttr extends MoveEffectAttr { if (!target.status || (target.status.effect === statusToApply && move.chance < 0)) { const statusAfflictResult = target.trySetStatus(statusToApply, true, user); if (statusAfflictResult) { - user.scene.queueMessage(getStatusEffectHealText(user.status.effect, getPokemonNameWithAffix(user))); + if (user.status) { + user.scene.queueMessage(getStatusEffectHealText(user.status.effect, getPokemonNameWithAffix(user))); + } user.resetStatus(); user.updateInfo(); } @@ -1923,7 +1965,7 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr { const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)]; user.scene.tryTransferHeldItemModifier(stolenItem, user, false).then(success => { if (success) { - user.scene.queueMessage(getPokemonMessage(user, ` stole\n${target.name}'s ${stolenItem.type.name}!`)); + user.scene.queueMessage(i18next.t("moveTriggers:stoleItem", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: stolenItem.type.name})); } resolve(success); }); @@ -2002,9 +2044,9 @@ export class RemoveHeldItemAttr extends MoveEffectAttr { target.scene.updateModifiers(target.isPlayer()); if (this.berriesOnly) { - user.scene.queueMessage(getPokemonMessage(user, ` incinerated\n${target.name}'s ${removedItem.type.name}!`)); + user.scene.queueMessage(i18next.t("moveTriggers:incineratedItem", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name})); } else { - user.scene.queueMessage(getPokemonMessage(user, ` knocked off\n${target.name}'s ${removedItem.type.name}!`)); + user.scene.queueMessage(i18next.t("moveTriggers:knockedOffItem", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name})); } } @@ -2150,6 +2192,12 @@ export class HealStatusEffectAttr extends MoveEffectAttr { return false; } + // Special edge case for shield dust blocking Sparkling Aria curing burn + const moveTargets = getMoveTargets(user, move.id); + if (target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && move.id === Moves.SPARKLING_ARIA && moveTargets.targets.length === 1) { + return false; + } + const pokemon = this.selfTarget ? user : target; if (pokemon.status && this.effects.includes(pokemon.status.effect)) { pokemon.scene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon))); @@ -2325,7 +2373,7 @@ export class ChargeAttr extends OverrideMoveEffectAttr { if (!lastMove || lastMove.move !== move.id || (lastMove.result !== MoveResult.OTHER && (this.sameTurn || lastMove.turn !== user.scene.currentBattle.turn))) { (args[0] as Utils.BooleanHolder).value = true; new MoveChargeAnim(this.chargeAnim, move.id, user).play(user.scene, () => { - user.scene.queueMessage(getPokemonMessage(user, ` ${this.chargeText.replace("{TARGET}", target.name)}`)); + user.scene.queueMessage(this.chargeText.replace("{TARGET}", getPokemonNameWithAffix(target)).replace("{USER}", getPokemonNameWithAffix(user))); if (this.tagType) { user.addTag(this.tagType, 1, move.id, user.id); } @@ -2381,7 +2429,7 @@ export class SunlightChargeAttr extends ChargeAttr { export class ElectroShotChargeAttr extends ChargeAttr { private statIncreaseApplied: boolean; constructor() { - super(ChargeAnim.ELECTRO_SHOT_CHARGING, "absorbed electricity!", null, true); + super(ChargeAnim.ELECTRO_SHOT_CHARGING, i18next.t("moveTriggers:absorbedElectricity", {pokemonName: "{USER}"}), null, true); // Add a flag because ChargeAttr skills use themselves twice instead of once over one-to-two turns this.statIncreaseApplied = false; } @@ -2433,14 +2481,14 @@ export class DelayedAttackAttr extends OverrideMoveEffectAttr { if (args.length < 2 || !args[1]) { new MoveChargeAnim(this.chargeAnim, move.id, user).play(user.scene, () => { (args[0] as Utils.BooleanHolder).value = true; - user.scene.queueMessage(getPokemonMessage(user, ` ${this.chargeText.replace("{TARGET}", getPokemonNameWithAffix(target))}`)); + user.scene.queueMessage(this.chargeText.replace("{TARGET}", getPokemonNameWithAffix(target)).replace("{USER}", getPokemonNameWithAffix(user))); user.pushMoveHistory({ move: move.id, targets: [ target.getBattlerIndex() ], result: MoveResult.OTHER }); user.scene.arena.addTag(this.tagType, 3, move.id, user.id, ArenaTagSide.BOTH, false, target.getBattlerIndex()); resolve(true); }); } else { - user.scene.ui.showText(getPokemonMessage(user.scene.getPokemonById(target.id), ` took\nthe ${move.name} attack!`), null, () => resolve(true)); + user.scene.ui.showText(i18next.t("moveTriggers:tookMoveAttack", {pokemonName: getPokemonNameWithAffix(user.scene.getPokemonById(target.id)), moveName: move.name}), null, () => resolve(true)); } }); } @@ -2580,36 +2628,15 @@ export class GrowthStatChangeAttr extends StatChangeAttr { } } -export class HalfHpStatMaxAttr extends StatChangeAttr { - constructor(stat: BattleStat) { - super(stat, 12, true, null, false); - } - - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { - return new Promise(resolve => { - user.damageAndUpdate(Math.floor(user.getMaxHp() / 2), HitResult.OTHER, false, true); - user.updateInfo().then(() => { - const ret = super.apply(user, target, move, args); - user.scene.queueMessage(getPokemonMessage(user, ` cut its own HP\nand maximized its ${getBattleStatName(this.stats[BattleStat.ATK])}!`)); - resolve(ret); - }); - }); - } - - getCondition(): MoveConditionFunc { - return (user, target, move) => user.getHpRatio() > 0.5 && user.summonData.battleStats[this.stats[BattleStat.ATK]] < 6; - } - - // TODO: Add benefit score that considers HP cut -} - export class CutHpStatBoostAttr extends StatChangeAttr { private cutRatio: integer; + private messageCallback: ((user: Pokemon) => void) | undefined; - constructor(stat: BattleStat | BattleStat[], levels: integer, cutRatio: integer) { + constructor(stat: BattleStat | BattleStat[], levels: integer, cutRatio: integer, messageCallback?: ((user: Pokemon) => void) | undefined) { super(stat, levels, true, null, true); this.cutRatio = cutRatio; + this.messageCallback = messageCallback; } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { @@ -2617,13 +2644,16 @@ export class CutHpStatBoostAttr extends StatChangeAttr { user.damageAndUpdate(Math.floor(user.getMaxHp() / this.cutRatio), HitResult.OTHER, false, true); user.updateInfo().then(() => { const ret = super.apply(user, target, move, args); + if (this.messageCallback) { + this.messageCallback(user); + } resolve(ret); }); }); } getCondition(): MoveConditionFunc { - return (user, target, move) => user.getHpRatio() > 1 / this.cutRatio; + return (user, target, move) => user.getHpRatio() > 1 / this.cutRatio && this.stats.some(s => user.summonData.battleStats[s] < 6); } } @@ -2643,8 +2673,7 @@ export class CopyStatsAttr extends MoveEffectAttr { } target.updateInfo(); user.updateInfo(); - - target.scene.queueMessage(getPokemonMessage(user, " copied\n") + getPokemonMessage(target, "'s stat changes!")); + target.scene.queueMessage(i18next.t("moveTriggers:copiedStatChanges", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target)})); return true; } @@ -2662,7 +2691,7 @@ export class InvertStatsAttr extends MoveEffectAttr { target.updateInfo(); user.updateInfo(); - target.scene.queueMessage(getPokemonMessage(target, "'s stat changes\nwere all reversed!")); + target.scene.queueMessage(i18next.t("moveTriggers:invertStats", {pokemonName: getPokemonNameWithAffix(target)})); return true; } @@ -2680,7 +2709,7 @@ export class ResetStatsAttr extends MoveEffectAttr { target.updateInfo(); user.updateInfo(); - target.scene.queueMessage(getPokemonMessage(target, "'s stat changes\nwere eliminated!")); + target.scene.queueMessage(i18next.t("moveTriggers:resetStats", {pokemonName: getPokemonNameWithAffix(target)})); return true; } @@ -2710,7 +2739,7 @@ export class SwapStatsAttr extends MoveEffectAttr { } target.updateInfo(); user.updateInfo(); - target.scene.queueMessage(getPokemonMessage(user, " switched stat changes with the target!")); + target.scene.queueMessage(i18next.t("moveTriggers:switchedStatChanges", {pokemonName: getPokemonNameWithAffix(user)})); return true; } } @@ -2855,7 +2884,12 @@ export class BeatUpAttr extends VariablePowerAttr { */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const power = args[0] as Utils.NumberHolder; - const allyIndex = user.turnData.hitCount - user.turnData.hitsLeft; + + const party = user.isPlayer() ? user.scene.getParty() : user.scene.getEnemyParty(); + const allyCount = party.filter(pokemon => { + return pokemon.id === user.id || !pokemon.status?.effect; + }).length; + const allyIndex = (user.turnData.hitCount - user.turnData.hitsLeft) % allyCount; power.value = beatUpFunc(user, allyIndex); return true; } @@ -2866,7 +2900,7 @@ const doublePowerChanceMessageFunc = (user: Pokemon, target: Pokemon, move: Move user.scene.executeWithSeedOffset(() => { const rand = Utils.randSeedInt(100); if (rand < move.chance) { - message = getPokemonMessage(user, " is going all out for this attack!"); + message = i18next.t("moveTriggers:goingAllOutForAttack", {pokemonName: getPokemonNameWithAffix(user)}); } }, user.scene.currentBattle.turn << 6, user.scene.waveSeed); return message; @@ -3145,7 +3179,7 @@ const magnitudeMessageFunc = (user: Pokemon, target: Pokemon, move: Move) => { } } - message = `Magnitude ${m + 4}!`; + message = i18next.t("moveTriggers:magnitudeMessage", {magnitude: m + 4}); }, user.scene.currentBattle.turn << 6, user.scene.waveSeed); return message; }; @@ -3295,7 +3329,7 @@ export class PresentPowerAttr extends VariablePowerAttr { // If this move is multi-hit, disable all other hits user.stopMultiHit(); target.scene.unshiftPhase(new PokemonHealPhase(target.scene, target.getBattlerIndex(), - Math.max(Math.floor(target.getMaxHp() / 4), 1), getPokemonMessage(target, " regained\nhealth!"), true)); + Math.max(Math.floor(target.getMaxHp() / 4), 1), i18next.t("moveTriggers:regainedHealth", {pokemonName: getPokemonNameWithAffix(target)}), true)); } return true; @@ -3405,6 +3439,72 @@ export class MultiHitPowerIncrementAttr extends VariablePowerAttr { } } +/** + * Attribute used for moves that double in power if the given move immediately + * preceded the move applying the attribute, namely Fusion Flare and + * Fusion Bolt. + * @extends VariablePowerAttr + * @see {@linkcode apply} + */ +export class LastMoveDoublePowerAttr extends VariablePowerAttr { + /** The move that must precede the current move */ + private move: Moves; + + constructor(move: Moves) { + super(); + + this.move = move; + } + + /** + * Doubles power of move if the given move is found to precede the current + * move with no other moves being executed in between, only ignoring failed + * moves if any. + * @param user {@linkcode Pokemon} that used the move + * @param target N/A + * @param move N/A + * @param args [0] {@linkcode Utils.NumberHolder} that holds the resulting power of the move + * @returns true if attribute application succeeds, false otherwise + */ + apply(user: Pokemon, _target: Pokemon, _move: Move, args: any[]): boolean { + const power = args[0] as Utils.NumberHolder; + const enemy = user.getOpponent(0); + const pokemonActed: Pokemon[] = []; + + if (enemy.turnData.acted) { + pokemonActed.push(enemy); + } + + if (user.scene.currentBattle.double) { + const userAlly = user.getAlly(); + const enemyAlly = enemy.getAlly(); + + if (userAlly && userAlly.turnData.acted) { + pokemonActed.push(userAlly); + } + if (enemyAlly && enemyAlly.turnData.acted) { + pokemonActed.push(enemyAlly); + } + } + + pokemonActed.sort((a, b) => b.turnData.order - a.turnData.order); + + for (const p of pokemonActed) { + const [ lastMove ] = p.getLastXMoves(1); + if (lastMove.result !== MoveResult.FAIL) { + if ((lastMove.result === MoveResult.SUCCESS) && (lastMove.move === this.move)) { + power.value *= 2; + return true; + } else { + break; + } + } + } + + return false; + } +} + export class VariableAtkAttr extends MoveAttr { constructor() { super(); @@ -3716,26 +3816,18 @@ export class IvyCudgelTypeAttr extends VariableMoveTypeAttr { switch (form) { case 1: // Wellspring Mask - move.type = Type.WATER; - break; - case 2: // Hearthflame Mask - move.type = Type.FIRE; - break; - case 3: // Cornerstone Mask - move.type = Type.ROCK; - break; - case 4: // Teal Mask Tera - move.type = Type.GRASS; - break; case 5: // Wellspring Mask Tera move.type = Type.WATER; break; + case 2: // Hearthflame Mask case 6: // Hearthflame Mask Tera move.type = Type.FIRE; break; + case 3: // Cornerstone Mask case 7: // Cornerstone Mask Tera move.type = Type.ROCK; break; + case 4: // Teal Mask Tera default: move.type = Type.GRASS; break; @@ -3985,7 +4077,7 @@ const crashDamageFunc = (user: Pokemon, move: Move) => { } user.damageAndUpdate(Math.floor(user.getMaxHp() / 2), HitResult.OTHER, false, true); - user.scene.queueMessage(getPokemonMessage(user, " kept going\nand crashed!")); + user.scene.queueMessage(i18next.t("moveTriggers:keptGoingAndCrashed", {pokemonName: getPokemonNameWithAffix(user)})); user.turnData.damageTaken += Math.floor(user.getMaxHp() / 2); return true; @@ -4025,7 +4117,7 @@ export class DisableMoveAttr extends MoveEffectAttr { target.summonData.disabledMove = disabledMove.moveId; target.summonData.disabledTurns = 4; - user.scene.queueMessage(getPokemonMessage(target, `'s ${disabledMove.getName()}\nwas disabled!`)); + user.scene.queueMessage(i18next.t("abilityTriggers:postDefendMoveDisable", { pokemonNameWithAffix: getPokemonNameWithAffix(target), moveName: disabledMove.getName()})); return true; } @@ -4306,12 +4398,6 @@ export class ProtectAttr extends AddBattlerTagAttr { } } -export class EndureAttr extends ProtectAttr { - constructor() { - super(BattlerTagType.ENDURING); - } -} - export class IgnoreAccuracyAttr extends AddBattlerTagAttr { constructor() { super(BattlerTagType.IGNORE_ACCURACY, true, false, 2); @@ -4322,35 +4408,7 @@ export class IgnoreAccuracyAttr extends AddBattlerTagAttr { return false; } - user.scene.queueMessage(getPokemonMessage(user, ` took aim\nat ${target.name}!`)); - - return true; - } -} - -export class AlwaysGetHitAttr extends AddBattlerTagAttr { - constructor() { - super(BattlerTagType.ALWAYS_GET_HIT, true, false, 0, 0, true); - } - - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - if (!super.apply(user, target, move, args)) { - return false; - } - - return true; - } -} - -export class ReceiveDoubleDamageAttr extends AddBattlerTagAttr { - constructor() { - super(BattlerTagType.RECEIVE_DOUBLE_DAMAGE, true, false, 0, 0, true); - } - - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - if (!super.apply(user, target, move, args)) { - return false; - } + user.scene.queueMessage(i18next.t("moveTriggers:tookAimAtTarget", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target)})); return true; } @@ -4366,7 +4424,7 @@ export class FaintCountdownAttr extends AddBattlerTagAttr { return false; } - user.scene.queueMessage(getPokemonMessage(target, `\nwill faint in ${this.turnCountMin - 1} turns.`)); + user.scene.queueMessage(i18next.t("moveTriggers:faintCountdown", {pokemonName: getPokemonNameWithAffix(target), turnCount: this.turnCountMin - 1})); return true; } @@ -4606,7 +4664,7 @@ export class SwapArenaTagsAttr extends MoveEffectAttr { } - user.scene.queueMessage( `${getPokemonNameWithAffix(user)} swapped the battle effects affecting each side of the field!`); + user.scene.queueMessage( i18next.t("moveTriggers:swapArenaTags", {pokemonName: getPokemonNameWithAffix(user)})); return true; } } @@ -4701,19 +4759,14 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { if (switchOutTarget.hp > 0) { applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, switchOutTarget); // switchOut below sets the UI to select party(this is not a separate Phase), then adds a SwitchSummonPhase with selected 'mon - (switchOutTarget as PlayerPokemon).switchOut(this.batonPass, true).then(() => resolve(true)); + (switchOutTarget as PlayerPokemon).switchOut(this.batonPass).then(() => resolve(true)); } else { resolve(false); } return; - } else if (user.scene.currentBattle.battleType) { - // Switch out logic for the battle type - switchOutTarget.resetTurnData(); - switchOutTarget.resetSummonData(); - switchOutTarget.hideInfo(); - switchOutTarget.setVisible(false); - switchOutTarget.scene.field.remove(switchOutTarget); - user.scene.triggerPokemonFormChange(switchOutTarget, SpeciesFormChangeActiveTrigger, true); + } else if (user.scene.currentBattle.battleType !== BattleType.WILD) { + // Switch out logic for trainer battles + switchOutTarget.leaveField(!this.batonPass); if (switchOutTarget.hp > 0) { // for opponent switching out @@ -4726,7 +4779,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { if (switchOutTarget.hp) { switchOutTarget.hideInfo().then(() => switchOutTarget.destroy()); switchOutTarget.scene.field.remove(switchOutTarget); - user.scene.queueMessage(getPokemonMessage(switchOutTarget, " fled!"), null, true, 500); + user.scene.queueMessage(i18next.t("moveTriggers:fled", {pokemonName: getPokemonNameWithAffix(switchOutTarget)}), null, true, 500); } if (!switchOutTarget.getAlly()?.isActive(true)) { @@ -4750,7 +4803,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { getFailedText(user: Pokemon, target: Pokemon, move: Move, cancelled: Utils.BooleanHolder): string | null { const blockedByAbility = new Utils.BooleanHolder(false); applyAbAttrs(ForceSwitchOutImmunityAbAttr, target, blockedByAbility); - return blockedByAbility.value ? getPokemonMessage(target, " can't be switched out!") : null; + return blockedByAbility.value ? i18next.t("moveTriggers:cannotBeSwitchedOut", {pokemonName: getPokemonNameWithAffix(target)}) : null; } getSwitchOutCondition(): MoveConditionFunc { @@ -4872,7 +4925,7 @@ export class CopyTypeAttr extends MoveEffectAttr { user.summonData.types = target.getTypes(true); user.updateInfo(); - user.scene.queueMessage(getPokemonMessage(user, `'s type\nchanged to match ${getPokemonNameWithAffix(target)}'s!`)); + user.scene.queueMessage(i18next.t("moveTriggers:copyType", {pokemonName: getPokemonNameWithAffix(user), targetPokemonName: getPokemonNameWithAffix(target)})); return true; } @@ -4897,7 +4950,7 @@ export class CopyBiomeTypeAttr extends MoveEffectAttr { user.summonData.types = [ biomeType ]; user.updateInfo(); - user.scene.queueMessage(getPokemonMessage(user, ` transformed\ninto the ${Utils.toReadableString(Type[biomeType])} type!`)); + user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoType", {pokemonName: getPokemonNameWithAffix(user), typeName: i18next.t(`pokemonInfo:Type.${Type[biomeType]}`)})); return true; } @@ -4916,7 +4969,7 @@ export class ChangeTypeAttr extends MoveEffectAttr { target.summonData.types = [this.type]; target.updateInfo(); - user.scene.queueMessage(getPokemonMessage(target, ` transformed\ninto the ${Utils.toReadableString(Type[this.type])} type!`)); + user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoType", {pokemonName: getPokemonNameWithAffix(target), typeName: i18next.t(`pokemonInfo:Type.${Type[this.type]}`)})); return true; } @@ -4943,7 +4996,7 @@ export class AddTypeAttr extends MoveEffectAttr { target.summonData.types = types; target.updateInfo(); - user.scene.queueMessage(`${Utils.toReadableString(Type[this.type])} was added to\n` + getPokemonMessage(target, "!")); + user.scene.queueMessage(i18next.t("moveTriggers:addType", {typeName: i18next.t(`pokemonInfo:Type.${Type[this.type]}`), pokemonName: getPokemonNameWithAffix(target)})); return true; } @@ -4965,7 +5018,7 @@ export class FirstMoveTypeAttr extends MoveEffectAttr { const firstMoveType = target.getMoveset()[0].getMove().type; user.summonData.types = [ firstMoveType ]; - user.scene.queueMessage(i18next.t("battle:transformedIntoType", {pokemonName: getPokemonNameWithAffix(user), type: Utils.toReadableString(Type[firstMoveType])})); + user.scene.queueMessage(i18next.t("battle:transformedIntoType", {pokemonName: getPokemonNameWithAffix(user), type: i18next.t(`pokemonInfo:Type.${Type[firstMoveType]}`)})); return true; } @@ -5367,7 +5420,7 @@ export class MovesetCopyMoveAttr extends OverrideMoveEffectAttr { user.summonData.moveset = user.getMoveset().slice(0); user.summonData.moveset[thisMoveIndex] = new PokemonMove(copiedMove.id, 0, 0); - user.scene.queueMessage(getPokemonMessage(user, ` copied\n${copiedMove.name}!`)); + user.scene.queueMessage(i18next.t("moveTriggers:copiedMove", {pokemonName: getPokemonNameWithAffix(user), moveName: copiedMove.name})); return true; } @@ -5400,7 +5453,7 @@ export class SketchAttr extends MoveEffectAttr { user.setMove(sketchIndex, sketchedMove.id); - user.scene.queueMessage(getPokemonMessage(user, ` sketched\n${sketchedMove.name}!`)); + user.scene.queueMessage(i18next.t("moveTriggers:sketchedMove", {pokemonName: getPokemonNameWithAffix(user), moveName: sketchedMove.name})); return true; } @@ -5443,7 +5496,7 @@ export class AbilityChangeAttr extends MoveEffectAttr { (this.selfTarget ? user : target).summonData.ability = this.ability; - user.scene.queueMessage("The " + getPokemonMessage((this.selfTarget ? user : target), ` acquired\n${allAbilities[this.ability].name}!`)); + user.scene.queueMessage(i18next.t("moveTriggers:acquiredAbility", {pokemonName: getPokemonNameWithAffix((this.selfTarget ? user : target)), abilityName: allAbilities[this.ability].name})); return true; } @@ -5469,11 +5522,11 @@ export class AbilityCopyAttr extends MoveEffectAttr { user.summonData.ability = target.getAbility().id; - user.scene.queueMessage(getPokemonMessage(user, " copied the ") + getPokemonMessage(target, `'s\n${allAbilities[target.getAbility().id].name}!`)); + user.scene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name})); if (this.copyToPartner && user.scene.currentBattle?.double && user.getAlly().hp) { user.getAlly().summonData.ability = target.getAbility().id; - user.getAlly().scene.queueMessage(getPokemonMessage(user.getAlly(), " copied the ") + getPokemonMessage(target, `'s\n${allAbilities[target.getAbility().id].name}!`)); + user.getAlly().scene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", {pokemonName: getPokemonNameWithAffix(user.getAlly()), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name})); } return true; @@ -5506,7 +5559,7 @@ export class AbilityGiveAttr extends MoveEffectAttr { target.summonData.ability = user.getAbility().id; - user.scene.queueMessage("The" + getPokemonMessage(target, `\nacquired ${allAbilities[user.getAbility().id].name}!`)); + user.scene.queueMessage(i18next.t("moveTriggers:acquiredAbility", {pokemonName: getPokemonNameWithAffix(target), abilityName: allAbilities[user.getAbility().id].name})); return true; } @@ -5526,7 +5579,7 @@ export class SwitchAbilitiesAttr extends MoveEffectAttr { user.summonData.ability = target.getAbility().id; target.summonData.ability = tempAbilityId; - user.scene.queueMessage(getPokemonMessage(user, " swapped\nabilities with its target!")); + user.scene.queueMessage(i18next.t("moveTriggers:swappedAbilitiesWithTarget", {pokemonName: getPokemonNameWithAffix(user)})); return true; } @@ -5553,7 +5606,7 @@ export class SuppressAbilitiesAttr extends MoveEffectAttr { target.summonData.abilitySuppressed = true; - target.scene.queueMessage(getPokemonMessage(target, "'s ability\nwas suppressed!")); + target.scene.queueMessage(i18next.t("moveTriggers:suppressAbilities", {pokemonName: getPokemonNameWithAffix(target)})); return true; } @@ -5610,7 +5663,7 @@ export class TransformAttr extends MoveEffectAttr { user.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m.moveId, m.ppUsed, m.ppUp)); user.summonData.types = target.getTypes(); - user.scene.queueMessage(getPokemonMessage(user, ` transformed\ninto ${target.name}!`)); + user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoTarget", {pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target)})); user.loadAssets(false).then(() => { user.playAnim(); @@ -5641,7 +5694,7 @@ export class MoneyAttr extends MoveEffectAttr { apply(user: Pokemon, target: Pokemon, move: Move): boolean { user.scene.currentBattle.moneyScattered += user.scene.getWaveMoneyAmount(0.2); - user.scene.queueMessage("Coins were scattered everywhere!"); + user.scene.queueMessage(i18next.t("moveTriggers:coinsScatteredEverywhere")); return true; } } @@ -5665,7 +5718,7 @@ export class DestinyBondAttr extends MoveEffectAttr { * @returns true */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - user.scene.queueMessage(`${getPokemonMessage(user, " is trying\nto take its foe down with it!")}`); + user.scene.queueMessage(`${i18next.t("moveTriggers:tryingToTakeFoeDown", {pokemonName: getPokemonNameWithAffix(user)})}`); user.addTag(BattlerTagType.DESTINY_BOND, undefined, move.id, user.id); return true; } @@ -5704,8 +5757,7 @@ export class AttackedByItemAttr extends MoveAttr { } const itemName = heldItems[0]?.type?.name ?? "item"; - const attackedByItemString = ` is about to be attacked by its ${itemName}!`; - target.scene.queueMessage(getPokemonMessage(target, attackedByItemString)); + target.scene.queueMessage(i18next.t("moveTriggers:attackedByItem", {pokemonName: getPokemonNameWithAffix(target), itemName: itemName})); return true; }; @@ -5739,7 +5791,7 @@ const failIfDampCondition: MoveConditionFunc = (user, target, move) => { user.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled)); // Queue a message if an ability prevented usage of the move if (cancelled.value) { - user.scene.queueMessage(getPokemonMessage(user, ` cannot use ${move.name}!`)); + user.scene.queueMessage(i18next.t("moveTriggers:cannotUseMove", {pokemonName: getPokemonNameWithAffix(user), moveName: move.name})); } return !cancelled.value; }; @@ -5860,7 +5912,7 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr { getCondition(): MoveConditionFunc { return (user, target, move) => { const moveHistory = target.getLastXMoves(); - return !!moveHistory.length; + return moveHistory.length !== 0; }; } } @@ -5965,7 +6017,7 @@ export function initMoves() { .attr(OneHitKOAttr) .attr(OneHitKOAccuracyAttr), new AttackMove(Moves.RAZOR_WIND, Type.NORMAL, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 1) - .attr(ChargeAttr, ChargeAnim.RAZOR_WIND_CHARGING, "whipped\nup a whirlwind!") + .attr(ChargeAttr, ChargeAnim.RAZOR_WIND_CHARGING, i18next.t("moveTriggers:whippedUpAWhirlwind", {pokemonName: "{USER}"})) .attr(HighCritAttr) .windMove() .ignoresVirtual() @@ -5985,7 +6037,7 @@ export function initMoves() { .hidesTarget() .windMove(), new AttackMove(Moves.FLY, Type.FLYING, MoveCategory.PHYSICAL, 90, 95, 15, -1, 0, 1) - .attr(ChargeAttr, ChargeAnim.FLY_CHARGING, "flew\nup high!", BattlerTagType.FLYING) + .attr(ChargeAttr, ChargeAnim.FLY_CHARGING, i18next.t("moveTriggers:flewUpHigh", {pokemonName: "{USER}"}), BattlerTagType.FLYING) .condition(failOnGravityCondition) .ignoresVirtual(), new AttackMove(Moves.BIND, Type.NORMAL, MoveCategory.PHYSICAL, 15, 85, 20, -1, 0, 1) @@ -6133,7 +6185,7 @@ export function initMoves() { .slicingMove() .target(MoveTarget.ALL_NEAR_ENEMIES), new AttackMove(Moves.SOLAR_BEAM, Type.GRASS, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 1) - .attr(SunlightChargeAttr, ChargeAnim.SOLAR_BEAM_CHARGING, "took\nin sunlight!") + .attr(SunlightChargeAttr, ChargeAnim.SOLAR_BEAM_CHARGING, i18next.t("moveTriggers:tookInSunlight", {pokemonName: "{USER}"})) .attr(AntiSunlightPowerDecreaseAttr) .ignoresVirtual(), new StatusMove(Moves.POISON_POWDER, Type.POISON, 75, 35, -1, 0, 1) @@ -6182,7 +6234,7 @@ export function initMoves() { .attr(HitsTagAttr, BattlerTagType.UNDERGROUND, false) .makesContact(false), new AttackMove(Moves.DIG, Type.GROUND, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 1) - .attr(ChargeAttr, ChargeAnim.DIG_CHARGING, "dug a hole!", BattlerTagType.UNDERGROUND) + .attr(ChargeAttr, ChargeAnim.DIG_CHARGING, i18next.t("moveTriggers:dugAHole", {pokemonName: "{USER}"}), BattlerTagType.UNDERGROUND) .ignoresVirtual(), new StatusMove(Moves.TOXIC, Type.POISON, 90, 10, -1, 0, 1) .attr(StatusEffectAttr, StatusEffect.TOXIC) @@ -6278,7 +6330,7 @@ export function initMoves() { new AttackMove(Moves.SWIFT, Type.NORMAL, MoveCategory.SPECIAL, 60, -1, 20, -1, 0, 1) .target(MoveTarget.ALL_NEAR_ENEMIES), new AttackMove(Moves.SKULL_BASH, Type.NORMAL, MoveCategory.PHYSICAL, 130, 100, 10, -1, 0, 1) - .attr(ChargeAttr, ChargeAnim.SKULL_BASH_CHARGING, "lowered\nits head!", null, true) + .attr(ChargeAttr, ChargeAnim.SKULL_BASH_CHARGING, i18next.t("moveTriggers:loweredItsHead", {pokemonName: "{USER}"}), null, true) .attr(StatChangeAttr, BattleStat.DEF, 1, true) .ignoresVirtual(), new AttackMove(Moves.SPIKE_CANNON, Type.NORMAL, MoveCategory.PHYSICAL, 20, 100, 15, -1, 0, 1) @@ -6317,7 +6369,7 @@ export function initMoves() { new StatusMove(Moves.LOVELY_KISS, Type.NORMAL, 75, 10, -1, 0, 1) .attr(StatusEffectAttr, StatusEffect.SLEEP), new AttackMove(Moves.SKY_ATTACK, Type.FLYING, MoveCategory.PHYSICAL, 140, 90, 5, 30, 0, 1) - .attr(ChargeAttr, ChargeAnim.SKY_ATTACK_CHARGING, "is glowing!") + .attr(ChargeAttr, ChargeAnim.SKY_ATTACK_CHARGING, i18next.t("moveTriggers:isGlowing", {pokemonName: "{USER}"})) .attr(HighCritAttr) .attr(FlinchAttr) .makesContact(false) @@ -6442,7 +6494,9 @@ export function initMoves() { new StatusMove(Moves.SWEET_KISS, Type.FAIRY, 75, 10, -1, 0, 2) .attr(ConfuseAttr), new SelfStatusMove(Moves.BELLY_DRUM, Type.NORMAL, -1, 10, -1, 0, 2) - .attr(HalfHpStatMaxAttr, BattleStat.ATK), + .attr(CutHpStatBoostAttr, [BattleStat.ATK], 12, 2, (user) => { + user.scene.queueMessage(i18next.t("moveTriggers:cutOwnHpAndMaximizedStat", {pokemonName: getPokemonNameWithAffix(user), statName: getBattleStatName(BattleStat.ATK)})); + }), new AttackMove(Moves.SLUDGE_BOMB, Type.POISON, MoveCategory.SPECIAL, 90, 100, 10, 30, 0, 2) .attr(StatusEffectAttr, StatusEffect.POISON) .ballBombMove(), @@ -6491,7 +6545,7 @@ export function initMoves() { .attr(HitHealAttr) .triageMove(), new SelfStatusMove(Moves.ENDURE, Type.NORMAL, -1, 10, -1, 4, 2) - .attr(EndureAttr), + .attr(ProtectAttr, BattlerTagType.ENDURING), new StatusMove(Moves.CHARM, Type.FAIRY, 100, 20, -1, 0, 2) .attr(StatChangeAttr, BattleStat.ATK, -2), new AttackMove(Moves.ROLLOUT, Type.ROCK, MoveCategory.PHYSICAL, 30, 90, 20, -1, 0, 2) @@ -6523,7 +6577,7 @@ export function initMoves() { .target(MoveTarget.ALL_ENEMIES) .ignoresVirtual(), new StatusMove(Moves.HEAL_BELL, Type.NORMAL, -1, 5, -1, 0, 2) - .attr(PartyStatusCureAttr, "A bell chimed!", Abilities.SOUNDPROOF) + .attr(PartyStatusCureAttr, i18next.t("moveTriggers:bellChimed"), Abilities.SOUNDPROOF) .soundBased() .target(MoveTarget.PARTY), new AttackMove(Moves.RETURN, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 20, -1, 0, 2) @@ -6626,7 +6680,8 @@ export function initMoves() { .attr(StatChangeAttr, BattleStat.SPDEF, -1) .ballBombMove(), new AttackMove(Moves.FUTURE_SIGHT, Type.PSYCHIC, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 2) - .attr(DelayedAttackAttr, ArenaTagType.FUTURE_SIGHT, ChargeAnim.FUTURE_SIGHT_CHARGING, "foresaw\nan attack!"), + .partial() + .attr(DelayedAttackAttr, ArenaTagType.FUTURE_SIGHT, ChargeAnim.FUTURE_SIGHT_CHARGING, i18next.t("moveTriggers:foresawAnAttack", {pokemonName: "{USER}"})), new AttackMove(Moves.ROCK_SMASH, Type.FIGHTING, MoveCategory.PHYSICAL, 40, 100, 15, 50, 0, 2) .attr(StatChangeAttr, BattleStat.DEF, -1), new AttackMove(Moves.WHIRLPOOL, Type.WATER, MoveCategory.SPECIAL, 35, 85, 15, -1, 0, 2) @@ -6747,7 +6802,7 @@ export function initMoves() { .makesContact(false) .partial(), new AttackMove(Moves.DIVE, Type.WATER, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 3) - .attr(ChargeAttr, ChargeAnim.DIVE_CHARGING, "hid\nunderwater!", BattlerTagType.UNDERWATER) + .attr(ChargeAttr, ChargeAnim.DIVE_CHARGING, i18next.t("moveTriggers:hidUnderwater", {pokemonName: "{USER}"}), BattlerTagType.UNDERWATER) .ignoresVirtual(), new AttackMove(Moves.ARM_THRUST, Type.FIGHTING, MoveCategory.PHYSICAL, 15, 100, 20, -1, 0, 3) .attr(MultiHitAttr), @@ -6803,7 +6858,7 @@ export function initMoves() { .attr(MovePowerMultiplierAttr, (user, target, move) => [WeatherType.SUNNY, WeatherType.RAIN, WeatherType.SANDSTORM, WeatherType.HAIL, WeatherType.SNOW, WeatherType.FOG, WeatherType.HEAVY_RAIN, WeatherType.HARSH_SUN].includes(user.scene.arena.weather?.weatherType) && !user.scene.arena.weather?.isEffectSuppressed(user.scene) ? 2 : 1) .ballBombMove(), new StatusMove(Moves.AROMATHERAPY, Type.GRASS, -1, 5, -1, 0, 3) - .attr(PartyStatusCureAttr, "A soothing aroma wafted through the area!", Abilities.SAP_SIPPER) + .attr(PartyStatusCureAttr, i18next.t("moveTriggers:soothingAromaWaftedThroughArea"), Abilities.SAP_SIPPER) .target(MoveTarget.PARTY), new StatusMove(Moves.FAKE_TEARS, Type.DARK, 100, 20, -1, 0, 3) .attr(StatChangeAttr, BattleStat.SPDEF, -2), @@ -6878,7 +6933,7 @@ export function initMoves() { new SelfStatusMove(Moves.BULK_UP, Type.FIGHTING, -1, 20, -1, 0, 3) .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF ], 1, true), new AttackMove(Moves.BOUNCE, Type.FLYING, MoveCategory.PHYSICAL, 85, 85, 5, 30, 0, 3) - .attr(ChargeAttr, ChargeAnim.BOUNCE_CHARGING, "sprang up!", BattlerTagType.FLYING) + .attr(ChargeAttr, ChargeAnim.BOUNCE_CHARGING, i18next.t("moveTriggers:sprangUp", {pokemonName: "{USER}"}), BattlerTagType.FLYING) .attr(StatusEffectAttr, StatusEffect.PARALYSIS) .condition(failOnGravityCondition) .ignoresVirtual(), @@ -6914,7 +6969,8 @@ export function initMoves() { .attr(ConfuseAttr) .pulseMove(), new AttackMove(Moves.DOOM_DESIRE, Type.STEEL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 3) - .attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, "chose\nDoom Desire as its destiny!"), + .partial() + .attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, i18next.t("moveTriggers:choseDoomDesireAsDestiny", {pokemonName: "{USER}"})), new AttackMove(Moves.PSYCHO_BOOST, Type.PSYCHIC, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 3) .attr(StatChangeAttr, BattleStat.SPATK, -2, true), new SelfStatusMove(Moves.ROOST, Type.FLYING, -1, 5, -1, 0, 4) @@ -6977,12 +7033,13 @@ export function initMoves() { .unimplemented(), new StatusMove(Moves.PSYCHO_SHIFT, Type.PSYCHIC, 100, 10, -1, 0, 4) .attr(PsychoShiftEffectAttr) - .condition((user, target, move) => (user.status?.effect === StatusEffect.BURN - || user.status?.effect === StatusEffect.POISON - || user.status?.effect === StatusEffect.TOXIC - || user.status?.effect === StatusEffect.PARALYSIS - || user.status?.effect === StatusEffect.SLEEP) - && target.canSetStatus(user.status?.effect, false, false, user) + .condition((user, target, move) => { + let statusToApply = user.hasAbility(Abilities.COMATOSE) ? StatusEffect.SLEEP : undefined; + if (user.status?.effect && isNonVolatileStatusEffect(user.status.effect)) { + statusToApply = user.status.effect; + } + return statusToApply && target.canSetStatus(statusToApply, false, false, user); + } ), new AttackMove(Moves.TRUMP_CARD, Type.NORMAL, MoveCategory.SPECIAL, -1, -1, 5, -1, 0, 4) .makesContact() @@ -7227,7 +7284,7 @@ export function initMoves() { .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, true) .windMove(), new AttackMove(Moves.SHADOW_FORCE, Type.GHOST, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 4) - .attr(ChargeAttr, ChargeAnim.SHADOW_FORCE_CHARGING, "vanished\ninstantly!", BattlerTagType.HIDDEN) + .attr(ChargeAttr, ChargeAnim.SHADOW_FORCE_CHARGING, i18next.t("moveTriggers:vanishedInstantly", {pokemonName: "{USER}"}), BattlerTagType.HIDDEN) .ignoresProtect() .ignoresVirtual(), new SelfStatusMove(Moves.HONE_CLAWS, Type.DARK, -1, 15, -1, 0, 5) @@ -7269,7 +7326,7 @@ export function initMoves() { new AttackMove(Moves.STORM_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5) .attr(CritOnlyAttr), new AttackMove(Moves.FLAME_BURST, Type.FIRE, MoveCategory.SPECIAL, 70, 100, 15, -1, 0, 5) - .partial(), + .attr(FlameBurstAttr), new AttackMove(Moves.SLUDGE_WAVE, Type.POISON, MoveCategory.SPECIAL, 95, 100, 10, 10, 0, 5) .attr(StatusEffectAttr, StatusEffect.POISON) .target(MoveTarget.ALL_NEAR_OTHERS), @@ -7342,7 +7399,7 @@ export function initMoves() { MovePowerMultiplierAttr, (user, target, move) => target.status || target.hasAbility(Abilities.COMATOSE)? 2 : 1), new AttackMove(Moves.SKY_DROP, Type.FLYING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5) - .attr(ChargeAttr, ChargeAnim.SKY_DROP_CHARGING, "took {TARGET}\ninto the sky!", BattlerTagType.FLYING) // TODO: Add 2nd turn message + .attr(ChargeAttr, ChargeAnim.SKY_DROP_CHARGING, i18next.t("moveTriggers:tookTargetIntoSky", {pokemonName: "{USER}", targetName: "{TARGET}"}), BattlerTagType.FLYING) // TODO: Add 2nd turn message .condition(failOnGravityCondition) .ignoresVirtual(), new SelfStatusMove(Moves.SHIFT_GEAR, Type.STEEL, -1, 10, -1, 0, 5) @@ -7462,11 +7519,11 @@ export function initMoves() { .attr(StatChangeAttr, BattleStat.SPATK, 1, true) .danceMove(), new AttackMove(Moves.FREEZE_SHOCK, Type.ICE, MoveCategory.PHYSICAL, 140, 90, 5, 30, 0, 5) - .attr(ChargeAttr, ChargeAnim.FREEZE_SHOCK_CHARGING, "became cloaked\nin a freezing light!") + .attr(ChargeAttr, ChargeAnim.FREEZE_SHOCK_CHARGING, i18next.t("moveTriggers:becameCloakedInFreezingLight", {pokemonName: "{USER}"})) .attr(StatusEffectAttr, StatusEffect.PARALYSIS) .makesContact(false), new AttackMove(Moves.ICE_BURN, Type.ICE, MoveCategory.SPECIAL, 140, 90, 5, 30, 0, 5) - .attr(ChargeAttr, ChargeAnim.ICE_BURN_CHARGING, "became cloaked\nin freezing air!") + .attr(ChargeAttr, ChargeAnim.ICE_BURN_CHARGING, i18next.t("moveTriggers:becameCloakedInFreezingAir", {pokemonName: "{USER}"})) .attr(StatusEffectAttr, StatusEffect.BURN) .ignoresVirtual(), new AttackMove(Moves.SNARL, Type.DARK, MoveCategory.SPECIAL, 55, 95, 15, 100, 0, 5) @@ -7480,10 +7537,10 @@ export function initMoves() { .attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF, BattleStat.SPD ], -1, true), new AttackMove(Moves.FUSION_FLARE, Type.FIRE, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 5) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) - .partial(), + .attr(LastMoveDoublePowerAttr, Moves.FUSION_BOLT), new AttackMove(Moves.FUSION_BOLT, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 5) - .makesContact(false) - .partial(), + .attr(LastMoveDoublePowerAttr, Moves.FUSION_FLARE) + .makesContact(false), new AttackMove(Moves.FLYING_PRESS, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 95, 10, -1, 0, 6) .attr(MinimizeAccuracyAttr) .attr(FlyingTypeMultiplierAttr) @@ -7508,7 +7565,7 @@ export function initMoves() { new AttackMove(Moves.FELL_STINGER, Type.BUG, MoveCategory.PHYSICAL, 50, 100, 25, -1, 0, 6) .attr(PostVictoryStatChangeAttr, BattleStat.ATK, 3, true ), new AttackMove(Moves.PHANTOM_FORCE, Type.GHOST, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6) - .attr(ChargeAttr, ChargeAnim.PHANTOM_FORCE_CHARGING, "vanished\ninstantly!", BattlerTagType.HIDDEN) + .attr(ChargeAttr, ChargeAnim.PHANTOM_FORCE_CHARGING, i18next.t("moveTriggers:vanishedInstantly", {pokemonName: "{USER}"}), BattlerTagType.HIDDEN) .ignoresProtect() .ignoresVirtual(), new StatusMove(Moves.TRICK_OR_TREAT, Type.GHOST, 100, 20, -1, 0, 6) @@ -7610,7 +7667,7 @@ export function initMoves() { .powderMove() .unimplemented(), new SelfStatusMove(Moves.GEOMANCY, Type.FAIRY, -1, 10, -1, 0, 6) - .attr(ChargeAttr, ChargeAnim.GEOMANCY_CHARGING, "is charging its power!") + .attr(ChargeAttr, ChargeAnim.GEOMANCY_CHARGING, i18next.t("moveTriggers:isChargingPower", {pokemonName: "{USER}"})) .attr(StatChangeAttr, [ BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 2, true) .ignoresVirtual(), new StatusMove(Moves.MAGNETIC_FLUX, Type.ELECTRIC, -1, 20, -1, 0, 6) @@ -7816,7 +7873,7 @@ export function initMoves() { .condition((user, target, move) => target.summonData.battleStats[BattleStat.ATK] > -6) .triageMove(), new AttackMove(Moves.SOLAR_BLADE, Type.GRASS, MoveCategory.PHYSICAL, 125, 100, 10, -1, 0, 7) - .attr(SunlightChargeAttr, ChargeAnim.SOLAR_BLADE_CHARGING, "is glowing!") + .attr(SunlightChargeAttr, ChargeAnim.SOLAR_BLADE_CHARGING, i18next.t("moveTriggers:isGlowing", {pokemonName: "{USER}"})) .attr(AntiSunlightPowerDecreaseAttr) .slicingMove(), new AttackMove(Moves.LEAFAGE, Type.GRASS, MoveCategory.PHYSICAL, 40, 100, 40, -1, 0, 7) @@ -7856,7 +7913,7 @@ export function initMoves() { }) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) .attr(RemoveTypeAttr, Type.FIRE, (user) => { - user.scene.queueMessage(getPokemonMessage(user, " burned itself out!")); + user.scene.queueMessage(i18next.t("moveTriggers:burnedItselfOut", {pokemonName: getPokemonNameWithAffix(user)})); }), new StatusMove(Moves.SPEED_SWAP, Type.PSYCHIC, -1, 10, -1, 0, 7) .unimplemented(), @@ -7878,12 +7935,12 @@ export function initMoves() { new StatusMove(Moves.INSTRUCT, Type.PSYCHIC, -1, 15, -1, 0, 7) .unimplemented(), new AttackMove(Moves.BEAK_BLAST, Type.FLYING, MoveCategory.PHYSICAL, 100, 100, 15, -1, 5, 7) - .attr(ChargeAttr, ChargeAnim.BEAK_BLAST_CHARGING, "started\nheating up its beak!", undefined, false, true, -3) + .attr(ChargeAttr, ChargeAnim.BEAK_BLAST_CHARGING, i18next.t("moveTriggers:startedHeatingUpBeak", {pokemonName: "{USER}"}), undefined, false, true, -3) .ballBombMove() .makesContact(false) .partial(), new AttackMove(Moves.CLANGING_SCALES, Type.DRAGON, MoveCategory.SPECIAL, 110, 100, 5, -1, 0, 7) - .attr(StatChangeAttr, BattleStat.DEF, -1, true) + .attr(StatChangeAttr, BattleStat.DEF, -1, true, null, true, false, MoveEffectTrigger.HIT, true) .soundBased() .target(MoveTarget.ALL_NEAR_ENEMIES), new AttackMove(Moves.DRAGON_HAMMER, Type.DRAGON, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 7), @@ -8234,7 +8291,7 @@ export function initMoves() { .makesContact(false) .partial(), new AttackMove(Moves.METEOR_BEAM, Type.ROCK, MoveCategory.SPECIAL, 120, 90, 10, 100, 0, 8) - .attr(ChargeAttr, ChargeAnim.METEOR_BEAM_CHARGING, "is overflowing\nwith space power!", null, true) + .attr(ChargeAttr, ChargeAnim.METEOR_BEAM_CHARGING, i18next.t("moveTriggers:isOverflowingWithSpacePower", {pokemonName: "{USER}"}), null, true) .attr(StatChangeAttr, BattleStat.SPATK, 1, true) .ignoresVirtual(), new AttackMove(Moves.SHELL_SIDE_ARM, Type.POISON, MoveCategory.SPECIAL, 90, 100, 10, 20, 0, 8) @@ -8530,8 +8587,8 @@ export function initMoves() { new AttackMove(Moves.ICE_SPINNER, Type.ICE, MoveCategory.PHYSICAL, 80, 100, 15, -1, 0, 9) .attr(ClearTerrainAttr), new AttackMove(Moves.GLAIVE_RUSH, Type.DRAGON, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 9) - .attr(AlwaysGetHitAttr) - .attr(ReceiveDoubleDamageAttr), + .attr(AddBattlerTagAttr, BattlerTagType.ALWAYS_GET_HIT, true, false, 0, 0, true) + .attr(AddBattlerTagAttr, BattlerTagType.RECEIVE_DOUBLE_DAMAGE, true, false, 0, 0, true), new StatusMove(Moves.REVIVAL_BLESSING, Type.NORMAL, -1, 1, -1, 0, 9) .triageMove() .attr(RevivalBlessingAttr) @@ -8633,7 +8690,7 @@ export function initMoves() { return userTypes.includes(Type.ELECTRIC); }) .attr(RemoveTypeAttr, Type.ELECTRIC, (user) => { - user.scene.queueMessage(getPokemonMessage(user, " used up all its electricity!")); + user.scene.queueMessage(i18next.t("moveTriggers:usedUpAllElectricity", {pokemonName: getPokemonNameWithAffix(user)})); }), new AttackMove(Moves.GIGATON_HAMMER, Type.STEEL, MoveCategory.PHYSICAL, 160, 100, 5, -1, 0, 9) .makesContact(false) @@ -8729,8 +8786,8 @@ export function initMoves() { new AttackMove(Moves.MALIGNANT_CHAIN, Type.POISON, MoveCategory.SPECIAL, 100, 100, 5, 50, 0, 9) .attr(StatusEffectAttr, StatusEffect.TOXIC) ); - allMoves.map(m=>{ - if (m.getAttrs(StatChangeAttr).some(a=> a.selfTarget && a.levels < 0)) { + allMoves.map(m => { + if (m.getAttrs(StatChangeAttr).some(a => a.selfTarget && a.levels < 0)) { selfStatLowerMoves.push(m.id); } }); diff --git a/src/data/pokemon-evolutions.ts b/src/data/pokemon-evolutions.ts index 696cf006ad0..236d174492f 100644 --- a/src/data/pokemon-evolutions.ts +++ b/src/data/pokemon-evolutions.ts @@ -1145,6 +1145,11 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.PAWMOT, 32, null, null) ], [Species.TANDEMAUS]: [ + new SpeciesFormEvolution(Species.MAUSHOLD, "", "three", 25, null, new SpeciesEvolutionCondition(p => { + let ret = false; + p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id); + return ret; + })), new SpeciesEvolution(Species.MAUSHOLD, 25, null, null) ], [Species.FIDOUGH]: [ diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index d6fe12a8186..93781063061 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -9,6 +9,7 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { TimeOfDay } from "#enums/time-of-day"; import { getPokemonNameWithAffix } from "#app/messages.js"; +import i18next from "i18next"; export enum FormChangeItem { NONE, @@ -138,7 +139,7 @@ export class SpeciesFormChange { public formKey: string; public trigger: SpeciesFormChangeTrigger; public quiet: boolean; - public conditions: SpeciesFormChangeCondition[]; + public readonly conditions: SpeciesFormChangeCondition[]; constructor(speciesId: Species, preFormKey: string, evoFormKey: string, trigger: SpeciesFormChangeTrigger, quiet: boolean = false, ...conditions: SpeciesFormChangeCondition[]) { this.speciesId = speciesId; @@ -357,28 +358,27 @@ export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger { export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: SpeciesFormChange, preName: string): string { const isMega = formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -1; const isGmax = formChange.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1; - const isEmax = formChange.formKey.indexOf("eternamax") > -1; + const isEmax = formChange.formKey.indexOf(SpeciesFormKey.ETERNAMAX) > -1; const isRevert = !isMega && formChange.formKey === pokemon.species.forms[0].formKey; - const prefix = !pokemon.isPlayer() ? pokemon.hasTrainer() ? "Foe " : "Wild " : "Your "; if (isMega) { - return `${prefix}${preName} Mega Evolved\ninto ${pokemon.name}!`; + return i18next.t("battlePokemonForm:megaChange", { preName, pokemonName: pokemon.name }); } if (isGmax) { - return `${prefix}${preName} Gigantamaxed\ninto ${pokemon.name}!`; + return i18next.t("battlePokemonForm:gigantamaxChange", { preName, pokemonName: pokemon.name }); } if (isEmax) { - return `${prefix}${preName} Eternamaxed\ninto ${pokemon.name}!`; + return i18next.t("battlePokemonForm:eternamaxChange", { preName, pokemonName: pokemon.name }); } if (isRevert) { - return `${prefix}${getPokemonNameWithAffix(pokemon)} reverted\nto its original form!`; + return i18next.t("battlePokemonForm:revertChange", { pokemonName: getPokemonNameWithAffix(pokemon) }); } - return `${prefix}${preName} changed form!`; + return i18next.t("battlePokemonForm:formChange", { preName }); } /** * Gives a condition for form changing checking if a species is registered as caught in the player's dex data. * Used for fusion forms such as Kyurem and Necrozma. - * @param species + * @param species {@linkcode Species} * @returns A {@linkcode SpeciesFormChangeCondition} checking if that species is registered as caught */ function getSpeciesDependentFormChangeCondition(species: Species): SpeciesFormChangeCondition { diff --git a/src/data/pokemon-level-moves.ts b/src/data/pokemon-level-moves.ts index 2ba8ccdf463..ccf6ac022ae 100644 --- a/src/data/pokemon-level-moves.ts +++ b/src/data/pokemon-level-moves.ts @@ -17287,7 +17287,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { ], [Species.DIPPLIN]: [ [ EVOLVE_MOVE, Moves.DOUBLE_HIT ], - [ RELEARN_MOVE, Moves.INFESTATION ], + [ RELEARN_MOVE, Moves.DRAGON_CHEER ], // Custom [ 1, Moves.WITHDRAW ], [ 1, Moves.SWEET_SCENT ], [ 1, Moves.RECYCLE ], @@ -18666,7 +18666,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 48, Moves.PIKA_PAPOW ], ], 3: [ - [ EVOLVE_MOVE, Moves.METEOR_MASH ], + [ 1, Moves.METEOR_MASH ], [ 1, Moves.TAIL_WHIP ], [ 1, Moves.GROWL ], [ 1, Moves.THUNDER_SHOCK ], @@ -18690,7 +18690,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 48, Moves.PIKA_PAPOW ], ], 4: [ - [ EVOLVE_MOVE, Moves.ICICLE_CRASH ], + [ 1, Moves.ICICLE_CRASH ], [ 1, Moves.TAIL_WHIP ], [ 1, Moves.GROWL ], [ 1, Moves.THUNDER_SHOCK ], @@ -18714,7 +18714,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 48, Moves.PIKA_PAPOW ], ], 5: [ - [ EVOLVE_MOVE, Moves.DRAINING_KISS ], + [ 1, Moves.DRAINING_KISS ], [ 1, Moves.TAIL_WHIP ], [ 1, Moves.GROWL ], [ 1, Moves.THUNDER_SHOCK ], @@ -18738,7 +18738,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 48, Moves.PIKA_PAPOW ], ], 6: [ - [ EVOLVE_MOVE, Moves.ELECTRIC_TERRAIN ], + [ 1, Moves.ELECTRIC_TERRAIN ], [ 1, Moves.TAIL_WHIP ], [ 1, Moves.GROWL ], [ 1, Moves.THUNDER_SHOCK ], @@ -18762,7 +18762,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 48, Moves.PIKA_PAPOW ], ], 7: [ - [ EVOLVE_MOVE, Moves.FLYING_PRESS ], + [ 1, Moves.FLYING_PRESS ], [ 1, Moves.TAIL_WHIP ], [ 1, Moves.GROWL ], [ 1, Moves.THUNDER_SHOCK ], @@ -18886,7 +18886,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { }, [Species.ROTOM]: { 1: [ - [ EVOLVE_MOVE, Moves.OVERHEAT ], + [ 1, Moves.OVERHEAT ], [ 1, Moves.DOUBLE_TEAM ], [ 1, Moves.ASTONISH ], [ 5, Moves.THUNDER_SHOCK ], @@ -18902,7 +18902,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 55, Moves.UPROAR ], ], 2: [ - [ EVOLVE_MOVE, Moves.HYDRO_PUMP ], + [ 1, Moves.HYDRO_PUMP ], [ 1, Moves.DOUBLE_TEAM ], [ 1, Moves.ASTONISH ], [ 5, Moves.THUNDER_SHOCK ], @@ -18918,7 +18918,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 55, Moves.UPROAR ], ], 3: [ - [ EVOLVE_MOVE, Moves.BLIZZARD ], + [ 1, Moves.BLIZZARD ], [ 1, Moves.DOUBLE_TEAM ], [ 1, Moves.ASTONISH ], [ 5, Moves.THUNDER_SHOCK ], @@ -18934,7 +18934,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 55, Moves.UPROAR ], ], 4: [ - [ EVOLVE_MOVE, Moves.AIR_SLASH ], + [ 1, Moves.AIR_SLASH ], [ 1, Moves.DOUBLE_TEAM ], [ 1, Moves.ASTONISH ], [ 5, Moves.THUNDER_SHOCK ], @@ -18950,7 +18950,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = { [ 55, Moves.UPROAR ], ], 5: [ - [ EVOLVE_MOVE, Moves.LEAF_STORM ], + [ 1, Moves.LEAF_STORM ], [ 1, Moves.DOUBLE_TEAM ], [ 1, Moves.ASTONISH ], [ 5, Moves.THUNDER_SHOCK ], diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 3b09f8f7698..64e3fa70ad6 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -301,7 +301,7 @@ export abstract class PokemonSpeciesForm { let variantDataIndex: integer|string = this.speciesId; const species = getPokemonSpecies(this.speciesId); if (species.forms.length > 0) { - formkey = species.forms[formIndex]?.formKey; + formkey = species.forms[formIndex]?.formSpriteKey; if (formkey) { variantDataIndex = `${this.speciesId}-${formkey}`; } @@ -435,7 +435,7 @@ export abstract class PokemonSpeciesForm { for (const moveId of moveset) { if (speciesEggMoves.hasOwnProperty(rootSpeciesId)) { const eggMoveIndex = speciesEggMoves[rootSpeciesId].findIndex(m => m === moveId); - if (eggMoveIndex > -1 && eggMoves & Math.pow(2, eggMoveIndex)) { + if (eggMoveIndex > -1 && (eggMoves & (1 << eggMoveIndex))) { continue; } } @@ -630,7 +630,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali } if (key) { - return i18next.t(`pokemonForm:${key}`, {pokemonName: this.name}); + return i18next.t(`battlePokemonForm:${key}`, {pokemonName: this.name}); } } return this.name; @@ -1671,7 +1671,7 @@ export function initSpecies() { new PokemonForm("Fairy", "fairy", Type.FAIRY, null, 3.2, 320, Abilities.MULTITYPE, Abilities.NONE, Abilities.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 324), new PokemonForm("???", "unknown", Type.UNKNOWN, null, 3.2, 320, Abilities.MULTITYPE, Abilities.NONE, Abilities.NONE, 720, 120, 120, 120, 120, 120, 120, 3, 0, 324), ), - new PokemonSpecies(Species.VICTINI, 4, false, false, true, "Victory Pokémon", Type.PSYCHIC, Type.FIRE, 0.4, 4, Abilities.VICTORY_STAR, Abilities.NONE, Abilities.NONE, 600, 100, 100, 100, 100, 100, 100, 3, 100, 300, GrowthRate.SLOW, null, false), + new PokemonSpecies(Species.VICTINI, 5, false, false, true, "Victory Pokémon", Type.PSYCHIC, Type.FIRE, 0.4, 4, Abilities.VICTORY_STAR, Abilities.NONE, Abilities.NONE, 600, 100, 100, 100, 100, 100, 100, 3, 100, 300, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.SNIVY, 5, false, false, false, "Grass Snake Pokémon", Type.GRASS, null, 0.6, 8.1, Abilities.OVERGROW, Abilities.NONE, Abilities.CONTRARY, 308, 45, 45, 55, 45, 55, 63, 45, 70, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.SERVINE, 5, false, false, false, "Grass Snake Pokémon", Type.GRASS, null, 0.8, 16, Abilities.OVERGROW, Abilities.NONE, Abilities.CONTRARY, 413, 60, 60, 75, 60, 75, 83, 45, 70, 145, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.SERPERIOR, 5, false, false, false, "Regal Pokémon", Type.GRASS, null, 3.3, 63, Abilities.OVERGROW, Abilities.NONE, Abilities.CONTRARY, 528, 75, 75, 95, 75, 95, 113, 45, 70, 238, GrowthRate.MEDIUM_SLOW, 87.5, false), @@ -2459,8 +2459,8 @@ export function initSpecies() { new PokemonSpecies(Species.PAWMOT, 9, false, false, false, "Hands-On Pokémon", Type.ELECTRIC, Type.FIGHTING, 0.9, 41, Abilities.VOLT_ABSORB, Abilities.NATURAL_CURE, Abilities.IRON_FIST, 490, 70, 115, 70, 70, 60, 105, 45, 50, 245, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.TANDEMAUS, 9, false, false, false, "Couple Pokémon", Type.NORMAL, null, 0.3, 1.8, Abilities.RUN_AWAY, Abilities.PICKUP, Abilities.OWN_TEMPO, 305, 50, 50, 45, 40, 45, 75, 150, 50, 61, GrowthRate.FAST, null, false), new PokemonSpecies(Species.MAUSHOLD, 9, false, false, false, "Family Pokémon", Type.NORMAL, null, 0.3, 2.3, Abilities.FRIEND_GUARD, Abilities.CHEEK_POUCH, Abilities.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165, GrowthRate.FAST, null, false, false, - new PokemonForm("Family of Four", "four", Type.NORMAL, null, 0.3, 2.3, Abilities.FRIEND_GUARD, Abilities.CHEEK_POUCH, Abilities.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165), - new PokemonForm("Family of Three", "three", Type.NORMAL, null, 0.3, 2.8, Abilities.FRIEND_GUARD, Abilities.CHEEK_POUCH, Abilities.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165), + new PokemonForm("Family of Four", "four", Type.NORMAL, null, 0.3, 2.8, Abilities.FRIEND_GUARD, Abilities.CHEEK_POUCH, Abilities.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165), + new PokemonForm("Family of Three", "three", Type.NORMAL, null, 0.3, 2.3, Abilities.FRIEND_GUARD, Abilities.CHEEK_POUCH, Abilities.TECHNICIAN, 470, 74, 75, 70, 65, 75, 111, 75, 50, 165), ), new PokemonSpecies(Species.FIDOUGH, 9, false, false, false, "Puppy Pokémon", Type.FAIRY, null, 0.3, 10.9, Abilities.OWN_TEMPO, Abilities.NONE, Abilities.KLUTZ, 312, 37, 55, 70, 30, 55, 65, 190, 50, 62, GrowthRate.MEDIUM_SLOW, 50, false), new PokemonSpecies(Species.DACHSBUN, 9, false, false, false, "Dog Pokémon", Type.FAIRY, null, 0.5, 14.9, Abilities.WELL_BAKED_BODY, Abilities.NONE, Abilities.AROMA_VEIL, 477, 57, 80, 115, 50, 80, 95, 90, 50, 167, GrowthRate.MEDIUM_SLOW, 50, false), @@ -2682,71 +2682,71 @@ export const speciesStarters = { [Species.BULBASAUR]: 3, [Species.CHARMANDER]: 3, [Species.SQUIRTLE]: 3, - [Species.CATERPIE]: 1, + [Species.CATERPIE]: 2, [Species.WEEDLE]: 1, - [Species.PIDGEY]: 2, + [Species.PIDGEY]: 1, [Species.RATTATA]: 1, - [Species.SPEAROW]: 2, + [Species.SPEAROW]: 1, [Species.EKANS]: 2, - [Species.PIKACHU]: 4, + [Species.PIKACHU]: 3, [Species.SANDSHREW]: 2, [Species.NIDORAN_F]: 3, [Species.NIDORAN_M]: 3, - [Species.CLEFAIRY]: 4, + [Species.CLEFAIRY]: 3, [Species.VULPIX]: 3, - [Species.JIGGLYPUFF]: 4, - [Species.ZUBAT]: 2, - [Species.ODDISH]: 2, - [Species.PARAS]: 1, + [Species.JIGGLYPUFF]: 2, + [Species.ZUBAT]: 3, + [Species.ODDISH]: 3, + [Species.PARAS]: 2, [Species.VENONAT]: 2, - [Species.DIGLETT]: 3, - [Species.MEOWTH]: 4, + [Species.DIGLETT]: 2, + [Species.MEOWTH]: 3, [Species.PSYDUCK]: 2, [Species.MANKEY]: 4, [Species.GROWLITHE]: 4, - [Species.POLIWAG]: 3, - [Species.ABRA]: 3, + [Species.POLIWAG]: 2, + [Species.ABRA]: 4, [Species.MACHOP]: 3, - [Species.BELLSPROUT]: 3, + [Species.BELLSPROUT]: 2, [Species.TENTACOOL]: 3, [Species.GEODUDE]: 3, - [Species.PONYTA]: 3, + [Species.PONYTA]: 2, [Species.SLOWPOKE]: 3, - [Species.MAGNEMITE]: 3, - [Species.FARFETCHD]: 4, - [Species.DODUO]: 4, - [Species.SEEL]: 3, - [Species.GRIMER]: 3, - [Species.SHELLDER]: 4, - [Species.GASTLY]: 3, - [Species.ONIX]: 4, - [Species.DROWZEE]: 3, - [Species.KRABBY]: 2, + [Species.MAGNEMITE]: 4, + [Species.FARFETCHD]: 2, + [Species.DODUO]: 3, + [Species.SEEL]: 1, + [Species.GRIMER]: 2, + [Species.SHELLDER]: 5, + [Species.GASTLY]: 4, + [Species.ONIX]: 3, + [Species.DROWZEE]: 2, + [Species.KRABBY]: 3, [Species.VOLTORB]: 2, - [Species.EXEGGCUTE]: 4, + [Species.EXEGGCUTE]: 3, [Species.CUBONE]: 3, - [Species.HITMONLEE]: 5, - [Species.HITMONCHAN]: 5, - [Species.LICKITUNG]: 5, - [Species.KOFFING]: 3, + [Species.HITMONLEE]: 4, + [Species.HITMONCHAN]: 4, + [Species.LICKITUNG]: 3, + [Species.KOFFING]: 2, [Species.RHYHORN]: 3, - [Species.CHANSEY]: 5, + [Species.CHANSEY]: 3, [Species.TANGELA]: 3, - [Species.KANGASKHAN]: 5, - [Species.HORSEA]: 4, - [Species.GOLDEEN]: 3, - [Species.STARYU]: 4, - [Species.MR_MIME]: 4, + [Species.KANGASKHAN]: 4, + [Species.HORSEA]: 3, + [Species.GOLDEEN]: 2, + [Species.STARYU]: 3, + [Species.MR_MIME]: 3, [Species.SCYTHER]: 5, - [Species.JYNX]: 4, - [Species.ELECTABUZZ]: 5, - [Species.MAGMAR]: 5, + [Species.JYNX]: 3, + [Species.ELECTABUZZ]: 4, + [Species.MAGMAR]: 4, [Species.PINSIR]: 4, - [Species.TAUROS]: 5, - [Species.MAGIKARP]: 3, - [Species.LAPRAS]: 5, + [Species.TAUROS]: 4, + [Species.MAGIKARP]: 4, + [Species.LAPRAS]: 4, [Species.DITTO]: 2, - [Species.EEVEE]: 4, + [Species.EEVEE]: 3, [Species.PORYGON]: 4, [Species.OMANYTE]: 3, [Species.KABUTO]: 3, @@ -2759,57 +2759,57 @@ export const speciesStarters = { [Species.MEWTWO]: 8, [Species.MEW]: 6, - [Species.CHIKORITA]: 3, + [Species.CHIKORITA]: 2, [Species.CYNDAQUIL]: 3, [Species.TOTODILE]: 3, [Species.SENTRET]: 1, - [Species.HOOTHOOT]: 1, + [Species.HOOTHOOT]: 2, [Species.LEDYBA]: 1, [Species.SPINARAK]: 1, - [Species.CHINCHOU]: 3, - [Species.PICHU]: 3, - [Species.CLEFFA]: 3, - [Species.IGGLYBUFF]: 3, + [Species.CHINCHOU]: 2, + [Species.PICHU]: 2, + [Species.CLEFFA]: 2, + [Species.IGGLYBUFF]: 1, [Species.TOGEPI]: 3, [Species.NATU]: 2, - [Species.MAREEP]: 3, + [Species.MAREEP]: 2, [Species.MARILL]: 4, - [Species.SUDOWOODO]: 5, - [Species.HOPPIP]: 1, - [Species.AIPOM]: 3, + [Species.SUDOWOODO]: 3, + [Species.HOPPIP]: 2, + [Species.AIPOM]: 2, [Species.SUNKERN]: 1, [Species.YANMA]: 3, [Species.WOOPER]: 2, - [Species.MURKROW]: 4, - [Species.MISDREAVUS]: 3, + [Species.MURKROW]: 3, + [Species.MISDREAVUS]: 2, [Species.UNOWN]: 1, - [Species.WOBBUFFET]: 4, - [Species.GIRAFARIG]: 4, + [Species.WOBBUFFET]: 2, + [Species.GIRAFARIG]: 3, [Species.PINECO]: 2, - [Species.DUNSPARCE]: 4, - [Species.GLIGAR]: 4, - [Species.SNUBBULL]: 3, + [Species.DUNSPARCE]: 3, + [Species.GLIGAR]: 3, + [Species.SNUBBULL]: 2, [Species.QWILFISH]: 3, - [Species.SHUCKLE]: 4, + [Species.SHUCKLE]: 3, [Species.HERACROSS]: 5, [Species.SNEASEL]: 4, [Species.TEDDIURSA]: 4, [Species.SLUGMA]: 2, [Species.SWINUB]: 3, - [Species.CORSOLA]: 3, - [Species.REMORAID]: 3, - [Species.DELIBIRD]: 3, - [Species.MANTINE]: 4, - [Species.SKARMORY]: 5, - [Species.HOUNDOUR]: 4, + [Species.CORSOLA]: 2, + [Species.REMORAID]: 2, + [Species.DELIBIRD]: 2, + [Species.MANTINE]: 3, + [Species.SKARMORY]: 4, + [Species.HOUNDOUR]: 3, [Species.PHANPY]: 3, - [Species.STANTLER]: 4, - [Species.SMEARGLE]: 3, - [Species.TYROGUE]: 4, - [Species.SMOOCHUM]: 3, - [Species.ELEKID]: 4, - [Species.MAGBY]: 4, - [Species.MILTANK]: 5, + [Species.STANTLER]: 3, + [Species.SMEARGLE]: 1, + [Species.TYROGUE]: 2, + [Species.SMOOCHUM]: 2, + [Species.ELEKID]: 3, + [Species.MAGBY]: 3, + [Species.MILTANK]: 4, [Species.RAIKOU]: 6, [Species.ENTEI]: 6, [Species.SUICUNE]: 6, @@ -2819,68 +2819,68 @@ export const speciesStarters = { [Species.CELEBI]: 6, [Species.TREECKO]: 3, - [Species.TORCHIC]: 3, + [Species.TORCHIC]: 4, [Species.MUDKIP]: 3, [Species.POOCHYENA]: 2, [Species.ZIGZAGOON]: 2, [Species.WURMPLE]: 1, [Species.LOTAD]: 3, - [Species.SEEDOT]: 3, + [Species.SEEDOT]: 2, [Species.TAILLOW]: 3, - [Species.WINGULL]: 3, + [Species.WINGULL]: 2, [Species.RALTS]: 3, [Species.SURSKIT]: 2, [Species.SHROOMISH]: 3, [Species.SLAKOTH]: 4, [Species.NINCADA]: 4, - [Species.WHISMUR]: 3, + [Species.WHISMUR]: 2, [Species.MAKUHITA]: 3, - [Species.AZURILL]: 3, - [Species.NOSEPASS]: 3, - [Species.SKITTY]: 3, - [Species.SABLEYE]: 3, - [Species.MAWILE]: 5, + [Species.AZURILL]: 4, + [Species.NOSEPASS]: 2, + [Species.SKITTY]: 1, + [Species.SABLEYE]: 2, + [Species.MAWILE]: 3, [Species.ARON]: 3, - [Species.MEDITITE]: 4, - [Species.ELECTRIKE]: 3, + [Species.MEDITITE]: 3, + [Species.ELECTRIKE]: 2, [Species.PLUSLE]: 2, [Species.MINUN]: 2, [Species.VOLBEAT]: 2, [Species.ILLUMISE]: 2, - [Species.ROSELIA]: 4, - [Species.GULPIN]: 3, + [Species.ROSELIA]: 3, + [Species.GULPIN]: 1, [Species.CARVANHA]: 3, - [Species.WAILMER]: 3, - [Species.NUMEL]: 3, - [Species.TORKOAL]: 4, - [Species.SPOINK]: 3, - [Species.SPINDA]: 2, - [Species.TRAPINCH]: 4, - [Species.CACNEA]: 3, - [Species.SWABLU]: 3, - [Species.ZANGOOSE]: 5, - [Species.SEVIPER]: 4, - [Species.LUNATONE]: 4, - [Species.SOLROCK]: 4, - [Species.BARBOACH]: 3, + [Species.WAILMER]: 2, + [Species.NUMEL]: 2, + [Species.TORKOAL]: 3, + [Species.SPOINK]: 2, + [Species.SPINDA]: 1, + [Species.TRAPINCH]: 3, + [Species.CACNEA]: 2, + [Species.SWABLU]: 2, + [Species.ZANGOOSE]: 4, + [Species.SEVIPER]: 3, + [Species.LUNATONE]: 3, + [Species.SOLROCK]: 3, + [Species.BARBOACH]: 2, [Species.CORPHISH]: 3, - [Species.BALTOY]: 3, + [Species.BALTOY]: 2, [Species.LILEEP]: 3, [Species.ANORITH]: 3, [Species.FEEBAS]: 4, - [Species.CASTFORM]: 2, - [Species.KECLEON]: 4, - [Species.SHUPPET]: 3, + [Species.CASTFORM]: 1, + [Species.KECLEON]: 2, + [Species.SHUPPET]: 2, [Species.DUSKULL]: 3, - [Species.TROPIUS]: 5, - [Species.CHIMECHO]: 4, - [Species.ABSOL]: 5, - [Species.WYNAUT]: 3, - [Species.SNORUNT]: 3, - [Species.SPHEAL]: 3, + [Species.TROPIUS]: 3, + [Species.CHIMECHO]: 3, + [Species.ABSOL]: 4, + [Species.WYNAUT]: 2, + [Species.SNORUNT]: 2, + [Species.SPHEAL]: 2, [Species.CLAMPERL]: 3, - [Species.RELICANTH]: 4, - [Species.LUVDISC]: 2, + [Species.RELICANTH]: 3, + [Species.LUVDISC]: 1, [Species.BAGON]: 4, [Species.BELDUM]: 4, [Species.REGIROCK]: 6, @@ -2898,39 +2898,39 @@ export const speciesStarters = { [Species.CHIMCHAR]: 3, [Species.PIPLUP]: 3, [Species.STARLY]: 3, - [Species.BIDOOF]: 2, + [Species.BIDOOF]: 3, [Species.KRICKETOT]: 1, - [Species.SHINX]: 3, + [Species.SHINX]: 2, [Species.BUDEW]: 3, [Species.CRANIDOS]: 3, [Species.SHIELDON]: 3, - [Species.BURMY]: 1, + [Species.BURMY]: 2, [Species.COMBEE]: 2, - [Species.PACHIRISU]: 3, - [Species.BUIZEL]: 3, - [Species.CHERUBI]: 3, + [Species.PACHIRISU]: 2, + [Species.BUIZEL]: 2, + [Species.CHERUBI]: 1, [Species.SHELLOS]: 3, - [Species.DRIFLOON]: 3, - [Species.BUNEARY]: 3, - [Species.GLAMEOW]: 3, - [Species.CHINGLING]: 3, - [Species.STUNKY]: 3, + [Species.DRIFLOON]: 2, + [Species.BUNEARY]: 2, + [Species.GLAMEOW]: 2, + [Species.CHINGLING]: 2, + [Species.STUNKY]: 2, [Species.BRONZOR]: 3, - [Species.BONSLY]: 4, - [Species.MIME_JR]: 3, - [Species.HAPPINY]: 4, - [Species.CHATOT]: 4, - [Species.SPIRITOMB]: 5, + [Species.BONSLY]: 2, + [Species.MIME_JR]: 2, + [Species.HAPPINY]: 2, + [Species.CHATOT]: 2, + [Species.SPIRITOMB]: 4, [Species.GIBLE]: 4, [Species.MUNCHLAX]: 4, - [Species.RIOLU]: 4, + [Species.RIOLU]: 3, [Species.HIPPOPOTAS]: 3, [Species.SKORUPI]: 3, - [Species.CROAGUNK]: 3, - [Species.CARNIVINE]: 4, - [Species.FINNEON]: 3, - [Species.MANTYKE]: 3, - [Species.SNOVER]: 3, + [Species.CROAGUNK]: 2, + [Species.CARNIVINE]: 2, + [Species.FINNEON]: 1, + [Species.MANTYKE]: 2, + [Species.SNOVER]: 2, [Species.ROTOM]: 5, [Species.UXIE]: 6, [Species.MESPRIT]: 6, @@ -2946,75 +2946,75 @@ export const speciesStarters = { [Species.DARKRAI]: 6, [Species.SHAYMIN]: 6, [Species.ARCEUS]: 9, - [Species.VICTINI]: 7, + [Species.VICTINI]: 7, [Species.SNIVY]: 3, [Species.TEPIG]: 3, [Species.OSHAWOTT]: 3, - [Species.PATRAT]: 2, + [Species.PATRAT]: 1, [Species.LILLIPUP]: 3, - [Species.PURRLOIN]: 3, - [Species.PANSAGE]: 3, - [Species.PANSEAR]: 3, - [Species.PANPOUR]: 3, - [Species.MUNNA]: 3, - [Species.PIDOVE]: 2, - [Species.BLITZLE]: 3, + [Species.PURRLOIN]: 2, + [Species.PANSAGE]: 2, + [Species.PANSEAR]: 2, + [Species.PANPOUR]: 2, + [Species.MUNNA]: 2, + [Species.PIDOVE]: 1, + [Species.BLITZLE]: 2, [Species.ROGGENROLA]: 3, [Species.WOOBAT]: 3, [Species.DRILBUR]: 4, - [Species.AUDINO]: 4, - [Species.TIMBURR]: 3, + [Species.AUDINO]: 3, + [Species.TIMBURR]: 4, [Species.TYMPOLE]: 3, - [Species.THROH]: 5, - [Species.SAWK]: 5, - [Species.SEWADDLE]: 3, + [Species.THROH]: 4, + [Species.SAWK]: 4, + [Species.SEWADDLE]: 2, [Species.VENIPEDE]: 3, [Species.COTTONEE]: 3, [Species.PETILIL]: 3, [Species.BASCULIN]: 4, - [Species.SANDILE]: 3, + [Species.SANDILE]: 4, [Species.DARUMAKA]: 4, - [Species.MARACTUS]: 4, - [Species.DWEBBLE]: 3, + [Species.MARACTUS]: 2, + [Species.DWEBBLE]: 2, [Species.SCRAGGY]: 3, - [Species.SIGILYPH]: 5, + [Species.SIGILYPH]: 4, [Species.YAMASK]: 3, - [Species.TIRTOUGA]: 4, - [Species.ARCHEN]: 4, - [Species.TRUBBISH]: 3, + [Species.TIRTOUGA]: 3, + [Species.ARCHEN]: 3, + [Species.TRUBBISH]: 2, [Species.ZORUA]: 3, [Species.MINCCINO]: 3, [Species.GOTHITA]: 3, [Species.SOLOSIS]: 3, - [Species.DUCKLETT]: 3, + [Species.DUCKLETT]: 2, [Species.VANILLITE]: 3, - [Species.DEERLING]: 3, - [Species.EMOLGA]: 3, + [Species.DEERLING]: 2, + [Species.EMOLGA]: 2, [Species.KARRABLAST]: 3, - [Species.FOONGUS]: 3, + [Species.FOONGUS]: 2, [Species.FRILLISH]: 3, [Species.ALOMOMOLA]: 4, [Species.JOLTIK]: 3, [Species.FERROSEED]: 3, [Species.KLINK]: 3, - [Species.TYNAMO]: 3, + [Species.TYNAMO]: 2, [Species.ELGYEM]: 3, [Species.LITWICK]: 3, [Species.AXEW]: 4, - [Species.CUBCHOO]: 3, - [Species.CRYOGONAL]: 5, - [Species.SHELMET]: 3, - [Species.STUNFISK]: 4, + [Species.CUBCHOO]: 2, + [Species.CRYOGONAL]: 4, + [Species.SHELMET]: 2, + [Species.STUNFISK]: 3, [Species.MIENFOO]: 3, - [Species.DRUDDIGON]: 5, + [Species.DRUDDIGON]: 4, [Species.GOLETT]: 3, [Species.PAWNIARD]: 4, - [Species.BOUFFALANT]: 5, + [Species.BOUFFALANT]: 4, [Species.RUFFLET]: 3, [Species.VULLABY]: 3, - [Species.HEATMOR]: 5, - [Species.DURANT]: 5, + [Species.HEATMOR]: 3, + [Species.DURANT]: 4, [Species.DEINO]: 4, [Species.LARVESTA]: 4, [Species.COBALION]: 6, @@ -3032,77 +3032,77 @@ export const speciesStarters = { [Species.CHESPIN]: 3, [Species.FENNEKIN]: 3, - [Species.FROAKIE]: 3, - [Species.BUNNELBY]: 2, + [Species.FROAKIE]: 4, + [Species.BUNNELBY]: 3, [Species.FLETCHLING]: 3, - [Species.SCATTERBUG]: 1, - [Species.LITLEO]: 3, + [Species.SCATTERBUG]: 2, + [Species.LITLEO]: 2, [Species.FLABEBE]: 3, - [Species.SKIDDO]: 3, + [Species.SKIDDO]: 2, [Species.PANCHAM]: 3, - [Species.FURFROU]: 4, - [Species.ESPURR]: 3, + [Species.FURFROU]: 3, + [Species.ESPURR]: 2, [Species.HONEDGE]: 4, - [Species.SPRITZEE]: 3, + [Species.SPRITZEE]: 2, [Species.SWIRLIX]: 3, [Species.INKAY]: 3, [Species.BINACLE]: 3, - [Species.SKRELP]: 3, + [Species.SKRELP]: 2, [Species.CLAUNCHER]: 3, [Species.HELIOPTILE]: 3, [Species.TYRUNT]: 3, [Species.AMAURA]: 3, [Species.HAWLUCHA]: 4, - [Species.DEDENNE]: 4, - [Species.CARBINK]: 4, + [Species.DEDENNE]: 2, + [Species.CARBINK]: 2, [Species.GOOMY]: 4, - [Species.KLEFKI]: 4, - [Species.PHANTUMP]: 3, - [Species.PUMPKABOO]: 3, + [Species.KLEFKI]: 3, + [Species.PHANTUMP]: 2, + [Species.PUMPKABOO]: 2, [Species.BERGMITE]: 3, - [Species.NOIBAT]: 4, + [Species.NOIBAT]: 3, [Species.XERNEAS]: 8, [Species.YVELTAL]: 8, [Species.ZYGARDE]: 8, [Species.DIANCIE]: 7, [Species.HOOPA]: 7, [Species.VOLCANION]: 6, - [Species.ETERNAL_FLOETTE]: 5, + [Species.ETERNAL_FLOETTE]: 4, [Species.ROWLET]: 3, [Species.LITTEN]: 3, - [Species.POPPLIO]: 3, - [Species.PIKIPEK]: 3, + [Species.POPPLIO]: 4, + [Species.PIKIPEK]: 2, [Species.YUNGOOS]: 2, - [Species.GRUBBIN]: 2, - [Species.CRABRAWLER]: 4, + [Species.GRUBBIN]: 3, + [Species.CRABRAWLER]: 3, [Species.ORICORIO]: 3, [Species.CUTIEFLY]: 3, [Species.ROCKRUFF]: 3, - [Species.WISHIWASHI]: 3, - [Species.MAREANIE]: 3, + [Species.WISHIWASHI]: 2, + [Species.MAREANIE]: 2, [Species.MUDBRAY]: 3, [Species.DEWPIDER]: 3, - [Species.FOMANTIS]: 3, - [Species.MORELULL]: 3, + [Species.FOMANTIS]: 2, + [Species.MORELULL]: 2, [Species.SALANDIT]: 3, [Species.STUFFUL]: 3, [Species.BOUNSWEET]: 3, [Species.COMFEY]: 4, - [Species.ORANGURU]: 5, - [Species.PASSIMIAN]: 5, + [Species.ORANGURU]: 4, + [Species.PASSIMIAN]: 4, [Species.WIMPOD]: 3, [Species.SANDYGAST]: 3, - [Species.PYUKUMUKU]: 3, + [Species.PYUKUMUKU]: 2, [Species.TYPE_NULL]: 5, - [Species.MINIOR]: 5, - [Species.KOMALA]: 5, - [Species.TURTONATOR]: 5, - [Species.TOGEDEMARU]: 4, - [Species.MIMIKYU]: 5, - [Species.BRUXISH]: 5, - [Species.DRAMPA]: 5, - [Species.DHELMISE]: 5, + [Species.MINIOR]: 4, + [Species.KOMALA]: 3, + [Species.TURTONATOR]: 4, + [Species.TOGEDEMARU]: 3, + [Species.MIMIKYU]: 4, + [Species.BRUXISH]: 4, + [Species.DRAMPA]: 4, + [Species.DHELMISE]: 4, [Species.JANGMO_O]: 4, [Species.TAPU_KOKO]: 6, [Species.TAPU_LELE]: 6, @@ -3124,49 +3124,49 @@ export const speciesStarters = { [Species.BLACEPHALON]: 7, [Species.ZERAORA]: 6, [Species.MELTAN]: 6, - [Species.ALOLA_RATTATA]: 2, - [Species.ALOLA_SANDSHREW]: 4, - [Species.ALOLA_VULPIX]: 4, - [Species.ALOLA_DIGLETT]: 3, - [Species.ALOLA_MEOWTH]: 4, + [Species.ALOLA_RATTATA]: 1, + [Species.ALOLA_SANDSHREW]: 2, + [Species.ALOLA_VULPIX]: 3, + [Species.ALOLA_DIGLETT]: 2, + [Species.ALOLA_MEOWTH]: 3, [Species.ALOLA_GEODUDE]: 3, [Species.ALOLA_GRIMER]: 3, - [Species.GROOKEY]: 3, - [Species.SCORBUNNY]: 3, - [Species.SOBBLE]: 3, + [Species.GROOKEY]: 4, + [Species.SCORBUNNY]: 4, + [Species.SOBBLE]: 4, [Species.SKWOVET]: 2, - [Species.ROOKIDEE]: 4, + [Species.ROOKIDEE]: 3, [Species.BLIPBUG]: 2, - [Species.NICKIT]: 3, - [Species.GOSSIFLEUR]: 3, - [Species.WOOLOO]: 3, + [Species.NICKIT]: 1, + [Species.GOSSIFLEUR]: 2, + [Species.WOOLOO]: 2, [Species.CHEWTLE]: 3, - [Species.YAMPER]: 3, + [Species.YAMPER]: 2, [Species.ROLYCOLY]: 3, - [Species.APPLIN]: 4, + [Species.APPLIN]: 3, [Species.SILICOBRA]: 3, [Species.CRAMORANT]: 3, [Species.ARROKUDA]: 3, [Species.TOXEL]: 3, [Species.SIZZLIPEDE]: 3, - [Species.CLOBBOPUS]: 3, + [Species.CLOBBOPUS]: 2, [Species.SINISTEA]: 3, - [Species.HATENNA]: 4, + [Species.HATENNA]: 3, [Species.IMPIDIMP]: 3, [Species.MILCERY]: 3, [Species.FALINKS]: 4, [Species.PINCURCHIN]: 3, [Species.SNOM]: 3, - [Species.STONJOURNER]: 4, - [Species.EISCUE]: 4, - [Species.INDEEDEE]: 3, + [Species.STONJOURNER]: 3, + [Species.EISCUE]: 3, + [Species.INDEEDEE]: 4, [Species.MORPEKO]: 3, - [Species.CUFANT]: 4, + [Species.CUFANT]: 3, [Species.DRACOZOLT]: 5, - [Species.ARCTOZOLT]: 5, + [Species.ARCTOZOLT]: 4, [Species.DRACOVISH]: 5, - [Species.ARCTOVISH]: 5, + [Species.ARCTOVISH]: 4, [Species.DURALUDON]: 5, [Species.DREEPY]: 4, [Species.ZACIAN]: 9, @@ -3179,67 +3179,67 @@ export const speciesStarters = { [Species.GLASTRIER]: 6, [Species.SPECTRIER]: 7, [Species.CALYREX]: 8, - [Species.GALAR_MEOWTH]: 4, - [Species.GALAR_PONYTA]: 4, + [Species.GALAR_MEOWTH]: 3, + [Species.GALAR_PONYTA]: 2, [Species.GALAR_SLOWPOKE]: 3, - [Species.GALAR_FARFETCHD]: 5, - [Species.GALAR_CORSOLA]: 4, + [Species.GALAR_FARFETCHD]: 3, + [Species.GALAR_CORSOLA]: 3, [Species.GALAR_ZIGZAGOON]: 3, [Species.GALAR_DARUMAKA]: 4, [Species.GALAR_YAMASK]: 3, - [Species.GALAR_STUNFISK]: 4, - [Species.GALAR_MR_MIME]: 5, + [Species.GALAR_STUNFISK]: 2, + [Species.GALAR_MR_MIME]: 3, [Species.GALAR_ARTICUNO]: 6, [Species.GALAR_ZAPDOS]: 6, [Species.GALAR_MOLTRES]: 6, [Species.HISUI_GROWLITHE]: 4, [Species.HISUI_VOLTORB]: 3, [Species.HISUI_QWILFISH]: 4, - [Species.HISUI_SNEASEL]: 4, - [Species.HISUI_ZORUA]: 4, + [Species.HISUI_SNEASEL]: 5, + [Species.HISUI_ZORUA]: 3, [Species.ENAMORUS]: 7, - [Species.SPRIGATITO]: 3, - [Species.FUECOCO]: 3, - [Species.QUAXLY]: 3, + [Species.SPRIGATITO]: 4, + [Species.FUECOCO]: 4, + [Species.QUAXLY]: 4, [Species.LECHONK]: 2, [Species.TAROUNTULA]: 1, [Species.NYMBLE]: 3, [Species.PAWMI]: 3, [Species.TANDEMAUS]: 4, - [Species.FIDOUGH]: 3, + [Species.FIDOUGH]: 2, [Species.SMOLIV]: 3, - [Species.SQUAWKABILLY]: 3, + [Species.SQUAWKABILLY]: 2, [Species.NACLI]: 4, [Species.CHARCADET]: 4, [Species.TADBULB]: 3, [Species.WATTREL]: 3, [Species.MASCHIFF]: 3, - [Species.SHROODLE]: 3, + [Species.SHROODLE]: 2, [Species.BRAMBLIN]: 3, [Species.TOEDSCOOL]: 3, - [Species.KLAWF]: 4, + [Species.KLAWF]: 3, [Species.CAPSAKID]: 3, - [Species.RELLOR]: 3, + [Species.RELLOR]: 2, [Species.FLITTLE]: 3, [Species.TINKATINK]: 4, - [Species.WIGLETT]: 3, + [Species.WIGLETT]: 2, [Species.BOMBIRDIER]: 3, - [Species.FINIZEN]: 4, + [Species.FINIZEN]: 3, [Species.VAROOM]: 4, - [Species.CYCLIZAR]: 5, + [Species.CYCLIZAR]: 4, [Species.ORTHWORM]: 4, [Species.GLIMMET]: 4, - [Species.GREAVARD]: 4, + [Species.GREAVARD]: 3, [Species.FLAMIGO]: 4, - [Species.CETODDLE]: 4, + [Species.CETODDLE]: 3, [Species.VELUZA]: 4, - [Species.DONDOZO]: 5, - [Species.TATSUGIRI]: 5, + [Species.DONDOZO]: 4, + [Species.TATSUGIRI]: 4, [Species.GREAT_TUSK]: 6, [Species.SCREAM_TAIL]: 6, [Species.BRUTE_BONNET]: 6, - [Species.FLUTTER_MANE]: 6, + [Species.FLUTTER_MANE]: 7, [Species.SLITHER_WING]: 6, [Species.SANDY_SHOCKS]: 6, [Species.IRON_TREADS]: 6, @@ -3273,7 +3273,7 @@ export const speciesStarters = { [Species.PECHARUNT]: 6, [Species.PALDEA_TAUROS]: 5, [Species.PALDEA_WOOPER]: 3, - [Species.BLOODMOON_URSALUNA]: 7, + [Species.BLOODMOON_URSALUNA]: 6, }; export const noStarterFormKeys: string[] = [ @@ -3319,14 +3319,14 @@ export const starterPassiveAbilities = { [Species.SQUIRTLE]: Abilities.STURDY, [Species.CATERPIE]: Abilities.MAGICIAN, [Species.WEEDLE]: Abilities.TINTED_LENS, - [Species.PIDGEY]: Abilities.GALE_WINGS, + [Species.PIDGEY]: Abilities.FLARE_BOOST, [Species.RATTATA]: Abilities.STRONG_JAW, [Species.SPEAROW]: Abilities.MOXIE, [Species.EKANS]: Abilities.REGENERATOR, [Species.SANDSHREW]: Abilities.TOUGH_CLAWS, [Species.NIDORAN_F]: Abilities.FLARE_BOOST, [Species.NIDORAN_M]: Abilities.GUTS, - [Species.VULPIX]: Abilities.SOLAR_POWER, + [Species.VULPIX]: Abilities.FUR_COAT, [Species.ZUBAT]: Abilities.INTIMIDATE, [Species.ODDISH]: Abilities.TRIAGE, [Species.PARAS]: Abilities.TRIAGE, @@ -3345,16 +3345,16 @@ export const starterPassiveAbilities = { [Species.PONYTA]: Abilities.MAGIC_GUARD, [Species.SLOWPOKE]: Abilities.UNAWARE, [Species.MAGNEMITE]: Abilities.LEVITATE, - [Species.FARFETCHD]: Abilities.HUGE_POWER, + [Species.FARFETCHD]: Abilities.SNIPER, [Species.DODUO]: Abilities.PARENTAL_BOND, [Species.SEEL]: Abilities.WATER_BUBBLE, [Species.GRIMER]: Abilities.WATER_ABSORB, [Species.SHELLDER]: Abilities.ICE_SCALES, [Species.GASTLY]: Abilities.SHADOW_SHIELD, [Species.ONIX]: Abilities.ROCKY_PAYLOAD, - [Species.DROWZEE]: Abilities.BAD_DREAMS, + [Species.DROWZEE]: Abilities.MAGICIAN, [Species.KRABBY]: Abilities.UNBURDEN, - [Species.VOLTORB]: Abilities.ELECTRIC_SURGE, + [Species.VOLTORB]: Abilities.TRANSISTOR, [Species.EXEGGCUTE]: Abilities.RIPEN, [Species.CUBONE]: Abilities.PARENTAL_BOND, [Species.LICKITUNG]: Abilities.THICK_FAT, @@ -3374,7 +3374,7 @@ export const starterPassiveAbilities = { [Species.EEVEE]: Abilities.SIMPLE, [Species.PORYGON]: Abilities.PROTEAN, [Species.OMANYTE]: Abilities.STURDY, - [Species.KABUTO]: Abilities.SHARPNESS, + [Species.KABUTO]: Abilities.TOUGH_CLAWS, [Species.AERODACTYL]: Abilities.ORICHALCUM_PULSE, [Species.ARTICUNO]: Abilities.SNOW_WARNING, [Species.ZAPDOS]: Abilities.DRIZZLE, @@ -3476,7 +3476,7 @@ export const starterPassiveAbilities = { [Species.CACNEA]: Abilities.SAND_RUSH, [Species.SWABLU]: Abilities.ADAPTABILITY, [Species.ZANGOOSE]: Abilities.POISON_HEAL, - [Species.SEVIPER]: Abilities.INTIMIDATE, + [Species.SEVIPER]: Abilities.MULTISCALE, [Species.LUNATONE]: Abilities.SHADOW_SHIELD, [Species.SOLROCK]: Abilities.DROUGHT, [Species.BARBOACH]: Abilities.SIMPLE, @@ -3495,16 +3495,16 @@ export const starterPassiveAbilities = { [Species.SNORUNT]: Abilities.SNOW_WARNING, [Species.SPHEAL]: Abilities.UNAWARE, [Species.CLAMPERL]: Abilities.DRIZZLE, - [Species.RELICANTH]: Abilities.SOLID_ROCK, + [Species.RELICANTH]: Abilities.PRIMORDIAL_SEA, [Species.LUVDISC]: Abilities.MULTISCALE, - [Species.BAGON]: Abilities.ADAPTABILITY, + [Species.BAGON]: Abilities.DRAGONS_MAW, [Species.BELDUM]: Abilities.LEVITATE, [Species.REGIROCK]: Abilities.SAND_STREAM, [Species.REGICE]: Abilities.SNOW_WARNING, [Species.REGISTEEL]: Abilities.FILTER, - [Species.LATIAS]: Abilities.SOUL_HEART, + [Species.LATIAS]: Abilities.PRISM_ARMOR, [Species.LATIOS]: Abilities.TINTED_LENS, - [Species.KYOGRE]: Abilities.RAIN_DISH, + [Species.KYOGRE]: Abilities.MOLD_BREAKER, [Species.GROUDON]: Abilities.TURBOBLAZE, [Species.RAYQUAZA]: Abilities.UNNERVE, [Species.JIRACHI]: Abilities.COMATOSE, @@ -3523,7 +3523,7 @@ export const starterPassiveAbilities = { [Species.COMBEE]: Abilities.INTIMIDATE, [Species.PACHIRISU]: Abilities.HONEY_GATHER, [Species.BUIZEL]: Abilities.MOXIE, - [Species.CHERUBI]: Abilities.DROUGHT, + [Species.CHERUBI]: Abilities.ORICHALCUM_PULSE, [Species.SHELLOS]: Abilities.REGENERATOR, [Species.DRIFLOON]: Abilities.MAGIC_GUARD, [Species.BUNEARY]: Abilities.ADAPTABILITY, @@ -3537,13 +3537,13 @@ export const starterPassiveAbilities = { [Species.CHATOT]: Abilities.PUNK_ROCK, [Species.SPIRITOMB]: Abilities.VESSEL_OF_RUIN, [Species.GIBLE]: Abilities.SAND_STREAM, - [Species.MUNCHLAX]: Abilities.RIPEN, + [Species.MUNCHLAX]: Abilities.HARVEST, [Species.RIOLU]: Abilities.MINDS_EYE, [Species.HIPPOPOTAS]: Abilities.UNAWARE, [Species.SKORUPI]: Abilities.SUPER_LUCK, [Species.CROAGUNK]: Abilities.MOXIE, [Species.CARNIVINE]: Abilities.ARENA_TRAP, - [Species.FINNEON]: Abilities.DRIZZLE, + [Species.FINNEON]: Abilities.WATER_BUBBLE, [Species.MANTYKE]: Abilities.UNAWARE, [Species.SNOVER]: Abilities.THICK_FAT, [Species.ROTOM]: Abilities.HADRON_ENGINE, @@ -3557,7 +3557,7 @@ export const starterPassiveAbilities = { [Species.GIRATINA]: Abilities.SHADOW_SHIELD, [Species.CRESSELIA]: Abilities.MAGIC_BOUNCE, [Species.PHIONE]: Abilities.SIMPLE, - [Species.MANAPHY]: Abilities.SIMPLE, + [Species.MANAPHY]: Abilities.PRIMORDIAL_SEA, [Species.DARKRAI]: Abilities.UNNERVE, [Species.SHAYMIN]: Abilities.WIND_RIDER, [Species.ARCEUS]: Abilities.ADAPTABILITY, @@ -3590,13 +3590,13 @@ export const starterPassiveAbilities = { [Species.SANDILE]: Abilities.TOUGH_CLAWS, [Species.DARUMAKA]: Abilities.GORILLA_TACTICS, [Species.MARACTUS]: Abilities.WELL_BAKED_BODY, - [Species.DWEBBLE]: Abilities.ANGER_SHELL, + [Species.DWEBBLE]: Abilities.ROCKY_PAYLOAD, [Species.SCRAGGY]: Abilities.PROTEAN, - [Species.SIGILYPH]: Abilities.MAGICIAN, + [Species.SIGILYPH]: Abilities.FLARE_BOOST, [Species.YAMASK]: Abilities.PURIFYING_SALT, - [Species.TIRTOUGA]: Abilities.ANGER_SHELL, + [Species.TIRTOUGA]: Abilities.WATER_ABSORB, [Species.ARCHEN]: Abilities.MULTISCALE, - [Species.TRUBBISH]: Abilities.TOXIC_DEBRIS, + [Species.TRUBBISH]: Abilities.NEUTRALIZING_GAS, [Species.ZORUA]: Abilities.DARK_AURA, [Species.MINCCINO]: Abilities.FUR_COAT, [Species.GOTHITA]: Abilities.UNNERVE, @@ -3611,7 +3611,7 @@ export const starterPassiveAbilities = { [Species.ALOMOMOLA]: Abilities.MULTISCALE, [Species.JOLTIK]: Abilities.TRANSISTOR, [Species.FERROSEED]: Abilities.ROUGH_SKIN, - [Species.KLINK]: Abilities.STEELWORKER, + [Species.KLINK]: Abilities.STEELY_SPIRIT, [Species.TYNAMO]: Abilities.POISON_HEAL, [Species.ELGYEM]: Abilities.PRISM_ARMOR, [Species.LITWICK]: Abilities.SOUL_HEART, @@ -3625,7 +3625,7 @@ export const starterPassiveAbilities = { [Species.GOLETT]: Abilities.SHADOW_SHIELD, [Species.PAWNIARD]: Abilities.SWORD_OF_RUIN, [Species.BOUFFALANT]: Abilities.ROCK_HEAD, - [Species.RUFFLET]: Abilities.GALE_WINGS, + [Species.RUFFLET]: Abilities.SPEED_BOOST, [Species.VULLABY]: Abilities.THICK_FAT, [Species.HEATMOR]: Abilities.CONTRARY, [Species.DURANT]: Abilities.COMPOUND_EYES, @@ -3651,12 +3651,12 @@ export const starterPassiveAbilities = { [Species.SCATTERBUG]: Abilities.PRANKSTER, [Species.LITLEO]: Abilities.BEAST_BOOST, [Species.FLABEBE]: Abilities.GRASSY_SURGE, - [Species.SKIDDO]: Abilities.GRASSY_SURGE, + [Species.SKIDDO]: Abilities.SEED_SOWER, [Species.PANCHAM]: Abilities.FUR_COAT, [Species.FURFROU]: Abilities.FLUFFY, [Species.ESPURR]: Abilities.FUR_COAT, [Species.HONEDGE]: Abilities.SHARPNESS, - [Species.SPRITZEE]: Abilities.MISTY_SURGE, + [Species.SPRITZEE]: Abilities.FUR_COAT, [Species.SWIRLIX]: Abilities.WELL_BAKED_BODY, [Species.INKAY]: Abilities.UNNERVE, [Species.BINACLE]: Abilities.SAP_SIPPER, @@ -3670,17 +3670,17 @@ export const starterPassiveAbilities = { [Species.CARBINK]: Abilities.SOLID_ROCK, [Species.GOOMY]: Abilities.REGENERATOR, [Species.KLEFKI]: Abilities.LEVITATE, - [Species.PHANTUMP]: Abilities.RIPEN, + [Species.PHANTUMP]: Abilities.SHADOW_TAG, [Species.PUMPKABOO]: Abilities.WELL_BAKED_BODY, [Species.BERGMITE]: Abilities.ICE_SCALES, [Species.NOIBAT]: Abilities.PUNK_ROCK, - [Species.XERNEAS]: Abilities.MISTY_SURGE, + [Species.XERNEAS]: Abilities.HARVEST, [Species.YVELTAL]: Abilities.SOUL_HEART, [Species.ZYGARDE]: Abilities.HUGE_POWER, [Species.DIANCIE]: Abilities.LEVITATE, [Species.HOOPA]: Abilities.OPPORTUNIST, [Species.VOLCANION]: Abilities.FILTER, - [Species.ROWLET]: Abilities.UNBURDEN, + [Species.ROWLET]: Abilities.SNIPER, [Species.LITTEN]: Abilities.FUR_COAT, [Species.POPPLIO]: Abilities.PUNK_ROCK, [Species.PIKIPEK]: Abilities.TECHNICIAN, @@ -3714,7 +3714,7 @@ export const starterPassiveAbilities = { [Species.BRUXISH]: Abilities.MULTISCALE, [Species.DRAMPA]: Abilities.THICK_FAT, [Species.DHELMISE]: Abilities.WATER_BUBBLE, - [Species.JANGMO_O]: Abilities.PUNK_ROCK, + [Species.JANGMO_O]: Abilities.DAUNTLESS_SHIELD, [Species.TAPU_KOKO]: Abilities.TRANSISTOR, [Species.TAPU_LELE]: Abilities.SHEER_FORCE, [Species.TAPU_BULU]: Abilities.TRIAGE, @@ -3726,7 +3726,7 @@ export const starterPassiveAbilities = { [Species.XURKITREE]: Abilities.TRANSISTOR, [Species.CELESTEELA]: Abilities.HEATPROOF, [Species.KARTANA]: Abilities.SHARPNESS, - [Species.GUZZLORD]: Abilities.INNARDS_OUT, + [Species.GUZZLORD]: Abilities.POISON_HEAL, [Species.NECROZMA]: Abilities.BEAST_BOOST, [Species.MAGEARNA]: Abilities.STEELY_SPIRIT, [Species.MARSHADOW]: Abilities.IRON_FIST, @@ -3738,13 +3738,13 @@ export const starterPassiveAbilities = { [Species.GROOKEY]: Abilities.GRASS_PELT, [Species.SCORBUNNY]: Abilities.NO_GUARD, [Species.SOBBLE]: Abilities.SUPER_LUCK, - [Species.SKWOVET]: Abilities.RIPEN, + [Species.SKWOVET]: Abilities.HARVEST, [Species.ROOKIDEE]: Abilities.IRON_BARBS, [Species.BLIPBUG]: Abilities.PSYCHIC_SURGE, [Species.NICKIT]: Abilities.MAGICIAN, [Species.GOSSIFLEUR]: Abilities.GRASSY_SURGE, [Species.WOOLOO]: Abilities.SIMPLE, - [Species.CHEWTLE]: Abilities.ROCK_HEAD, + [Species.CHEWTLE]: Abilities.ROCKY_PAYLOAD, [Species.YAMPER]: Abilities.SHEER_FORCE, [Species.ROLYCOLY]: Abilities.SOLID_ROCK, [Species.APPLIN]: Abilities.DRAGONS_MAW, @@ -3757,7 +3757,7 @@ export const starterPassiveAbilities = { [Species.SINISTEA]: Abilities.SHADOW_SHIELD, [Species.HATENNA]: Abilities.FAIRY_AURA, [Species.IMPIDIMP]: Abilities.FUR_COAT, - [Species.MILCERY]: Abilities.MISTY_SURGE, + [Species.MILCERY]: Abilities.REGENERATOR, [Species.FALINKS]: Abilities.PARENTAL_BOND, [Species.PINCURCHIN]: Abilities.ELECTROMORPHOSIS, [Species.SNOM]: Abilities.SNOW_WARNING, @@ -3776,7 +3776,7 @@ export const starterPassiveAbilities = { [Species.ZAMAZENTA]: Abilities.STAMINA, [Species.ETERNATUS]: Abilities.SUPREME_OVERLORD, [Species.KUBFU]: Abilities.IRON_FIST, - [Species.ZARUDE]: Abilities.GRASSY_SURGE, + [Species.ZARUDE]: Abilities.TOUGH_CLAWS, [Species.REGIELEKI]: Abilities.ELECTRIC_SURGE, [Species.REGIDRAGO]: Abilities.MULTISCALE, [Species.GLASTRIER]: Abilities.FILTER, @@ -3785,7 +3785,7 @@ export const starterPassiveAbilities = { [Species.ENAMORUS]: Abilities.FAIRY_AURA, [Species.SPRIGATITO]: Abilities.MAGICIAN, [Species.FUECOCO]: Abilities.PUNK_ROCK, - [Species.QUAXLY]: Abilities.DEFIANT, + [Species.QUAXLY]: Abilities.OPPORTUNIST, [Species.LECHONK]: Abilities.SIMPLE, [Species.TAROUNTULA]: Abilities.HONEY_GATHER, [Species.NYMBLE]: Abilities.GUTS, @@ -3833,7 +3833,7 @@ export const starterPassiveAbilities = { [Species.IRON_MOTH]: Abilities.LEVITATE, [Species.IRON_THORNS]: Abilities.SAND_STREAM, [Species.FRIGIBAX]: Abilities.SNOW_WARNING, - [Species.GIMMIGHOUL]: Abilities.CONTRARY, + [Species.GIMMIGHOUL]: Abilities.HONEY_GATHER, [Species.WO_CHIEN]: Abilities.VESSEL_OF_RUIN, [Species.CHIEN_PAO]: Abilities.INTREPID_SWORD, [Species.TING_LU]: Abilities.STAMINA, @@ -3864,7 +3864,7 @@ export const starterPassiveAbilities = { [Species.ALOLA_GRIMER]: Abilities.TOXIC_DEBRIS, [Species.ETERNAL_FLOETTE]: Abilities.MAGIC_GUARD, [Species.GALAR_MEOWTH]: Abilities.STEELWORKER, - [Species.GALAR_PONYTA]: Abilities.PIXILATE, + [Species.GALAR_PONYTA]: Abilities.MOXIE, [Species.GALAR_SLOWPOKE]: Abilities.UNAWARE, [Species.GALAR_FARFETCHD]: Abilities.INTREPID_SWORD, [Species.GALAR_ARTICUNO]: Abilities.SERENE_GRACE, @@ -3876,7 +3876,7 @@ export const starterPassiveAbilities = { [Species.GALAR_YAMASK]: Abilities.TABLETS_OF_RUIN, [Species.GALAR_STUNFISK]: Abilities.ARENA_TRAP, [Species.HISUI_GROWLITHE]: Abilities.RECKLESS, - [Species.HISUI_VOLTORB]: Abilities.ELECTRIC_SURGE, + [Species.HISUI_VOLTORB]: Abilities.TRANSISTOR, [Species.HISUI_QWILFISH]: Abilities.MERCILESS, [Species.HISUI_SNEASEL]: Abilities.SCRAPPY, [Species.HISUI_ZORUA]: Abilities.ADAPTABILITY, diff --git a/src/data/terrain.ts b/src/data/terrain.ts index 507557eaf9f..d0b2fb53d3e 100644 --- a/src/data/terrain.ts +++ b/src/data/terrain.ts @@ -61,7 +61,7 @@ export class Terrain { const priority = new Utils.IntegerHolder(move.priority); applyAbAttrs(IncrementMovePriorityAbAttr, user, null, move, priority); // Cancels move if the move has positive priority and targets a Pokemon grounded on the Psychic Terrain - return priority.value > 0 && user.getOpponents().filter(o => targets.includes(o.getBattlerIndex()) && o.isGrounded()).length > 0; + return priority.value > 0 && user.getOpponents().some(o => targets.includes(o.getBattlerIndex()) && o.isGrounded()); } } diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 4f3481b27ac..8d61463f316 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -556,7 +556,7 @@ export class TrainerConfig { const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); this.name = i18next.t(`trainerNames:${nameForCall}`); this.setTitle(title); - this.setMoneyMultiplier(2.25); + this.setMoneyMultiplier(2.5); this.setBoss(); this.setStaticParty(); this.setBattleBgm("battle_plasma_boss"); @@ -1187,6 +1187,12 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.RARE]: [Species.PORYGON, Species.ALOLA_RATTATA, Species.ALOLA_SANDSHREW, Species.ALOLA_MEOWTH, Species.ALOLA_GRIMER, Species.ALOLA_GEODUDE], [TrainerPoolTier.SUPER_RARE]: [Species.DRATINI, Species.LARVITAR] }), + [TrainerType.ROCKET_ADMIN]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setSpeciesPools({ + [TrainerPoolTier.COMMON]: [ Species.RATTATA, Species.KOFFING, Species.EKANS, Species.GYARADOS, Species.TAUROS, Species.SCYTHER, Species.CUBONE, Species.GROWLITHE, Species.MURKROW, Species.GASTLY, Species.EXEGGCUTE, Species.VOLTORB], + [TrainerPoolTier.UNCOMMON]: [Species.PORYGON, Species.ALOLA_RATTATA, Species.ALOLA_SANDSHREW, Species.ALOLA_MEOWTH, Species.ALOLA_GRIMER, Species.ALOLA_GEODUDE], + [TrainerPoolTier.RARE]: [Species.DRATINI, Species.LARVITAR] + }), [TrainerType.MAGMA_GRUNT]: new TrainerConfig(++t).setHasGenders("Magma Grunt Female").setHasDouble("Magma Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [Species.SLUGMA, Species.POOCHYENA, Species.NUMEL, Species.ZIGZAGOON, Species.DIGLETT, Species.MAGBY, Species.TORKOAL, Species.BALTOY, Species.BARBOACH], @@ -1194,6 +1200,12 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.RARE]: [Species.TRAPINCH, Species.HEATMOR], [TrainerPoolTier.SUPER_RARE]: [Species.TURTONATOR, Species.CHARCADET] }), + [TrainerType.MAGMA_ADMIN]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setSpeciesPools({ + [TrainerPoolTier.COMMON]: [ Species.NUMEL, Species.POOCHYENA, Species.SLUGMA, Species.SOLROCK, Species.HIPPOPOTAS, Species.SANDACONDA, Species.PHANPY, Species.SWINUB, Species.GLIGAR], + [TrainerPoolTier.UNCOMMON]: [Species.TRAPINCH, Species.HEATMOR], + [TrainerPoolTier.RARE]: [Species.TURTONATOR, Species.CHARCADET] + }), [TrainerType.AQUA_GRUNT]: new TrainerConfig(++t).setHasGenders("Aqua Grunt Female").setHasDouble("Aqua Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.CARVANHA, Species.WAILMER, Species.ZIGZAGOON, Species.LOTAD, Species.CORPHISH, Species.SPHEAL ], @@ -1201,6 +1213,12 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.RARE]: [Species.MANTINE, Species.BASCULEGION, Species.REMORAID, Species.ARROKUDA], [TrainerPoolTier.SUPER_RARE]: [Species.DONDOZO] }), + [TrainerType.AQUA_ADMIN]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setSpeciesPools({ + [TrainerPoolTier.COMMON]: [ Species.CARVANHA, Species.CORPHISH, Species.ZIGZAGOON, Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.QWILFISH ], + [TrainerPoolTier.UNCOMMON]: [Species.MANTINE, Species.BASCULEGION, Species.REMORAID, Species.ARROKUDA], + [TrainerPoolTier.RARE]: [Species.DONDOZO] + }), [TrainerType.GALACTIC_GRUNT]: new TrainerConfig(++t).setHasGenders("Galactic Grunt Female").setHasDouble("Galactic Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.GLAMEOW, Species.STUNKY, Species.CROAGUNK, Species.SHINX, Species.WURMPLE, Species.BRONZOR, Species.DRIFLOON, Species.BURMY], @@ -1208,6 +1226,12 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.RARE]: [Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.HISUI_SNEASEL], [TrainerPoolTier.SUPER_RARE]: [Species.HISUI_ZORUA, Species.HISUI_SLIGGOO] }), + [TrainerType.GALACTIC_ADMIN]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setSpeciesPools({ + [TrainerPoolTier.COMMON]: [ Species.GLAMEOW, Species.STUNKY, Species.BRONZOR, Species.CARNIVINE, Species.GROWLITHE, Species.QWILFISH, Species.SNEASEL ], + [TrainerPoolTier.UNCOMMON]: [Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.HISUI_SNEASEL], + [TrainerPoolTier.RARE]: [Species.HISUI_ZORUA, Species.HISUI_SLIGGOO] + }), [TrainerType.PLASMA_GRUNT]: new TrainerConfig(++t).setHasGenders("Plasma Grunt Female").setHasDouble("Plasma Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_plasma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.PATRAT, Species.LILLIPUP, Species.PURRLOIN, Species.SCRAFTY, Species.WOOBAT, Species.VANILLITE, Species.SANDILE, Species.TRUBBISH], @@ -1215,6 +1239,12 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.RARE]: [Species.PAWNIARD, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.KLINK], [TrainerPoolTier.SUPER_RARE]: [Species.DRUDDIGON, Species.BOUFFALANT, Species.AXEW, Species.DEINO, Species.DURANT] }), + [TrainerType.PLASMA_SAGE]: new TrainerConfig(++t).setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_plasma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setSpeciesPools({ + [TrainerPoolTier.COMMON]: [ Species.SCRAFTY, Species.LILLIPUP, Species.PURRLOIN, Species.FRILLISH, Species.VENIPEDE, Species.GOLETT, Species.TIMBURR, Species.DARUMAKA, Species.AMOONGUSS], + [TrainerPoolTier.UNCOMMON]: [Species.PAWNIARD, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.KLINK], + [TrainerPoolTier.RARE]: [Species.DRUDDIGON, Species.BOUFFALANT, Species.AXEW, Species.DEINO, Species.DURANT] + }), [TrainerType.FLARE_GRUNT]: new TrainerConfig(++t).setHasGenders("Flare Grunt Female").setHasDouble("Flare Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.FLETCHLING, Species.LITLEO, Species.PONYTA, Species.INKAY, Species.HOUNDOUR, Species.SKORUPI, Species.SCRAFTY, Species.CROAGUNK], @@ -1222,6 +1252,12 @@ export const trainerConfigs: TrainerConfigs = { [TrainerPoolTier.RARE]: [Species.LITWICK, Species.SNEASEL, Species.PANCHAM, Species.PAWNIARD], [TrainerPoolTier.SUPER_RARE]: [Species.NOIVERN, Species.DRUDDIGON] }), + [TrainerType.FLARE_ADMIN]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) + .setSpeciesPools({ + [TrainerPoolTier.COMMON]: [ Species.FLETCHLING, Species.LITLEO, Species.INKAY, Species.HELIOPTILE, Species.ELECTRIKE, Species.SKRELP, Species.GULPIN, Species.PURRLOIN, Species.POOCHYENA, Species.SCATTERBUG], + [TrainerPoolTier.UNCOMMON]: [Species.LITWICK, Species.SNEASEL, Species.PANCHAM, Species.PAWNIARD], + [TrainerPoolTier.RARE]: [Species.NOIVERN, Species.DRUDDIGON] + }), [TrainerType.BROCK]: new TrainerConfig((t = TrainerType.BROCK)).initForGymLeader(signatureSpecies["BROCK"],true, Type.ROCK).setBattleBgm("battle_kanto_gym").setMixedBattleBgm("battle_kanto_gym"), [TrainerType.MISTY]: new TrainerConfig(++t).initForGymLeader(signatureSpecies["MISTY"],false, Type.WATER).setBattleBgm("battle_kanto_gym").setMixedBattleBgm("battle_kanto_gym"), [TrainerType.LT_SURGE]: new TrainerConfig(++t).initForGymLeader(signatureSpecies["LT_SURGE"],true, Type.ELECTRIC).setBattleBgm("battle_kanto_gym").setMixedBattleBgm("battle_kanto_gym"), @@ -1368,7 +1404,7 @@ export const trainerConfigs: TrainerConfigs = { p.generateAndPopulateMoveset(); p.generateName(); })), - [TrainerType.STEVEN]: new TrainerConfig(++t).initForChampion(signatureSpecies["STEVEN"],true).setBattleBgm("battle_hoenn_champion").setMixedBattleBgm("battle_hoenn_champion").setHasDouble("steven_wallace_double").setDoubleTrainerType(TrainerType.WALLACE).setDoubleTitle("champion_double") + [TrainerType.STEVEN]: new TrainerConfig(++t).initForChampion(signatureSpecies["STEVEN"],true).setBattleBgm("battle_hoenn_champion_g5").setMixedBattleBgm("battle_hoenn_champion_g6").setHasDouble("steven_wallace_double").setDoubleTrainerType(TrainerType.WALLACE).setDoubleTitle("champion_double") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SKARMORY], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); })) @@ -1377,7 +1413,7 @@ export const trainerConfigs: TrainerConfigs = { p.generateAndPopulateMoveset(); p.generateName(); })), - [TrainerType.WALLACE]: new TrainerConfig(++t).initForChampion(signatureSpecies["WALLACE"],true).setBattleBgm("battle_hoenn_champion").setMixedBattleBgm("battle_hoenn_champion").setHasDouble("wallace_steven_double").setDoubleTrainerType(TrainerType.STEVEN).setDoubleTitle("champion_double") + [TrainerType.WALLACE]: new TrainerConfig(++t).initForChampion(signatureSpecies["WALLACE"],true).setBattleBgm("battle_hoenn_champion_g5").setMixedBattleBgm("battle_hoenn_champion_g6").setHasDouble("wallace_steven_double").setDoubleTrainerType(TrainerType.STEVEN).setDoubleTitle("champion_double") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PELIPPER], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 1; // Drizzle p.generateAndPopulateMoveset(); diff --git a/src/data/type.ts b/src/data/type.ts index cf3bc85ab48..1330eb83f4b 100644 --- a/src/data/type.ts +++ b/src/data/type.ts @@ -505,7 +505,7 @@ export function getTypeDamageMultiplier(attackType: integer, defType: integer): * Retrieve the types resisting a given type * @returns An array populated with Types, or an empty array if no resistances exist (Unknown or Stellar type) */ -export function getTypeResistances(type: integer): Type[] { +export function getTypeResistances(type: number): Type[] { switch (type) { case Type.NORMAL: return [Type.ROCK, Type.STEEL, Type.GHOST]; diff --git a/src/enums/trainer-type.ts b/src/enums/trainer-type.ts index 6bd8f567acb..db0bf3a8d64 100644 --- a/src/enums/trainer-type.ts +++ b/src/enums/trainer-type.ts @@ -53,11 +53,17 @@ export enum TrainerType { WORKER, YOUNGSTER, ROCKET_GRUNT, + ROCKET_ADMIN, MAGMA_GRUNT, + MAGMA_ADMIN, AQUA_GRUNT, + AQUA_ADMIN, GALACTIC_GRUNT, + GALACTIC_ADMIN, PLASMA_GRUNT, + PLASMA_SAGE, FLARE_GRUNT, + FLARE_ADMIN, ROCKET_BOSS_GIOVANNI_1, ROCKET_BOSS_GIOVANNI_2, MAXIE, diff --git a/src/field/arena.ts b/src/field/arena.ts index 7d1046986a5..cb045cc76ac 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -638,8 +638,14 @@ export class Arena { } } - /** Clears terrain and arena tags when entering new biome or trainer battle. */ + /** + * Clears weather, terrain and arena tags when entering new biome or trainer battle. + */ resetArenaEffects(): void { + // Don't reset weather if a Biome's permanent weather is active + if (this.weather?.turnsLeft !== 0) { + this.trySetWeather(WeatherType.NONE, false); + } this.trySetTerrain(TerrainType.NONE, false, true); this.removeAllTags(); } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index f630cc16a48..7fc5f14d0e1 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -23,7 +23,7 @@ import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoo import { WeatherType } from "../data/weather"; import { TempBattleStat } from "../data/temp-battle-stat"; import { ArenaTagSide, WeakenMoveScreenTag } from "../data/arena-tag"; -import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, PreApplyBattlerTagAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldBattleStatMultiplierAbAttrs, FieldMultiplyBattleStatAbAttr, AddSecondStrikeAbAttr, IgnoreOpponentEvasionAbAttr } from "../data/ability"; +import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldBattleStatMultiplierAbAttrs, FieldMultiplyBattleStatAbAttr, AddSecondStrikeAbAttr, IgnoreOpponentEvasionAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr } from "../data/ability"; import PokemonData from "../system/pokemon-data"; import { BattlerIndex } from "../battle"; import { Mode } from "../ui/ui"; @@ -84,6 +84,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public friendship: integer; public metLevel: integer; public metBiome: Biome | -1; + public metSpecies: Species; public luck: integer; public pauseEvolutions: boolean; public pokerus: boolean; @@ -135,10 +136,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // If abilityIndex is not provided, determine it based on species and hidden ability if (species.abilityHidden && hasHiddenAbility) { // If the species has a hidden ability and the hidden ability is present - this.abilityIndex = species.ability2 ? 2 : 1; // Use ability index 2 if species has a second ability, otherwise use 1 + this.abilityIndex = 2; } else { // If there is no hidden ability or species does not have a hidden ability - this.abilityIndex = species.ability2 ? randAbilityIndex : 0; // Use random ability index if species has a second ability, otherwise use 0 + this.abilityIndex = species.ability2 !== species.ability1 ? randAbilityIndex : 0; // Use random ability index if species has a second ability, otherwise use 0 } } if (formIndex !== undefined) { @@ -173,6 +174,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.metLevel = dataSource.metLevel || 5; this.luck = dataSource.luck; this.metBiome = dataSource.metBiome; + this.metSpecies = dataSource.metSpecies ?? (this.metBiome !== -1 ? this.species.speciesId : this.species.getRootSpeciesId(true)); this.pauseEvolutions = dataSource.pauseEvolutions; this.pokerus = !!dataSource.pokerus; this.fusionSpecies = dataSource.fusionSpecies instanceof PokemonSpecies ? dataSource.fusionSpecies : getPokemonSpecies(dataSource.fusionSpecies); @@ -213,6 +215,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.friendship = species.baseFriendship; this.metLevel = level; this.metBiome = scene.currentBattle ? scene.arena.biomeType : -1; + this.metSpecies = species.speciesId; this.pokerus = false; if (level > 1) { @@ -885,11 +888,40 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } /** - * All moves that could be relearned by this pokemon at this point. Used for memory mushrooms. - * @returns {Moves[]} The valid moves + * Checks which egg moves have been unlocked for the {@linkcode Pokemon} based + * on the species it was met at or by the first {@linkcode Pokemon} in its evolution + * line that can act as a starter and provides those egg moves. + * @returns an array of {@linkcode Moves}, the length of which is determined by how many + * egg moves are unlocked for that species. + */ + getUnlockedEggMoves(): Moves[] { + const moves: Moves[] = []; + const species = this.metSpecies in speciesEggMoves ? this.metSpecies : this.getSpeciesForm(true).getRootSpeciesId(true); + if (species in speciesEggMoves) { + for (let i = 0; i < 4; i++) { + if (this.scene.gameData.starterData[species].eggMoves & (1 << i)) { + moves.push(speciesEggMoves[species][i]); + } + } + } + return moves; + } + + /** + * Gets all possible learnable level moves for the {@linkcode Pokemon}, + * excluding any moves already known. + * + * Available egg moves are only included if the {@linkcode Pokemon} was + * in the starting party of the run. + * @returns an array of {@linkcode Moves}, the length of which is determined + * by how many learnable moves there are for the {@linkcode Pokemon}. */ getLearnableLevelMoves(): Moves[] { - return this.getLevelMoves(1, true, false, true).map(lm => lm[1]).filter(lm => !this.moveset.filter(m => m.moveId === lm).length).filter((move: Moves, i: integer, array: Moves[]) => array.indexOf(move) === i); + let levelMoves = this.getLevelMoves(1, true).map(lm => lm[1]); + if (this.metBiome === -1) { + levelMoves = this.getUnlockedEggMoves().concat(levelMoves); + } + return levelMoves.filter(lm => !this.moveset.some(m => m.moveId === lm)); } /** @@ -1241,31 +1273,49 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } const immuneTags = this.findTags(tag => tag instanceof TypeImmuneTag && tag.immuneType === moveType); - immuneTags.forEach(tag => { - if (move !== undefined) { - const hitsTagAttrs = move.getAttrs(HitsTagAttr).filter(attr => attr.tagType === tag.tagType); - if (hitsTagAttrs.length === 0) { - multiplier = 0; - } + for (const tag of immuneTags) { + if (move && !move.getAttrs(HitsTagAttr).some(attr => attr.tagType === tag.tagType)) { + multiplier = 0; + break; } - }); + } return multiplier; } - getMatchupScore(pokemon: Pokemon): number { + /** + * Computes the given Pokemon's matchup score against this Pokemon. + * In most cases, this score ranges from near-zero to 16, but the maximum possible matchup score is 64. + * @param opponent {@linkcode Pokemon} The Pokemon to compare this Pokemon against + * @returns A score value based on how favorable this Pokemon is when fighting the given Pokemon + */ + getMatchupScore(opponent: Pokemon): number { const types = this.getTypes(true); - const enemyTypes = pokemon.getTypes(true, true); - const outspeed = (this.isActive(true) ? this.getBattleStat(Stat.SPD, pokemon) : this.getStat(Stat.SPD)) <= pokemon.getBattleStat(Stat.SPD, this); - let atkScore = pokemon.getAttackTypeEffectiveness(types[0], this) * (outspeed ? 1.25 : 1); - let defScore = 1 / Math.max(this.getAttackTypeEffectiveness(enemyTypes[0], pokemon), 0.25); + const enemyTypes = opponent.getTypes(true, true); + /** Is this Pokemon faster than the opponent? */ + const outspeed = (this.isActive(true) ? this.getBattleStat(Stat.SPD, opponent) : this.getStat(Stat.SPD)) >= opponent.getBattleStat(Stat.SPD, this); + /** + * Based on how effective this Pokemon's types are offensively against the opponent's types. + * This score is increased by 25 percent if this Pokemon is faster than the opponent. + */ + let atkScore = opponent.getAttackTypeEffectiveness(types[0], this) * (outspeed ? 1.25 : 1); + /** + * Based on how effectively this Pokemon defends against the opponent's types. + * This score cannot be higher than 4. + */ + let defScore = 1 / Math.max(this.getAttackTypeEffectiveness(enemyTypes[0], opponent), 0.25); if (types.length > 1) { - atkScore *= pokemon.getAttackTypeEffectiveness(types[1], this); + atkScore *= opponent.getAttackTypeEffectiveness(types[1], this); } if (enemyTypes.length > 1) { - defScore *= (1 / Math.max(this.getAttackTypeEffectiveness(enemyTypes[1], pokemon), 0.25)); + defScore *= (1 / Math.max(this.getAttackTypeEffectiveness(enemyTypes[1], opponent), 0.25)); } - let hpDiffRatio = this.getHpRatio() + (1 - pokemon.getHpRatio()); + /** + * Based on this Pokemon's HP ratio compared to that of the opponent. + * This ratio is multiplied by 1.5 if this Pokemon outspeeds the opponent; + * however, the final ratio cannot be higher than 1. + */ + let hpDiffRatio = this.getHpRatio() + (1 - opponent.getHpRatio()); if (outspeed) { hpDiffRatio = Math.min(hpDiffRatio * 1.5, 1); } @@ -1391,8 +1441,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return false; } - const rand1 = Utils.binToDec(Utils.decToBin(this.id).substring(0, 16)); - const rand2 = Utils.binToDec(Utils.decToBin(this.id).substring(16, 32)); + const rand1 = (this.id & 0xFFFF0000) >>> 16; + const rand2 = (this.id & 0x0000FFFF); const E = this.scene.gameData.trainerId ^ this.scene.gameData.secretId; const F = rand1 ^ rand2; @@ -1774,13 +1824,22 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (opponents.length === 1) { return opponents[0].name; } - return this.isPlayer() ? "the opposing team" : "your team"; + return this.isPlayer() ? i18next.t("arenaTag:opposingTeam") : i18next.t("arenaTag:yourTeam"); } getAlly(): Pokemon { return (this.isPlayer() ? this.scene.getPlayerField() : this.scene.getEnemyField())[this.getFieldIndex() ? 0 : 1]; } + /** + * Gets the Pokémon on the allied field. + * + * @returns An array of Pokémon on the allied field. + */ + getAlliedField(): Pokemon[] { + return this instanceof PlayerPokemon ? this.scene.getPlayerField() : this.scene.getEnemyField(); + } + /** * Calculates the accuracy multiplier of the user against a target. * @@ -1836,7 +1895,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const types = this.getTypes(true, true); const cancelled = new Utils.BooleanHolder(false); + const power = move.calculateBattlePower(source, this); const typeless = move.hasAttr(TypelessAttr); + const typeMultiplier = new Utils.NumberHolder(!typeless && (moveCategory !== MoveCategory.STATUS || move.getAttrs(StatusMoveTypeImmunityAttr).find(attr => types.includes(attr.immuneType))) ? this.getAttackTypeEffectiveness(move, source, false, false) : 1); @@ -1857,11 +1918,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.arena.applyTagsForSide(ArenaTagType.CRAFTY_SHIELD, defendingSide, cancelled, this, move.category, move.moveTarget); } + // Apply exceptional condition of Crafty Shield if the move used is Curse + if (move.id === Moves.CURSE) { + const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; + this.scene.arena.applyTagsForSide(ArenaTagType.CRAFTY_SHIELD, defendingSide, cancelled, this, move.category, move.moveTarget); + } + switch (moveCategory) { case MoveCategory.PHYSICAL: case MoveCategory.SPECIAL: const isPhysical = moveCategory === MoveCategory.PHYSICAL; - const power = move.calculateBattlePower(source, this); const sourceTeraType = source.getTeraType(); if (!typeless) { @@ -1949,7 +2015,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } const targetCount = getMoveTargets(source, move.id).targets.length; - const targetMultiplier = targetCount > 1 ? 0.75 : 1; + const targetMultiplier = targetCount > 1 ? 0.75 : 1; // 25% damage debuff on multi-target hits (even if it's immune) applyMoveAttrs(VariableAtkAttr, source, this, move, sourceAtk); applyMoveAttrs(VariableDefAttr, source, this, move, targetDef); @@ -2080,7 +2146,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { source.turnData.damageDealt += damage.value; source.turnData.currDamageDealt = damage.value; this.battleData.hitCount++; - const attackResult = { move: move.id, result: result as DamageResult, damage: damage.value, critical: isCritical, sourceId: source.id, attackingPosition: source.getBattlerIndex() }; + const attackResult = { move: move.id, result: result as DamageResult, damage: damage.value, critical: isCritical, sourceId: source.id, sourceBattlerIndex: source.getBattlerIndex() }; this.turnData.attacksReceived.unshift(attackResult); if (source.isPlayer() && !this.isPlayer()) { this.scene.applyModifiers(DamageMoneyRewardModifier, true, source, damage); @@ -2229,7 +2295,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const newTag = getBattlerTag(tagType, turnCount, sourceMove, sourceId); const cancelled = new Utils.BooleanHolder(false); - applyPreApplyBattlerTagAbAttrs(PreApplyBattlerTagAbAttr, this, newTag, cancelled); + applyPreApplyBattlerTagAbAttrs(BattlerTagImmunityAbAttr, this, newTag, cancelled); + + const userField = this.getAlliedField(); + userField.forEach(pokemon => applyPreApplyBattlerTagAbAttrs(UserFieldBattlerTagImmunityAbAttr, pokemon, newTag, cancelled)); if (!cancelled.value && newTag.canAdd(this)) { this.summonData.tags.push(newTag); @@ -2282,7 +2351,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { lapseTags(lapseType: BattlerTagLapseType): void { const tags = this.summonData.tags; - tags.filter(t => lapseType === BattlerTagLapseType.FAINT || ((t.lapseType.some(lType => lType === lapseType)) && !(t.lapse(this, lapseType)))).forEach(t => { + tags.filter(t => lapseType === BattlerTagLapseType.FAINT || ((t.lapseTypes.some(lType => lType === lapseType)) && !(t.lapse(this, lapseType)))).forEach(t => { t.onRemove(this); tags.splice(tags.indexOf(t), 1); }); @@ -2639,6 +2708,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const cancelled = new Utils.BooleanHolder(false); applyPreSetStatusAbAttrs(StatusEffectImmunityAbAttr, this, effect, cancelled, quiet); + const userField = this.getAlliedField(); + userField.forEach(pokemon => applyPreSetStatusAbAttrs(UserFieldStatusEffectImmunityAbAttr, pokemon, effect, cancelled, quiet)); + if (cancelled.value) { return false; } @@ -3089,6 +3161,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return this.randSeedInt((max - min) + 1, min); } + /** + * Causes a Pokemon to leave the field (such as in preparation for a switch out/escape). + * @param clearEffects Indicates if effects should be cleared (true) or passed + * to the next pokemon, such as during a baton pass (false) + */ + leaveField(clearEffects: boolean = true) { + this.resetTurnData(); + if (clearEffects) { + this.resetSummonData(); + this.resetBattleData(); + } + this.hideInfo(); + this.setVisible(false); + this.scene.field.remove(this); + this.scene.triggerPokemonFormChange(this, SpeciesFormChangeActiveTrigger, true); + } + destroy(): void { this.battleInfo?.destroy(); super.destroy(); @@ -3133,7 +3222,7 @@ export class PlayerPokemon extends Pokemon { } if (!dataSource) { - this.generateAndPopulateMoveset(); + this.moveset = []; } this.generateCompatibleTms(); } @@ -3200,25 +3289,21 @@ export class PlayerPokemon extends Pokemon { return true; } - switchOut(batonPass: boolean, removeFromField: boolean = false): Promise { + /** + * Causes this mon to leave the field (via {@linkcode leaveField}) and then + * opens the party switcher UI to switch a new mon in + * @param batonPass Indicates if this switch was caused by a baton pass (and + * thus should maintain active mon effects) + */ + switchOut(batonPass: boolean): Promise { return new Promise(resolve => { - this.resetTurnData(); - if (!batonPass) { - this.resetSummonData(); - } - this.hideInfo(); - this.setVisible(false); + this.leaveField(!batonPass); this.scene.ui.setMode(Mode.PARTY, PartyUiMode.FAINT_SWITCH, this.getFieldIndex(), (slotIndex: integer, option: PartyOption) => { if (slotIndex >= this.scene.currentBattle.getBattlerCount() && slotIndex < 6) { this.scene.prependToPhase(new SwitchSummonPhase(this.scene, this.getFieldIndex(), slotIndex, false, batonPass), MoveEndPhase); } - if (removeFromField) { - this.setVisible(false); - this.scene.field.remove(this); - this.scene.triggerPokemonFormChange(this, SpeciesFormChangeActiveTrigger, true); - } - this.scene.ui.setMode(Mode.MESSAGE).then(() => resolve()); + this.scene.ui.setMode(Mode.MESSAGE).then(resolve); }, PartyUiHandler.FilterNonFainted); }); } @@ -3645,7 +3730,13 @@ export class EnemyPokemon extends Pokemon { } } + /** + * Determines the move this Pokemon will use on the next turn, as well as + * the Pokemon the move will target. + * @returns this Pokemon's next move in the format {move, moveTargets} + */ getNextMove(): QueuedMove { + // If this Pokemon has a move already queued, return it. const queuedMove = this.getMoveQueue().length ? this.getMoveset().find(m => m.moveId === this.getMoveQueue()[0].move) : null; @@ -3658,11 +3749,15 @@ export class EnemyPokemon extends Pokemon { } } + // Filter out any moves this Pokemon cannot use const movePool = this.getMoveset().filter(m => m.isUsable(this)); + // If no moves are left, use Struggle. Otherwise, continue with move selection if (movePool.length) { + // If there's only 1 move in the move pool, use it. if (movePool.length === 1) { return { move: movePool[0].moveId, targets: this.getNextTargets(movePool[0].moveId) }; } + // If a move is forced because of Encore, use it. const encoreTag = this.getTag(EncoreTag) as EncoreTag; if (encoreTag) { const encoreMove = movePool.find(m => m.moveId === encoreTag.moveId); @@ -3671,11 +3766,16 @@ export class EnemyPokemon extends Pokemon { } } switch (this.aiType) { - case AiType.RANDOM: + case AiType.RANDOM: // No enemy should spawn with this AI type in-game const moveId = movePool[this.scene.randBattleSeedInt(movePool.length)].moveId; return { move: moveId, targets: this.getNextTargets(moveId) }; case AiType.SMART_RANDOM: case AiType.SMART: + /** + * Move selection is based on the move's calculated "benefit score" against the + * best possible target(s) (as determined by {@linkcode getNextTargets}). + * For more information on how benefit scores are calculated, see `docs/enemy-ai.md`. + */ const moveScores = movePool.map(() => 0); const moveTargets = Object.fromEntries(movePool.map(m => [ m.moveId, this.getNextTargets(m.moveId) ])); for (const m in movePool) { @@ -3692,14 +3792,26 @@ export class EnemyPokemon extends Pokemon { } const target = this.scene.getField()[mt]; + /** + * The "target score" of a move is given by the move's user benefit score + the move's target benefit score. + * If the target is an ally, the target benefit score is multiplied by -1. + */ let targetScore = move.getUserBenefitScore(this, target, move) + move.getTargetBenefitScore(this, target, move) * (mt < BattlerIndex.ENEMY === this.isPlayer() ? 1 : -1); if (Number.isNaN(targetScore)) { console.error(`Move ${move.name} returned score of NaN`); targetScore = 0; } + /** + * If this move is unimplemented, or the move is known to fail when used, set its + * target score to -20 + */ if ((move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && ![Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id)) { targetScore = -20; } else if (move instanceof AttackMove) { + /** + * Attack moves are given extra multipliers to their base benefit score based on + * the move's type effectiveness against the target and whether the move is a STAB move. + */ const effectiveness = target.getAttackMoveEffectiveness(this, pokemonMove); if (target.isPlayer() !== this.isPlayer()) { targetScore *= effectiveness; @@ -3712,13 +3824,14 @@ export class EnemyPokemon extends Pokemon { targetScore /= 1.5; } } + /** If a move has a base benefit score of 0, its benefit score is assumed to be unimplemented at this point */ if (!targetScore) { targetScore = -20; } } targetScores.push(targetScore); } - + // When a move has multiple targets, its score is equal to the maximum target score across all targets moveScore += Math.max(...targetScores); // could make smarter by checking opponent def/spdef @@ -3727,6 +3840,7 @@ export class EnemyPokemon extends Pokemon { console.log(moveScores); + // Sort the move pool in decreasing order of move score const sortedMovePool = movePool.slice(0); sortedMovePool.sort((a, b) => { const scoreA = moveScores[movePool.indexOf(a)]; @@ -3735,10 +3849,12 @@ export class EnemyPokemon extends Pokemon { }); let r = 0; if (this.aiType === AiType.SMART_RANDOM) { + // Has a 5/8 chance to select the best move, and a 3/8 chance to advance to the next best move (and repeat this roll) while (r < sortedMovePool.length - 1 && this.scene.randBattleSeedInt(8) >= 5) { r++; } } else if (this.aiType === AiType.SMART) { + // The chance to advance to the next best move increases when the compared moves' scores are closer to each other. while (r < sortedMovePool.length - 1 && (moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) >= 0 && this.scene.randBattleSeedInt(100) < Math.round((moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) * 50)) { r++; @@ -3752,15 +3868,25 @@ export class EnemyPokemon extends Pokemon { return { move: Moves.STRUGGLE, targets: this.getNextTargets(Moves.STRUGGLE) }; } + /** + * Determines the Pokemon the given move would target if used by this Pokemon + * @param moveId {@linkcode Moves} The move to be used + * @returns The indexes of the Pokemon the given move would target + */ getNextTargets(moveId: Moves): BattlerIndex[] { const moveTargets = getMoveTargets(this, moveId); const targets = this.scene.getField(true).filter(p => moveTargets.targets.indexOf(p.getBattlerIndex()) > -1); + // If the move is multi-target, return all targets' indexes if (moveTargets.multiple) { return targets.map(p => p.getBattlerIndex()); } const move = allMoves[moveId]; + /** + * Get the move's target benefit score against each potential target. + * For allies, this score is multiplied by -1. + */ const benefitScores = targets .map(p => [ p.getBattlerIndex(), move.getTargetBenefitScore(this, p, move) * (p.isPlayer() === this.isPlayer() ? 1 : -1) ]); @@ -3784,12 +3910,14 @@ export class EnemyPokemon extends Pokemon { let targetWeights = sortedBenefitScores.map(s => s[1]); const lowestWeight = targetWeights[targetWeights.length - 1]; + // If the lowest target weight (i.e. benefit score) is negative, add abs(lowestWeight) to all target weights if (lowestWeight < 1) { for (let w = 0; w < targetWeights.length; w++) { targetWeights[w] += Math.abs(lowestWeight - 1); } } + // Remove any targets whose weights are less than half the max of the target weights from consideration const benefitCutoffIndex = targetWeights.findIndex(s => s < targetWeights[0] / 2); if (benefitCutoffIndex > -1) { targetWeights = targetWeights.slice(0, benefitCutoffIndex); @@ -3804,6 +3932,11 @@ export class EnemyPokemon extends Pokemon { return total; }, 0); + /** + * Generate a random number from 0 to (totalWeight-1), + * then select the first target whose cumulative weight (with all previous targets' weights) + * is greater than that random number. + */ const randValue = this.scene.randBattleSeedInt(totalWeight); let targetIndex: integer; @@ -3987,6 +4120,7 @@ export class EnemyPokemon extends Pokemon { this.pokeball = pokeballType; this.metLevel = this.level; this.metBiome = this.scene.arena.biomeType; + this.metSpecies = this.species.speciesId; const newPokemon = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, this.gender, this.shiny, this.variant, this.ivs, this.nature, this); party.push(newPokemon); ret = newPokemon; @@ -4017,7 +4151,7 @@ export interface AttackMoveResult { damage: integer; critical: boolean; sourceId: integer; - attackingPosition: BattlerIndex; + sourceBattlerIndex: BattlerIndex; } export class PokemonSummonData { @@ -4064,6 +4198,7 @@ export class PokemonTurnData { public currDamageDealt: integer = 0; public damageTaken: integer = 0; public attacksReceived: AttackMoveResult[] = []; + public order: number; } export enum AiType { diff --git a/src/field/trainer.ts b/src/field/trainer.ts index 3e78afeae83..107dfbe6831 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -121,8 +121,8 @@ export default class Trainer extends Phaser.GameObjects.Container { // Determine the title to include based on the configuration and includeTitle flag. let title = includeTitle && this.config.title ? this.config.title : null; - - if (this.name === "" && name.toLowerCase().includes("grunt")) { + const evilTeamTitles = ["grunt", "admin", "sage"]; + if (this.name === "" && evilTeamTitles.some(t => name.toLocaleLowerCase().includes(t))) { // This is a evil team grunt so we localize it by only using the "name" as the title title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, "_")}`); console.log("Localized grunt name: " + title); diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 61178144ded..5275411055e 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -24,10 +24,12 @@ import { Biome } from "#enums/biome"; import { TrainerType } from "#enums/trainer-type"; export class LoadingScene extends SceneBase { + public static readonly KEY = "loading"; + readonly LOAD_EVENTS = Phaser.Loader.Events; constructor() { - super("loading"); + super(LoadingScene.KEY); Phaser.Plugins.PluginCache.register("Loader", CacheBustedLoaderPlugin, "load"); initI18n(); @@ -434,7 +436,7 @@ export class LoadingScene extends SceneBase { } const intro = this.add.video(0, 0); - intro.on(Phaser.GameObjects.Events.VIDEO_COMPLETE, (video: Phaser.GameObjects.Video) => { + intro.once(Phaser.GameObjects.Events.VIDEO_COMPLETE, (video: Phaser.GameObjects.Video) => { this.tweens.add({ targets: intro, duration: 500, @@ -482,7 +484,10 @@ export class LoadingScene extends SceneBase { } }); - this.load.on(this.LOAD_EVENTS.COMPLETE, () => loadingGraphics.forEach(go => go.destroy())); + this.load.on(this.LOAD_EVENTS.COMPLETE, () => { + loadingGraphics.forEach(go => go.destroy()); + intro.destroy(); + }); } get gameHeight() { @@ -494,6 +499,17 @@ export class LoadingScene extends SceneBase { } async create() { + this.events.once(Phaser.Scenes.Events.DESTROY, () => this.handleDestroy()); this.scene.start("battle"); } + + handleDestroy() { + console.debug(`Destroying ${LoadingScene.KEY} scene`); + this.load.off(this.LOAD_EVENTS.PROGRESS); + this.load.off(this.LOAD_EVENTS.FILE_COMPLETE); + this.load.off(this.LOAD_EVENTS.COMPLETE); + // this.textures.remove("loading_bg"); is removed in BattleScene.launchBattle() + this.children.removeAll(true); + console.debug(`Destroyed ${LoadingScene.KEY} scene`); + } } diff --git a/src/locales/de/ability-trigger.ts b/src/locales/de/ability-trigger.ts index 68930fbee21..3c9586fb6f2 100644 --- a/src/locales/de/ability-trigger.ts +++ b/src/locales/de/ability-trigger.ts @@ -35,12 +35,12 @@ export const abilityTriggers: SimpleTranslationEntries = { "battlerTagImmunity": "{{abilityName}} von {{pokemonNameWithAffix}} verhindert {{battlerTagName}}!", "forewarn": "Vorwarnung von {{pokemonNameWithAffix}}: Konzentraion auf {{moveName}}!", "frisk": "{{pokemonNameWithAffix}} hat die Fähigkeit {{opponentAbilityName}} von {{opponentName}} erschnüffelt!", - "postWeatherLapseHeal": "{{abilityName}} von {{pokemonName}} füllte einige KP auf!", + "postWeatherLapseHeal": "{{abilityName}} von {{pokemonNameWithAffix}} füllte einige KP auf!", "postWeatherLapseDamage": "{{pokemonNameWithAffix}} wurde durch {{abilityName}} verletzt!", "postTurnLootCreateEatenBerry": "{{pokemonNameWithAffix}} hat {{berryName}} geerntet!", - "postTurnHeal": "{{abilityName}} von {{pokemonName}} füllte einige KP auf!", + "postTurnHeal": "{{abilityName}} von {{pokemonNameWithAffix}} füllte einige KP auf!", "fetchBall": "{{pokemonNameWithAffix}} hat einen {{pokeballName}} gefunden!", - "healFromBerryUse": "{{abilityName}} von {{pokemonName}} füllte einige KP auf!", + "healFromBerryUse": "{{abilityName}} von {{pokemonNameWithAffix}} füllte einige KP auf!", "arenaTrap": "{{abilityName}} von {{pokemonNameWithAffix}} verhindert den Tausch!", "postBattleLoot": "{{pokemonNameWithAffix}} hebt {{itemName}} auf!", "postFaintContactDamage": "{{abilityName}} von {{pokemonNameWithAffix}} schadet seinem Angreifer!", @@ -56,7 +56,8 @@ export const abilityTriggers: SimpleTranslationEntries = { "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} verfügt über zwei Fähigkeiten!", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} verfügt über zwei Fähigkeiten!", "postSummonVesselOfRuin": "Unheilsgefäß von {{pokemonNameWithAffix}} schwächt {{statName}} aller Pokémon im Umkreis!", - "postSummonSwordOfRuin": "Unheilsschwert von {{pokemonNameWithAffix}} schwächt {{statName} aller Pokémon im Umkreis!", + "postSummonSwordOfRuin": "Unheilsschwert von {{pokemonNameWithAffix}} schwächt {{statName}} aller Pokémon im Umkreis!", "postSummonTabletsOfRuin": "Unheilstafeln von {{pokemonNameWithAffix}} schwächt {{statName}} aller Pokémon im Umkreis!", "postSummonBeadsOfRuin": "Unheilsjuwelen von {{pokemonNameWithAffix}} schwächt {{statName}} aller Pokémon im Umkreis!", + "preventBerryUse": "{{pokemonNameWithAffix}} kriegt vor Anspannung keine Beeren mehr runter!", } as const; diff --git a/src/locales/de/arena-tag.ts b/src/locales/de/arena-tag.ts new file mode 100644 index 00000000000..cc0a821aade --- /dev/null +++ b/src/locales/de/arena-tag.ts @@ -0,0 +1,50 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const arenaTag: SimpleTranslationEntries = { + "yourTeam": "Pokémon auf deiner Seite", + "opposingTeam": "Pokémon auf gegnerischer Seite", + "arenaOnRemove": "Der Effekt von {{moveName}} lässt nach!", + "arenaOnRemovePlayer": "Der Effekt von {{moveName}} lässt auf deiner Seite nach!", + "arenaOnRemoveEnemy": "Der Effekt von {{moveName}} lässt auf der Seite des Gegners nach!", + "mistOnAdd": "Pokémon, die auf der Seite von {{pokemonNameWithAffix}} kämpfen, werden in Weißnebel gehüllt!!", + "mistApply": "Der Weißnebel verhindert die Senkung von Statuswerten!", + "reflectOnAdd": "Reflektor stärkt Pokémon gegen physische Attacken!", + "reflectOnAddPlayer": "Reflektor stärkt Pokémon auf deiner Seite gegen physische Attacken!", + "reflectOnAddEnemy": "Reflektor stärkt gegnerische Pokémon gegen physische Attacken!", + "lightScreenOnAdd": "Lichtschild stärkt Pokémon gegen Spezial-Attacken!", + "lightScreenOnAddPlayer": "Lichtschild stärkt Pokémon, die auf deiner Seite kämpfen, gegen Spezial-Attacken!", + "lightScreenOnAddEnemy": "Lichtschild stärkt gegnerische Pokémon gegen Spezial-Attacken!", + "auroraVeilOnAdd": "Auroraschleier stärkt Pokémon gegen physische und Spezial-Attacken", + "auroraVeilOnAddPlayer": "Auroraschleier stärkt Pokémon auf deiner Seite gegen physische und Spezial-Attacken!", + "auroraVeilOnAddEnemy": "Auroraschleier stärkt gegnerische Pokémon gegen physische und Spezial-Attacken!", + "conditionalProtectOnAdd": "Die Pokémon werden von {{moveName}} behütet!", + "conditionalProtectOnAddPlayer": "Die Pokémon auf deiner Seite werden von {{moveName}} behütet!", + "conditionalProtectOnAddEnemy": "Die Pokémon auf der gegnerischen Seite werden von {{moveName}} behütet!", + "conditionalProtectApply": "{{pokemonNameWithAffix}} wird durch {{moveName}} geschützt!", + "matBlockOnAdd": "{{pokemonNameWithAffix}} bringt seinen Tatami-Schild in Position!", + "wishTagOnAdd": "Der Wunschtraum von {{pokemonNameWithAffix}} erfüllt sich!", + "mudSportOnAdd": "Die Stärke aller Elektro-Attacken wurde reduziert!", + "mudSportOnRemove": "Lehmsuhler hört auf zu wirken!", + "waterSportOnAdd": "Die Stärke aller Feuer-Attacken wurde reduziert!", + "waterSportOnRemove": "Nassmacher hört auf zu wirken!", + "spikesOnAdd": "Die {{opponentDesc}} sind von Stacheln umgeben!", + "spikesActivateTrap": "Die {{pokemonNameWithAffix}} wurde durch Stachler verletzt!!", + "toxicSpikesOnAdd": "Die {{opponentDesc}} sind überall von giftigen Stacheln umgeben", + "toxicSpikesActivateTrapPoison": "{{pokemonNameWithAffix}} absorbiert die {{moveName}}!", + "stealthRockOnAdd": "Um die {{opponentDesc}} schweben spitze Steine!", + "stealthRockActivateTrap": "{{pokemonNameWithAffix}} wird von spitzen Steinen getroffen!!", + "stickyWebOnAdd": "Am Boden um die {{opponentDesc}} entspinnt sich ein {{moveName}}!", + "stickyWebActivateTrap": "{{pokemonName}} ist im Klebenetz gefangen!", + "trickRoomOnAdd": "{{pokemonNameWithAffix}} hat die Dimensionen verdreht!", + "trickRoomOnRemove": "Die verdrehte Dimension ist wieder normal!", + "gravityOnAdd": "Die Erdanziehung wurde verstärkt!", + "gravityOnRemove": "Die Erdanziehung ist wieder normal!", + "tailwindOnAdd": "Die Pokémon erhalten Rückenwind!", + "tailwindOnAddPlayer": "Die Pokémon, die auf deiner Seite kämpfen, erhalten Rückenwind!", + "tailwindOnAddEnemy": "Die gegnerischen Pokémon erhalten Rückenwind!", + "tailwindOnRemove": "Der Rückenwind hat sich gelegt!", + "tailwindOnRemovePlayer": "Der Rückenwind auf deiner Seite hat sich gelegt!", + "tailwindOnRemoveEnemy": "Der Rückenwind auf gegnerischer Seite hat sich gelegt!", + "happyHourOnAdd": "Goldene Zeiten sind angebrochen!", + "happyHourOnRemove": "Die goldenen Zeiten sind vorbei!", +} as const; diff --git a/src/locales/de/bgm-name.ts b/src/locales/de/bgm-name.ts index 2a247e51a44..3877aeea9bd 100644 --- a/src/locales/de/bgm-name.ts +++ b/src/locales/de/bgm-name.ts @@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = { "missing_entries" : "{{name}}", "battle_kanto_champion": "S2W2 Vs. Kanto Champion", "battle_johto_champion": "S2W2 Vs. Johto Champion", - "battle_hoenn_champion": "S2W2 Vs. Hoenn Champion", + "battle_hoenn_champion_g5": "S2W2 Vs. Hoenn Champion", + "battle_hoenn_champion_g6": "ORAS Vs. Hoenn Champion", "battle_sinnoh_champion": "S2W2 Vs. Champion Cynthia", "battle_champion_alder": "SW Vs. Champion Lauro", "battle_champion_iris": "S2W2 Vs. Champion Lilia", diff --git a/src/locales/de/config.ts b/src/locales/de/config.ts index 940e3927bfd..d0779c9eec4 100644 --- a/src/locales/de/config.ts +++ b/src/locales/de/config.ts @@ -1,6 +1,7 @@ import { ability } from "./ability"; import { abilityTriggers } from "./ability-trigger"; import { arenaFlyout } from "./arena-flyout"; +import { arenaTag } from "./arena-tag"; import { PGFachv, PGMachv } from "./achv"; import { battle } from "./battle"; import { battleInfo } from "./battle-info"; @@ -23,6 +24,7 @@ import { } from "./dialogue"; import { egg } from "./egg"; import { fightUiHandler } from "./fight-ui-handler"; +import { filterBar } from "./filter-bar"; import { gameMode } from "./game-mode"; import { gameStatsUiHandler } from "./game-stats-ui-handler"; import { growth } from "./growth"; @@ -34,7 +36,7 @@ import { move } from "./move"; import { nature } from "./nature"; import { pokeball } from "./pokeball"; import { pokemon } from "./pokemon"; -import { pokemonForm } from "./pokemon-form"; +import { pokemonForm, battlePokemonForm } from "./pokemon-form"; import { pokemonInfo } from "./pokemon-info"; import { pokemonInfoContainer } from "./pokemon-info-container"; import { pokemonSummary } from "./pokemon-summary"; @@ -50,14 +52,17 @@ import { partyUiHandler } from "./party-ui-handler"; import { settings } from "./settings.js"; import { common } from "./common.js"; import { modifierSelectUiHandler } from "./modifier-select-ui-handler"; +import { moveTriggers } from "./move-trigger"; export const deConfig = { ability: ability, abilityTriggers: abilityTriggers, arenaFlyout: arenaFlyout, + arenaTag: arenaTag, battle: battle, battleInfo: battleInfo, battleMessageUiHandler: battleMessageUiHandler, + battlePokemonForm: battlePokemonForm, battlerTags: battlerTags, berry: berry, bgmName: bgmName, @@ -77,6 +82,7 @@ export const deConfig = { PGFdoubleBattleDialogue: PGFdoubleBattleDialogue, egg: egg, fightUiHandler: fightUiHandler, + filterBar: filterBar, gameMode: gameMode, gameStatsUiHandler: gameStatsUiHandler, growth: growth, @@ -105,5 +111,6 @@ export const deConfig = { voucher: voucher, weather: weather, partyUiHandler: partyUiHandler, - modifierSelectUiHandler: modifierSelectUiHandler + modifierSelectUiHandler: modifierSelectUiHandler, + moveTriggers: moveTriggers }; diff --git a/src/locales/de/dialogue.ts b/src/locales/de/dialogue.ts index 02c497b3182..57fd9071463 100644 --- a/src/locales/de/dialogue.ts +++ b/src/locales/de/dialogue.ts @@ -378,6 +378,19 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Das war mal wieder ein Schuss in den Ofen!" }, }, + "rocket_admin": { + "encounter": { + 1: "Oh? Du wagst es, dich Team Rocket zu widersetzen? Du wirst es bereuen.", + 2: "Du glaubst, du kannst uns aufhalten? Naiver Narr!", + 3: "Ich werde dir die wahre Macht von Team Rocket zeigen!" + }, + "victory": { + 1: "Nein! Verzeih mir, Giovanni!", + 2: "Wie konnte das geschehen?", + 3: "Urgh... Du warst zu stark..." + }, + }, + "firebreather": { "encounter": { 1: "Meine Flammen werden dich verschlingen!", @@ -410,6 +423,20 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Wie kann das sein? Ich bin Teil vom mächtigen Team Magma! Wir wollen doch nur die Welt verbessern…" }, }, + "magma_admin": { + "encounter": { + 1: `Hahaha! Du hast den ganzen weiten Weg auf dich genommen! Aber du bist zu spät! + $Unsere Mission ist schon fast abgeschlossen!`, + 2: `Du willst dich in Team Magmas Angelegenheiten einmischen? Du bist so süß, dass es ekelhaft ist! + $Ich werde dich ein für alle Mal erledigen!`, + 3: "Ich werde dir zeigen, was wahrer Schmerz ist! Mach dich bereit!", + }, + "victory": { + 1: "Hahaha! Ouch! Ich habe wohl verloren...", + 2: "Du bist ekelhaft stark!", + 3: "Da habe ich meine eigene Medizin zu schmecken bekommen!" + }, + }, "aqua_grunt": { "encounter": { 1: "Du willst dich also mit Team Aqua anlegen? Du traust dich ja was… Dich werfe ich über Bord!", @@ -418,6 +445,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Vielleicht sollte ich wohl lieber selber über die Planke gehen…", }, }, + "aqua_admin": { + "encounter": { + 1: "Ich bin eine Stufe über den Rüpeln, die du bisher gesehen hast. Ich werde dich pulverisieren!", + 2: "Hmmm? Wer ist das? Wer ist dieses verwöhnte Gör?", + 3: "Was machst du hier? Bist du uns gefolgt? Dann müssen wir dich wohl loswerden!" + }, + "victory": { + 1: "Also habe ich auch verloren...", + 2: "Ahhh?! War ich zu nachsichtig mit dir?!", + 3: "W-was war das?" + }, + }, "galactic_grunt": { "encounter": { 1: "Team Galaktik wird die Welt in eine bessere Welt verwandeln! Und du wirst uns nicht aufhalten!" @@ -426,6 +465,19 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Zyrus wird uns für diese Niederlage bestrafen…" }, }, + "galactic_admin": { + "encounter": { + 1: "Ich bin einer der Commander von Team Galaktik. Wir werden Zyrus' Traum verwirklichen!", + 2: `Alles, was sich Team Galaktik widersetzt, muss zerschlagen werden! + $Selbst der Gedanke an Widerstand wird nicht toleriert!`, + 3: "Was ist los? Sag mir nicht, dass du zitterst? Mach ich dir Angst? Gut so! Knie nieder!" + }, + "victory": { + 1: "Das kann nicht sein?! Ich habe verloren?! Du... du freches Gör!", + 2: "Du, mein Freund, bist stark! Aber widestand ist zwecklos! Team Galaktik wird siegen!", + 3: "Gegen ein Kind zu verlieren... Meine Unachtsamkeit wird mir nicht verziehen werden..." + }, + }, "plasma_grunt": { "encounter": { 1: "Pokémon sollten frei sein! Team Plasma wird sie befreien!" @@ -434,6 +486,19 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Wie konnte ich verlieren? Ich dachte, ich würde die Welt retten…" }, }, + "plasma_sage": { + "encounter": { + 1: "Du könntest eine Bedrohung für Team Plasma werden, also werden wir dich hier eliminieren!", + 2: "Oh, ernsthaft... Ich hatte nicht erwartet, kämpfen zu müssen!", + 3: `Du bist ein beeindruckender Trainer, dass du es so weit geschafft hast. + $Als Weiser von Team Plasma werde ich dich besiegen!` + }, + "victory": { + 1: "G-Cis...", + 2: "Es ist bitterkalt. Ich zittere. Ich leide.", + 3: "Hm. Du bist ein klügerer Trainer, als ich erwartet hatte. Ich bin beeindruckt." + }, + }, "flare_grunt": { "encounter": { 1: `Ich bin ein Mitglied von Team Flare! Das sieht man mir doch an. Mein Stil ist unverkennbar! @@ -443,6 +508,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Stil ist wohl doch nicht alles…" }, }, + "flare_admin": { + "encounter": { + 1: "Ah ha ha! Es wäre mir ein Vergnügen. Komm schon, kleiner Trainer! Zeig mir, was du drauf hast!", + 2: "Wir von Team Flare sind die einzigen, die die Schönheit der Welt wirklich schätzen!", + 3: "Ich habe auf dich gewartet! Lass mich ein wenig an dir forschen! Komm, lass uns beginnen!" + }, + "victory": { + 1: "Du bist ziemlich stark. Oh ja, sehr stark, in der Tat.", + 2: "Es scheint als hätte ich mich geirrt… Der Sieger steht fest.", + 3: "Wunderbar! Erstaunlich! Du hast enormes Geschick und dieser Mut!" + }, + }, "rocket_boss_giovanni_1": { "encounter": { 1: `Ich bin beeindruckt, du hast es bis hierher geschafft! @@ -476,7 +553,7 @@ export const PGMdialogue: DialogueTranslationEntries = { $Wir brauchen mehr Landmassen um zu leben! Team Magma wird dieses Ziel mit aller Macht erreichen!` }, "victory": { - 1:"Ugh! Das entspricht nicht meinen Berechnungen! Wie konnte ich verlieren? Wir sehen uns wieder!" + 1: "Ugh! Das entspricht nicht meinen Berechnungen! Wie konnte ich verlieren? Wir sehen uns wieder!" }, "defeat": { 1: "Team Magma wird weiterhin die Welt verbessern!" @@ -542,7 +619,7 @@ export const PGMdialogue: DialogueTranslationEntries = { }, "plasma_boss_ghetsis_1": { "encounter": { - 1:"Ich werde nicht zulassen, dass mich jemand aufhält! Egal wer es auch sein mag!" + 1: "Ich werde nicht zulassen, dass mich jemand aufhält! Egal wer es auch sein mag!" }, "victory": { 1: "Wie kann das sein? Ich bin der Schöpfer von Team Plasma! Ich bin perfekt!" @@ -2604,7 +2681,7 @@ export const PGFbattleSpecDialogue: SimpleTranslationEntries = PGMbattleSpecDial // Dialogue that does not fit into any other category (e.g. tutorial messages, or the end of the game). For when the player character is male export const PGMmiscDialogue: SimpleTranslationEntries = { "ending": - `@c{smile}Oh? Du hast gewonnen?@d{96} @c{smile_eclosed}Ich schätze, das hätte ich wissen sollen. + `@c{smile}Oh? Du hast gewonnen?@d{96} @c{smile_eclosed}Ich schätze, das hätte ich wissen sollen. $Aber, du bist jetzt zurück. $@c{smile}Es ist vorbei.@d{64} Du hast die Schleife beendet. $@c{serious_smile_fists}Du hast auch deinen Traum erfüllt, nicht wahr?\nDu hast nicht einmal verloren. @@ -2615,7 +2692,7 @@ export const PGMmiscDialogue: SimpleTranslationEntries = { $@c{serious_smile_fists}Vielleicht können wir, wenn wir zurück sind, noch einen Kampf haben? $Wenn du dazu bereit bist.`, "ending_female": - `@c{shock}Du bist zurück?@d{32} Bedeutet das…@d{96} du hast gewonnen?! + `@c{shock}Du bist zurück?@d{32} Bedeutet das…@d{96} du hast gewonnen?! $@c{smile_ehalf}Ich hätte wissen sollen, dass du es in dir hast. $@c{smile_eclosed}Natürlich… ich hatte immer dieses Gefühl. $@c{smile}Es ist jetzt vorbei, richtig? Du hast die Schleife beendet. diff --git a/src/locales/de/filter-bar.ts b/src/locales/de/filter-bar.ts new file mode 100644 index 00000000000..1094b0fd43a --- /dev/null +++ b/src/locales/de/filter-bar.ts @@ -0,0 +1,33 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const filterBar: SimpleTranslationEntries = { + "genFilter": "Gen.", + "typeFilter": "Typ", + "caughtFilter": "Gefangen", + "unlocksFilter": "Freisch.", + "miscFilter": "Sonst.", + "sortFilter": "Sort.", + "all": "Alle", + "normal": "Normal", + "uncaught": "Nicht gefangen", + "passive": "Passive", + "passiveUnlocked": "Passive freigeschaltet", + "passiveLocked": "Passive gesperrt", + "costReduction": "Cost Reduction", + "costReductionUnlocked": "Cost Reduction Unlocked", + "costReductionLocked": "Cost Reduction Locked", + "ribbon": "Band", + "hasWon": "Hat Klassik-Modus gewonnen", + "hasNotWon": "Hat Klassik-Modus nicht gewonnen", + "hiddenAbility": "Hidden Ability", + "hasHiddenAbility": "Hidden Ability - Yes", + "noHiddenAbility": "Hidden Ability - No", + "pokerus": "Pokerus", + "hasPokerus": "Pokerus - Yes", + "noPokerus": "Pokerus - No", + "sortByNumber": "Pokédex-Nummer", + "sortByCost": "Kosten", + "sortByCandies": "Anzahl Bonbons", + "sortByIVs": "IS-Werte", + "sortByName": "Name", +}; diff --git a/src/locales/de/modifier.ts b/src/locales/de/modifier.ts index 50b7e80b252..5a8126e3d85 100644 --- a/src/locales/de/modifier.ts +++ b/src/locales/de/modifier.ts @@ -10,4 +10,5 @@ export const modifier: SimpleTranslationEntries = { "turnHeldItemTransferApply": "{{itemName}} von {{pokemonNameWithAffix}} wurde durch {{typeName}} von {{pokemonName}} absorbiert!", "contactHeldItemTransferApply": "{{itemName}} von {{pokemonNameWithAffix}} wurde durch {{typeName}} von {{pokemonName}} geklaut!", "enemyTurnHealApply": "{{pokemonNameWithAffix}} stellt einige KP wieder her!", + "bypassSpeedChanceApply": "Dank des Items {{itemName}} kann {{pokemonName}} schneller handeln als sonst!", } as const; diff --git a/src/locales/de/move-trigger.ts b/src/locales/de/move-trigger.ts index e69de29bb2d..427ec6acbde 100644 --- a/src/locales/de/move-trigger.ts +++ b/src/locales/de/move-trigger.ts @@ -0,0 +1,62 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const moveTriggers: SimpleTranslationEntries = { + "hitWithRecoil" : "{{pokemonName}} erleidet Schaden durch Rückstoß!", + "cutHpPowerUpMove": "{{pokemonName}} nutzt seine KP um seine Attacke zu verstärken!", + "absorbedElectricity": "{{pokemonName}} absorbiert elektrische Energie!", + "switchedStatChanges": "{{pokemonName}} tauschte die Statuswerteveränderungen mit dem Ziel!", + "goingAllOutForAttack": "{{pokemonName}} legt sich ins Zeug!", + "regainedHealth": "{{pokemonName}} erholt sich!", + "keptGoingAndCrashed": "{{pokemonName}} springt daneben und verletzt sich!", + "fled": "{{pokemonName}} ist geflüchtet!", + "cannotBeSwitchedOut": "{{pokemonName}} kann nicht ausgewechselt werden!", + "swappedAbilitiesWithTarget": "{{pokemonName}} tauscht Fähigkeiten mit dem Ziel!", + "coinsScatteredEverywhere": "Es sind überall Münzen verstreut!", + "attackedByItem": "{{pokemonName}} wird von seinem Item {{itemName}} angegriffen!", + "whippedUpAWhirlwind": "{{pokemonName}} erzeugt eine Windböe!", + "flewUpHigh": "{{pokemonName}} fliegt hoch empor!", + "tookInSunlight": "{{pokemonName}} absorbiert Sonnenlicht!", + "dugAHole": "{{pokemonName}} vergräbt sich in der Erde!", + "loweredItsHead": "{{pokemonName}} zieht seinen Kopf ein!", + "isGlowing": "{{pokemonName}} leuchtet grell!", + "bellChimed": "Eine Glocke läutet!", + "foresawAnAttack": "{{pokemonName}} sieht einen Angriff voraus!", + "hidUnderwater": "{{pokemonName}} taucht unter!", + "soothingAromaWaftedThroughArea": "Ein wohltuendes Aroma breitet sich aus!", + "sprangUp": "{{pokemonName}} springt hoch in die Luft!", + "choseDoomDesireAsDestiny": "{{pokemonName}} äußert einen Kismetwunsch für die Zukunft!", + "vanishedInstantly": "{{pokemonName}} verschwindet augenblicklich!", + "tookTargetIntoSky": "{{pokemonName}} entführt {{targetName}} in luftige Höhen!", + "becameCloakedInFreezingLight": "{{pokemonName}} wird von einem kühlen Licht umhüllt!", + "becameCloakedInFreezingAir": "{{pokemonName}} wird in klirrend kalte Luft gehüllt!", + "isChargingPower": "{{pokemonName}} saugt Kraft in sich auf!", + "burnedItselfOut": "{{pokemonName}} braucht sein Feuer komplett auf!", + "startedHeatingUpBeak": "{{pokemonName}} erhitzt seinen Schnabel!", + "isOverflowingWithSpacePower": "Kosmische Kräfte strömen aus {{pokemonName}}!", + "usedUpAllElectricity": "{{pokemonName}} braucht seinen Strom komplett auf!", + "stoleItem": "{{pokemonName}} hat {{targetName}} das Item {{itemName}} geklaut!", + "incineratedItem": "{{pokemonName}} hat {{itemName}} von {{targetName}} verbrannt. Es ist somit nutzlos geworden!", + "knockedOffItem": "{{pokemonName}} schlägt das Item {{itemName}} von {{targetName}} weg!", + "tookMoveAttack": "{{pokemonName}} wurde von {{moveName}} getroffen!", + "cutOwnHpAndMaximizedStat": "{{pokemonName}} nutzt seine KP und maximiert dadurch seinen {{statName}}-Wert!", + "copiedStatChanges": "{{pokemonName}} kopiert die Statusveränderungen von {{targetName}}!", + "magnitudeMessage": "Intensität {{magnitude}}!", + "tookAimAtTarget": "{{pokemonName}} zielt auf {{targetName}}!", + "transformedIntoType": "{{pokemonName}} nimmt den Typ {{typeName}} an!", + "copiedMove": "{{pokemonName}} kopiert {{moveName}}!", + "sketchedMove": "{{pokemonName}} ahmt die Attacke {{moveName}} nach!", + "acquiredAbility": "The {{pokemonName}} nimmt die Fähigkeit {{abilityName}} an!", + "copiedTargetAbility": "{{pokemonName}} kopiert{{abilityName}} von {{targetName}}!", + "transformedIntoTarget": "{{pokemonName}} verwandelt sich in {{targetName}}!", + "tryingToTakeFoeDown": "{{pokemonName}} versucht, den Angreifer mit sich zu nehmen!", + "addType": "{{pokemonName}} nimmt zusätzlich den Typ {{typeName}} an!", + "cannotUseMove": "{{pokemonName}} kann {{moveName}} nicht einsetzen!", + "healHp": "KP von {{pokemonName}} wurden aufgefrischt!", + "sacrificialFullRestore": "Das Heilopfer von {{pokemonName}} erreicht sein Ziel!", + "invertStats": "Alle Statusveränderungen von {{pokemonName}} wurden invertiert!", + "resetStats": "Die Statusveränderungen von {{pokemonName}} wurden aufgehoben!", + "faintCountdown": "{{pokemonName}} geht nach {{turnCount}} Runden K.O.!", + "copyType": "{{pokemonName}} hat den Typ von {{targetPokemonName}} angenommen!", + "suppressAbilities": "Die Fähigkeit von {{pokemonName}} wirkt nicht mehr!", + "swapArenaTags": "{{pokemonName}} hat die Effekte, die auf den beiden Seiten des Kampffeldes wirken, miteinander getauscht!", +} as const; diff --git a/src/locales/de/pokemon-form.ts b/src/locales/de/pokemon-form.ts index ee4e3a8f9be..53ecc310411 100644 --- a/src/locales/de/pokemon-form.ts +++ b/src/locales/de/pokemon-form.ts @@ -1,6 +1,6 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; -export const pokemonForm: SimpleTranslationEntries = { +export const battlePokemonForm: SimpleTranslationEntries = { // Battle forms "mega": "Mega-{{pokemonName}}", "mega-x": "Mega-{{pokemonName}} X", @@ -9,6 +9,14 @@ export const pokemonForm: SimpleTranslationEntries = { "gigantamax": "G-Dyna-{{pokemonName}}", "eternamax": "U-Dyna-{{pokemonName}}", + "megaChange": "{{preName}} hat sich zu {{pokemonName}} mega-entwickelt!", + "gigantamaxChange": "{{preName}} hat sich zu {{pokemonName}} gigadynamaximiert!", + "eternamaxChange": "{{preName}} hat sich zu {{pokemonName}} unendynamaximiert!", + "revertChange": "{{pokemonName}} hat seine ursprüngliche Form zurückerlangt!", + "formChange": "{{preName}} hat seine Form geändert!", +} as const; + +export const pokemonForm: SimpleTranslationEntries = { // Starters forms // 1G "pikachuCosplay": "Cosplay", diff --git a/src/locales/de/starter-select-ui-handler.ts b/src/locales/de/starter-select-ui-handler.ts index 9cf08846401..e8ae4ed201e 100644 --- a/src/locales/de/starter-select-ui-handler.ts +++ b/src/locales/de/starter-select-ui-handler.ts @@ -7,7 +7,8 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; */ export const starterSelectUiHandler: SimpleTranslationEntries = { "confirmStartTeam": "Mit diesen Pokémon losziehen?", - "invalidParty": "This is not a valid starting party!", + "confirmExit": "Do you want to exit?", + "invalidParty": "Das ist kein gültiges Team!", "gen1": "I", "gen2": "II", "gen3": "III", @@ -23,6 +24,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "nature": "Wesen:", "eggMoves": "Ei-Attacken", "addToParty": "Zum Team hinzufügen", + "removeFromParty": "Aus Team entfernen", "toggleIVs": "DVs anzeigen/verbergen", "manageMoves": "Attacken ändern", "manageNature": "Wesen ändern", diff --git a/src/locales/de/status-effect.ts b/src/locales/de/status-effect.ts index 997d005987e..b48bd468626 100644 --- a/src/locales/de/status-effect.ts +++ b/src/locales/de/status-effect.ts @@ -33,7 +33,7 @@ export const statusEffect: StatusEffectTranslationEntries = { description: "Paralyse", obtain: "{{pokemonNameWithAffix}} wurde paralysiert!\nEs kann eventuell nicht handeln!", obtainSource: "{{pokemonNameWithAffix}} wurde durch {{sourceText}} paralysiert,\nEs kann eventuell nicht handeln!", - activation: "{{pokemonNameWithAffix}}ist paralysiert!\nEs kann nicht angreifen!", + activation: "{{pokemonNameWithAffix}} ist paralysiert!\nEs kann nicht angreifen!", overlap: "{{pokemonNameWithAffix}} ist bereits paralysiert!", heal: "Die Paralyse von {{pokemonNameWithAffix}} wurde aufgehoben!" }, diff --git a/src/locales/de/trainers.ts b/src/locales/de/trainers.ts index 1390bf410ae..5b156afd331 100644 --- a/src/locales/de/trainers.ts +++ b/src/locales/de/trainers.ts @@ -128,21 +128,32 @@ export const trainerClasses: SimpleTranslationEntries = { "rocket_grunt": "Rüpel von Team Rocket", "rocket_grunt_female": "Rüpel von Team Rocket", "rocket_grunts": "Rüpel von Team Rocket", + "rocket_admin": "Team Rocket Vorstand", + "rocket_admin_female": "Team Rocket Vorstand", "magma_grunt": "Rüpel von Team Magma", "magma_grunt_female": "Rüpel von Team Magma", "magma_grunts": "Rüpel von Team Magma", + "magma_admin": "Team Magma Vorstand", + "magma_admin_female": "Team Magma Vorstand", "aqua_grunt": "Rüpel von Team Aqua", "aqua_grunt_female": "Rüpel von Team Aqua", "aqua_grunts": "Rüpel von Team Aqua", + "aqua_admin": "Team Aqua Vorstand", + "aqua_admin_female": "Team Aqua Vorstand", "galactic_grunt": "Rüpel von Team Galaktik", "galactic_grunt_female": "Rüpel von Team Galaktik", "galactic_grunts": "Rüpel von Team Galaktik", + "galactic_admin": "Team Galaktik Commander", + "galactic_admin_female": "Team Galaktik Commander", "plasma_grunt": "Rüpel von Team Plasma", "plasma_grunt_female": "Rüpel von Team Plasma", "plasma_grunts": "Rüpel von Team Plasma", + "plasma_sage": "Weiser von Team Plasma", "flare_grunt": "Rüpel von Team Flare", "flare_grunt_female": "Rüpel von Team Flare", "flare_grunts": "Rüpel von Team Flare", + "flare_admin": "Team Flare Vorstand", + "flare_admin_female": "Team Flare Vorstand", } as const; // Names of special trainers like gym leaders, elite four, and the champion diff --git a/src/locales/en/ability-trigger.ts b/src/locales/en/ability-trigger.ts index 8e35ea4deb9..ce41a964922 100644 --- a/src/locales/en/ability-trigger.ts +++ b/src/locales/en/ability-trigger.ts @@ -59,4 +59,5 @@ export const abilityTriggers: SimpleTranslationEntries = { "postSummonSwordOfRuin": "{{pokemonNameWithAffix}}'s Sword of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}'s Tablets of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}'s Beads of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", + "preventBerryUse": "{{pokemonNameWithAffix}} is too\nnervous to eat berries!", } as const; diff --git a/src/locales/en/arena-tag.ts b/src/locales/en/arena-tag.ts new file mode 100644 index 00000000000..8bc2302368a --- /dev/null +++ b/src/locales/en/arena-tag.ts @@ -0,0 +1,50 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const arenaTag: SimpleTranslationEntries = { + "yourTeam": "your team", + "opposingTeam": "the opposing team", + "arenaOnRemove": "{{moveName}}'s effect wore off.", + "arenaOnRemovePlayer": "{{moveName}}'s effect wore off\non your side.", + "arenaOnRemoveEnemy": "{{moveName}}'s effect wore off\non the foe's side.", + "mistOnAdd": "{{pokemonNameWithAffix}}'s team became\nshrouded in mist!", + "mistApply": "The mist prevented\nthe lowering of stats!", + "reflectOnAdd": "Reflect reduced the damage of physical moves.", + "reflectOnAddPlayer": "Reflect reduced the damage of physical moves on your side.", + "reflectOnAddEnemy": "Reflect reduced the damage of physical moves on the foe's side.", + "lightScreenOnAdd": "Light Screen reduced the damage of special moves.", + "lightScreenOnAddPlayer": "Light Screen reduced the damage of special moves on your side.", + "lightScreenOnAddEnemy": "Light Screen reduced the damage of special moves on the foe's side.", + "auroraVeilOnAdd": "Aurora Veil reduced the damage of moves.", + "auroraVeilOnAddPlayer": "Aurora Veil reduced the damage of moves on your side.", + "auroraVeilOnAddEnemy": "Aurora Veil reduced the damage of moves on the foe's side.", + "conditionalProtectOnAdd": "{{moveName}} protected team!", + "conditionalProtectOnAddPlayer": "{{moveName}} protected your team!", + "conditionalProtectOnAddEnemy": "{{moveName}} protected the\nopposing team!", + "conditionalProtectApply": "{{moveName}} protected {{pokemonNameWithAffix}}!", + "matBlockOnAdd": "{{pokemonNameWithAffix}} intends to flip up a mat\nand block incoming attacks!", + "wishTagOnAdd": "{{pokemonNameWithAffix}}'s wish\ncame true!", + "mudSportOnAdd": "Electricity's power was weakened!", + "mudSportOnRemove": "The effects of Mud Sport\nhave faded.", + "waterSportOnAdd": "Fire's power was weakened!", + "waterSportOnRemove": "The effects of Water Sport\nhave faded.", + "spikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!", + "spikesActivateTrap": "{{pokemonNameWithAffix}} is hurt\nby the spikes!", + "toxicSpikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!", + "toxicSpikesActivateTrapPoison": "{{pokemonNameWithAffix}} absorbed the {{moveName}}!", + "stealthRockOnAdd": "Pointed stones float in the air\naround {{opponentDesc}}!", + "stealthRockActivateTrap": "Pointed stones dug into\n{{pokemonNameWithAffix}}!", + "stickyWebOnAdd": "A {{moveName}} has been laid out on the ground around the opposing team!", + "stickyWebActivateTrap": "The opposing {{pokemonName}} was caught in a sticky web!", + "trickRoomOnAdd": "{{pokemonNameWithAffix}} twisted\nthe dimensions!", + "trickRoomOnRemove": "The twisted dimensions\nreturned to normal!", + "gravityOnAdd": "Gravity intensified!", + "gravityOnRemove": "Gravity returned to normal!", + "tailwindOnAdd": "The Tailwind blew from behind team!", + "tailwindOnAddPlayer": "The Tailwind blew from behind\nyour team!", + "tailwindOnAddEnemy": "The Tailwind blew from behind\nthe opposing team!", + "tailwindOnRemove": "Team's Tailwind petered out!", + "tailwindOnRemovePlayer": "Your team's Tailwind petered out!", + "tailwindOnRemoveEnemy": "The opposing team's Tailwind petered out!", + "happyHourOnAdd": "Everyone is caught up in the happy atmosphere!", + "happyHourOnRemove": "The atmosphere returned to normal.", +} as const; diff --git a/src/locales/en/bgm-name.ts b/src/locales/en/bgm-name.ts index 01fb86b281d..be9a8f621c7 100644 --- a/src/locales/en/bgm-name.ts +++ b/src/locales/en/bgm-name.ts @@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = { "missing_entries" : "{{name}}", "battle_kanto_champion": "B2W2 Kanto Champion Battle", "battle_johto_champion": "B2W2 Johto Champion Battle", - "battle_hoenn_champion": "B2W2 Hoenn Champion Battle", + "battle_hoenn_champion_g5": "B2W2 Hoenn Champion Battle", + "battle_hoenn_champion_g6": "ORAS Hoenn Champion Battle", "battle_sinnoh_champion": "B2W2 Sinnoh Champion Battle", "battle_champion_alder": "BW Unova Champion Battle", "battle_champion_iris": "B2W2 Unova Champion Battle", diff --git a/src/locales/en/config.ts b/src/locales/en/config.ts index 970bf5b71fc..a98dd750fbe 100644 --- a/src/locales/en/config.ts +++ b/src/locales/en/config.ts @@ -3,6 +3,7 @@ import { settings } from "./settings.js"; import { ability } from "./ability"; import { abilityTriggers } from "./ability-trigger"; import { arenaFlyout } from "./arena-flyout"; +import { arenaTag } from "./arena-tag"; import { PGFachv, PGMachv } from "./achv"; import { battle } from "./battle"; import { battleInfo } from "./battle-info"; @@ -25,6 +26,7 @@ import { } from "./dialogue"; import { egg } from "./egg"; import { fightUiHandler } from "./fight-ui-handler"; +import { filterBar } from "./filter-bar"; import { gameMode } from "./game-mode"; import { gameStatsUiHandler } from "./game-stats-ui-handler"; import { growth } from "./growth"; @@ -37,7 +39,7 @@ import { nature } from "./nature"; import { partyUiHandler } from "./party-ui-handler"; import { pokeball } from "./pokeball"; import { pokemon } from "./pokemon"; -import { pokemonForm } from "./pokemon-form"; +import { pokemonForm, battlePokemonForm } from "./pokemon-form"; import { pokemonInfo } from "./pokemon-info"; import { pokemonInfoContainer } from "./pokemon-info-container"; import { pokemonSummary } from "./pokemon-summary"; @@ -50,14 +52,17 @@ import { tutorial } from "./tutorial"; import { voucher } from "./voucher"; import { terrain, weather } from "./weather"; import { modifierSelectUiHandler } from "./modifier-select-ui-handler"; +import { moveTriggers } from "./move-trigger"; export const enConfig = { ability: ability, abilityTriggers: abilityTriggers, arenaFlyout: arenaFlyout, + arenaTag: arenaTag, battle: battle, battleInfo: battleInfo, battleMessageUiHandler: battleMessageUiHandler, + battlePokemonForm: battlePokemonForm, battlerTags: battlerTags, berry: berry, bgmName: bgmName, @@ -77,6 +82,7 @@ export const enConfig = { PGFdoubleBattleDialogue: PGFdoubleBattleDialogue, egg: egg, fightUiHandler: fightUiHandler, + filterBar: filterBar, gameMode: gameMode, gameStatsUiHandler: gameStatsUiHandler, growth: growth, @@ -105,5 +111,6 @@ export const enConfig = { voucher: voucher, weather: weather, partyUiHandler: partyUiHandler, - modifierSelectUiHandler: modifierSelectUiHandler + modifierSelectUiHandler: modifierSelectUiHandler, + moveTriggers: moveTriggers }; diff --git a/src/locales/en/dialogue.ts b/src/locales/en/dialogue.ts index dda8891b788..44693c38aa1 100644 --- a/src/locales/en/dialogue.ts +++ b/src/locales/en/dialogue.ts @@ -391,6 +391,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Team Rocket blasting off again!" }, }, + "rocket_admin": { + "encounter": { + 1: "Oh? You managed to get this far? You must be quite the trainer.", + 2: "That's quite enough of you playing hero, kid.", + 3: "I'll show you how scary an angry adult can be!" + }, + "victory": { + 1: "No! Forgive me Giovanni!", + 2: "How could this be?", + 3: "Urgh... You were too strong..." + }, + }, "magma_grunt": { "encounter": { 1: " If you get in the way of Team Magma, don’t expect any mercy!" @@ -399,6 +411,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Huh? I lost?!" }, }, + "magma_admin": { + "encounter": { + 1: "Hehehe! So you've come all the way here! But you're too late!", + 2: "You're going to meddle in Team Magma's affairs? You're so cute you're disgusting! I'll put you down kiddy!", + 3: "I'm going to give you a little taste of pain! Resign yourself to it!" + }, + "victory": { + 1: "Hehehe... So I lost...", + 2: "You're disgustingly strong!", + 3: "Ahahaha! Ouch!" + }, + }, "aqua_grunt": { "encounter": { 1: "No one who crosses Team Aqua gets any mercy, not even kids!" @@ -407,6 +431,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "You're kidding me!" }, }, + "aqua_admin": { + "encounter": { + 1: "I'm a cut above the grunts you've seen so far. I'm going to puvlerize you!", + 2: "Hahn? What's this? Who's this spoiled brat?", + 3: "What are you doing here? Did you follow us?" + }, + "victory": { + 1: "So I lost too...", + 2: "Ahhh?! Did I go too easy on you?!", + 3: "Wh-what was that?" + }, + }, "galactic_grunt": { "encounter": { 1: "Don't mess with Team Galactic!" @@ -415,6 +451,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Shut down..." }, }, + "galactic_admin": { + "encounter": { + 1: "I'm one of Team Galactic's Commanders.", + 2: "Anything that opposes Team Galactic must be crushed! Even the very thought of opposition will not be tolerated!", + 3: "What's the matter? Don't tell me you're shaking?" + }, + "victory": { + 1: "This can't be?! I lost?! You... you uppity brat!", + 2: "You, my friend, are tough!", + 3: "Losing to some child... Being careless cost me too much." + }, + }, "plasma_grunt": { "encounter": { 1: "We won't tolerate people who have different ideas!" @@ -423,6 +471,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Plasmaaaaaaaaa!" }, }, + "plasma_sage": { + "encounter": { + 1: "You could become a threat to Team Plasma, so we will eliminate you here!", + 2: "Oh, for crying out loud... I didn't expect to have to fight!", + 3: "You're an impressive Trainer to have made it this far." + }, + "victory": { + 1: "Ghetsis...", + 2: "It's bitter cold. I'm shivering. I'm suffering.", + 3: "Hmph. You're a smarter Trainer than I expected." + }, + }, "flare_grunt": { "encounter": { 1: "Fashion is most important to us!" @@ -431,6 +491,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "The future doesn't look bright for me." }, }, + "flare_admin": { + "encounter": { + 1: "Ah ha ha! It would be my pleasure. Come on, little Trainer! Let's see what you've got!", + 2: "Hmm... You're more powerful than you look. I wonder how much energy there is inside you.", + 3: "I've been waiting for you! I need to do a little research on you! Come, let us begin!" + }, + "victory": { + 1: "You're quite strong. Oh yes-very strong, indeed.", + 2: "Ding-ding-ding! Yup, you did it! To the victor goes the spoils!", + 3: "Wonderful! Amazing! You have tremendous skill and bravery!" + }, + }, "rocket_boss_giovanni_1": { "encounter": { 1: "So! I must say, I am impressed you got here!" diff --git a/src/locales/en/filter-bar.ts b/src/locales/en/filter-bar.ts new file mode 100644 index 00000000000..7a3174957ea --- /dev/null +++ b/src/locales/en/filter-bar.ts @@ -0,0 +1,33 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const filterBar: SimpleTranslationEntries = { + "genFilter": "Gen", + "typeFilter": "Type", + "caughtFilter": "Caught", + "unlocksFilter": "Unlocks", + "miscFilter": "Misc", + "sortFilter": "Sort", + "all": "All", + "normal": "Normal", + "uncaught": "Uncaught", + "passive": "Passive", + "passiveUnlocked": "Passive Unlocked", + "passiveLocked": "Passive Locked", + "costReduction": "Cost Reduction", + "costReductionUnlocked": "Cost Reduction Unlocked", + "costReductionLocked": "Cost Reduction Locked", + "ribbon": "Ribbon", + "hasWon": "Ribbon - Yes", + "hasNotWon": "Ribbon - No", + "hiddenAbility": "Hidden Ability", + "hasHiddenAbility": "Hidden Ability - Yes", + "noHiddenAbility": "Hidden Ability - No", + "pokerus": "Pokerus", + "hasPokerus": "Pokerus - Yes", + "noPokerus": "Pokerus - No", + "sortByNumber": "No.", + "sortByCost": "Cost", + "sortByCandies": "Candy Count", + "sortByIVs": "IVs", + "sortByName": "Name", +}; diff --git a/src/locales/en/modifier.ts b/src/locales/en/modifier.ts index 85098cdaaec..26a6a9c18ae 100644 --- a/src/locales/en/modifier.ts +++ b/src/locales/en/modifier.ts @@ -10,4 +10,5 @@ export const modifier: SimpleTranslationEntries = { "turnHeldItemTransferApply": "{{pokemonNameWithAffix}}'s {{itemName}} was absorbed\nby {{pokemonName}}'s {{typeName}}!", "contactHeldItemTransferApply": "{{pokemonNameWithAffix}}'s {{itemName}} was snatched\nby {{pokemonName}}'s {{typeName}}!", "enemyTurnHealApply": "{{pokemonNameWithAffix}}\nrestored some HP!", + "bypassSpeedChanceApply": "{{pokemonName}} can act faster than normal, thanks to its {{itemName}}!", } as const; diff --git a/src/locales/en/move-trigger.ts b/src/locales/en/move-trigger.ts new file mode 100644 index 00000000000..1d9d6459d83 --- /dev/null +++ b/src/locales/en/move-trigger.ts @@ -0,0 +1,62 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const moveTriggers: SimpleTranslationEntries = { + "hitWithRecoil" : "{{pokemonName}} was damaged by the recoil!", + "cutHpPowerUpMove": "{{pokemonName}} cut its own HP to power up its move!", + "absorbedElectricity": "{{pokemonName}} absorbed electricity!", + "switchedStatChanges": "{{pokemonName}} switched stat changes with the target!", + "goingAllOutForAttack": "{{pokemonName}} is going all out for this attack!", + "regainedHealth": "{{pokemonName}} regained\nhealth!", + "keptGoingAndCrashed": "{{pokemonName}} kept going\nand crashed!", + "fled": "{{pokemonName}} fled!", + "cannotBeSwitchedOut": "{{pokemonName}} can't be switched out!", + "swappedAbilitiesWithTarget": "{{pokemonName}} swapped\nabilities with its target!", + "coinsScatteredEverywhere": "Coins were scattered everywhere!", + "attackedByItem": "{{pokemonName}} is about to be attacked by its {{itemName}}!", + "whippedUpAWhirlwind": "{{pokemonName}} whipped\nup a whirlwind!", + "flewUpHigh": "{{pokemonName}} flew\nup high!", + "tookInSunlight": "{{pokemonName}} absorbed light!", + "dugAHole": "{{pokemonName}} burrowed its way under the ground!", + "loweredItsHead": "{{pokemonName}} tucked in its head!", + "isGlowing": "{{pokemonName}} became cloaked in a harsh light!", + "bellChimed": "A bell chimed!", + "foresawAnAttack": "{{pokemonName}} foresaw\nan attack!", + "hidUnderwater": "{{pokemonName}} hid\nunderwater!", + "soothingAromaWaftedThroughArea": "A soothing aroma wafted through the area!", + "sprangUp": "{{pokemonName}} sprang up!", + "choseDoomDesireAsDestiny": "{{pokemonName}} chose\nDoom Desire as its destiny!", + "vanishedInstantly": "{{pokemonName}} vanished\ninstantly!", + "tookTargetIntoSky": "{{pokemonName}} took {{targetName}}\ninto the sky!", + "becameCloakedInFreezingLight": "{{pokemonName}} became cloaked\nin a freezing light!", + "becameCloakedInFreezingAir": "{{pokemonName}} became cloaked\nin freezing air!", + "isChargingPower": "{{pokemonName}} is absorbing power!", + "burnedItselfOut": "{{pokemonName}} burned itself out!", + "startedHeatingUpBeak": "{{pokemonName}} started\nheating up its beak!", + "isOverflowingWithSpacePower": "{{pokemonName}} is overflowing\nwith space power!", + "usedUpAllElectricity": "{{pokemonName}} used up all its electricity!", + "stoleItem": "{{pokemonName}} stole\n{{targetName}}'s {{itemName}}!", + "incineratedItem": "{{pokemonName}} incinerated\n{{targetName}}'s {{itemName}}!", + "knockedOffItem": "{{pokemonName}} knocked off\n{{targetName}}'s {{itemName}}!", + "tookMoveAttack": "{{pokemonName}} took\nthe {{moveName}} attack!", + "cutOwnHpAndMaximizedStat": "{{pokemonName}} cut its own HP\nand maximized its {{statName}}!", + "copiedStatChanges": "{{pokemonName}} copied\n{{targetName}}'s stat changes!", + "magnitudeMessage": "Magnitude {{magnitude}}!", + "tookAimAtTarget": "{{pokemonName}} took aim\nat {{targetName}}!", + "transformedIntoType": "{{pokemonName}} transformed\ninto the {{typeName}} type!", + "copiedMove": "{{pokemonName}} copied\n{{moveName}}!", + "sketchedMove": "{{pokemonName}} sketched\n{{moveName}}!", + "acquiredAbility": "The {{pokemonName}} acquired\n{{abilityName}}!", + "copiedTargetAbility": "{{pokemonName}} copied the {{targetName}}'s\n{{abilityName}}!", + "transformedIntoTarget": "{{pokemonName}} transformed\ninto {{targetName}}!", + "tryingToTakeFoeDown": "{{pokemonName}} is hoping to take its attacker down with it!", + "addType": "{{typeName}} was added to\n{{pokemonName}}!", + "cannotUseMove": "{{pokemonName}} cannot use {{moveName}}!", + "healHp": "{{pokemonName}} had its HP restored.", + "sacrificialFullRestore": "{{pokemonName}}'s Healing Wish\nwas granted!", + "invertStats": "{{pokemonName}}'s stat changes\nwere all reversed!", + "resetStats": "{{pokemonName}}'s stat changes\nwere eliminated!", + "faintCountdown": "{{pokemonName}}\nwill faint in {{turnCount}} turns.", + "copyType": "{{pokemonName}}'s type became the same as\n{{targetPokemonName}}'s type!", + "suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!", + "swapArenaTags": "{{pokemonName}} swapped the battle effects affecting each side of the field!", +} as const; diff --git a/src/locales/en/pokemon-form.ts b/src/locales/en/pokemon-form.ts index b80819d5c64..e8d6fb8df4a 100644 --- a/src/locales/en/pokemon-form.ts +++ b/src/locales/en/pokemon-form.ts @@ -1,7 +1,6 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; -export const pokemonForm: SimpleTranslationEntries = { - // Battle forms +export const battlePokemonForm: SimpleTranslationEntries = { "mega": "Mega {{pokemonName}}", "mega-x": "Mega {{pokemonName}} X", "mega-y": "Mega {{pokemonName}} Y", @@ -9,6 +8,14 @@ export const pokemonForm: SimpleTranslationEntries = { "gigantamax": "G-Max {{pokemonName}}", "eternamax": "E-Max {{pokemonName}}", + "megaChange": "{{preName}} Mega Evolved\ninto {{pokemonName}}!", + "gigantamaxChange": "{{preName}} Gigantamaxed\ninto {{pokemonName}}!", + "eternamaxChange": "{{preName}} Eternamaxed\ninto {{pokemonName}}!", + "revertChange": "{{pokemonName}} reverted\nto its original form!", + "formChange": "{{preName}} changed form!", +} as const; + +export const pokemonForm: SimpleTranslationEntries = { // Starters forms // 1G "pikachuCosplay": "Cosplay", diff --git a/src/locales/en/starter-select-ui-handler.ts b/src/locales/en/starter-select-ui-handler.ts index 6d7b7f7cfb2..deb4236c8ba 100644 --- a/src/locales/en/starter-select-ui-handler.ts +++ b/src/locales/en/starter-select-ui-handler.ts @@ -7,6 +7,7 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; */ export const starterSelectUiHandler: SimpleTranslationEntries = { "confirmStartTeam": "Begin with these Pokémon?", + "confirmExit": "Do you want to exit?", "invalidParty": "This is not a valid starting party!", "gen1": "I", "gen2": "II", diff --git a/src/locales/en/status-effect.ts b/src/locales/en/status-effect.ts index 162b2ada281..5914fc27298 100644 --- a/src/locales/en/status-effect.ts +++ b/src/locales/en/status-effect.ts @@ -14,7 +14,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Poison", description: "poisoning", obtain: "{{pokemonNameWithAffix}}\nwas poisoned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas poisoned by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas poisoned by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is hurt\nby poison!", overlap: "{{pokemonNameWithAffix}} is\nalready poisoned!", heal: "{{pokemonNameWithAffix}} was\ncured of its poison!" @@ -23,7 +23,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Toxic", description: "poisoning", obtain: "{{pokemonNameWithAffix}}\nwas badly poisoned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas badly poisoned by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas badly poisoned by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is hurt\nby poison!", overlap: "{{pokemonNameWithAffix}} is\nalready poisoned!", heal: "{{pokemonNameWithAffix}} was\ncured of its poison!" @@ -32,7 +32,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Paralysis", description: "paralysis", obtain: "{{pokemonNameWithAffix}} was paralyzed,\nIt may be unable to move!", - obtainSource: "{{pokemonNameWithAffix}} was paralyzed by {{sourceText}}!\nIt may be unable to move!", + obtainSource: "{{pokemonNameWithAffix}} was paralyzed by the {{sourceText}}!\nIt may be unable to move!", activation: "{{pokemonNameWithAffix}} is paralyzed!\nIt can't move!", overlap: "{{pokemonNameWithAffix}} is\nalready paralyzed!", heal: "{{pokemonNameWithAffix}} was\nhealed of paralysis!" @@ -41,7 +41,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Sleep", description: "sleep", obtain: "{{pokemonNameWithAffix}}\nfell asleep!", - obtainSource: "{{pokemonNameWithAffix}}\nfell asleep from {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nfell asleep from the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is fast asleep.", overlap: "{{pokemonNameWithAffix}} is\nalready asleep!", heal: "{{pokemonNameWithAffix}} woke up!" @@ -50,7 +50,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Freeze", description: "freezing", obtain: "{{pokemonNameWithAffix}}\nwas frozen solid!", - obtainSource: "{{pokemonNameWithAffix}}\nwas frozen solid by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas frozen solid by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is\nfrozen solid!", overlap: "{{pokemonNameWithAffix}} is\nalready frozen!", heal: "{{pokemonNameWithAffix}} was\ndefrosted!" @@ -59,7 +59,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Burn", description: "burn", obtain: "{{pokemonNameWithAffix}}\nwas burned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas burned by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas burned by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is hurt\nby its burn!", overlap: "{{pokemonNameWithAffix}} is\nalready burned!", heal: "{{pokemonNameWithAffix}} was\nhealed of its burn!" diff --git a/src/locales/en/trainers.ts b/src/locales/en/trainers.ts index b59cfdc4fda..00367865d14 100644 --- a/src/locales/en/trainers.ts +++ b/src/locales/en/trainers.ts @@ -126,17 +126,34 @@ export const trainerClasses: SimpleTranslationEntries = { "workers": "Workers", "youngster": "Youngster", "rocket_grunt": "Rocket Grunt", + "rocket_grunts": "Rocket Grunts", "rocket_grunt_female": "Rocket Grunt", + "rocket_admin": "Rocket Admin", + "rocket_admin_female": "Rocket Admin", "magma_grunt": "Magma Grunt", "magma_grunt_female": "Magma Grunt", + "magma_grunts": "Magma Grunts", + "magma_admin": "Magma Admin", + "magma_admin_female": "Magma Admin", "aqua_grunt": "Aqua Grunt", "aqua_grunt_female": "Aqua Grunt", + "aqua_grunts": "Aqua Grunts", + "aqua_admin": "Aqua Admin", + "aqua_admin_female": "Aqua Admin", "galactic_grunt": "Galactic Grunt", "galactic_grunt_female": "Galactic Grunt", + "galactic_grunts": "Galactic Grunts", + "galactic_admin": "Galactic Admin", + "galactic_admin_female": "Galactic Admin", "plasma_grunt": "Plasma Grunt", "plasma_grunt_female": "Plasma Grunt", + "plasma_grunts": "Plasma Grunts", + "plasma_sage": "Plasma Sage", "flare_grunt": "Flare Grunt", "flare_grunt_female": "Flare Grunt", + "flare_grunts": "Flare Grunts", + "flare_admin": "Flare Admin", + "flare_admin_female": "Flare Admin", } as const; // Names of special trainers like gym leaders, elite four, and the champion diff --git a/src/locales/es/ability-trigger.ts b/src/locales/es/ability-trigger.ts index d5d487235e9..6b1f66a11e3 100644 --- a/src/locales/es/ability-trigger.ts +++ b/src/locales/es/ability-trigger.ts @@ -59,4 +59,5 @@ export const abilityTriggers: SimpleTranslationEntries = { "postSummonSwordOfRuin": "{{pokemonNameWithAffix}}'s Sword of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}'s Tablets of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}'s Beads of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", + "preventBerryUse": "{{pokemonNameWithAffix}} está muy nervioso y no puede comer bayas!", } as const; diff --git a/src/locales/es/arena-tag.ts b/src/locales/es/arena-tag.ts new file mode 100644 index 00000000000..8bc2302368a --- /dev/null +++ b/src/locales/es/arena-tag.ts @@ -0,0 +1,50 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const arenaTag: SimpleTranslationEntries = { + "yourTeam": "your team", + "opposingTeam": "the opposing team", + "arenaOnRemove": "{{moveName}}'s effect wore off.", + "arenaOnRemovePlayer": "{{moveName}}'s effect wore off\non your side.", + "arenaOnRemoveEnemy": "{{moveName}}'s effect wore off\non the foe's side.", + "mistOnAdd": "{{pokemonNameWithAffix}}'s team became\nshrouded in mist!", + "mistApply": "The mist prevented\nthe lowering of stats!", + "reflectOnAdd": "Reflect reduced the damage of physical moves.", + "reflectOnAddPlayer": "Reflect reduced the damage of physical moves on your side.", + "reflectOnAddEnemy": "Reflect reduced the damage of physical moves on the foe's side.", + "lightScreenOnAdd": "Light Screen reduced the damage of special moves.", + "lightScreenOnAddPlayer": "Light Screen reduced the damage of special moves on your side.", + "lightScreenOnAddEnemy": "Light Screen reduced the damage of special moves on the foe's side.", + "auroraVeilOnAdd": "Aurora Veil reduced the damage of moves.", + "auroraVeilOnAddPlayer": "Aurora Veil reduced the damage of moves on your side.", + "auroraVeilOnAddEnemy": "Aurora Veil reduced the damage of moves on the foe's side.", + "conditionalProtectOnAdd": "{{moveName}} protected team!", + "conditionalProtectOnAddPlayer": "{{moveName}} protected your team!", + "conditionalProtectOnAddEnemy": "{{moveName}} protected the\nopposing team!", + "conditionalProtectApply": "{{moveName}} protected {{pokemonNameWithAffix}}!", + "matBlockOnAdd": "{{pokemonNameWithAffix}} intends to flip up a mat\nand block incoming attacks!", + "wishTagOnAdd": "{{pokemonNameWithAffix}}'s wish\ncame true!", + "mudSportOnAdd": "Electricity's power was weakened!", + "mudSportOnRemove": "The effects of Mud Sport\nhave faded.", + "waterSportOnAdd": "Fire's power was weakened!", + "waterSportOnRemove": "The effects of Water Sport\nhave faded.", + "spikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!", + "spikesActivateTrap": "{{pokemonNameWithAffix}} is hurt\nby the spikes!", + "toxicSpikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!", + "toxicSpikesActivateTrapPoison": "{{pokemonNameWithAffix}} absorbed the {{moveName}}!", + "stealthRockOnAdd": "Pointed stones float in the air\naround {{opponentDesc}}!", + "stealthRockActivateTrap": "Pointed stones dug into\n{{pokemonNameWithAffix}}!", + "stickyWebOnAdd": "A {{moveName}} has been laid out on the ground around the opposing team!", + "stickyWebActivateTrap": "The opposing {{pokemonName}} was caught in a sticky web!", + "trickRoomOnAdd": "{{pokemonNameWithAffix}} twisted\nthe dimensions!", + "trickRoomOnRemove": "The twisted dimensions\nreturned to normal!", + "gravityOnAdd": "Gravity intensified!", + "gravityOnRemove": "Gravity returned to normal!", + "tailwindOnAdd": "The Tailwind blew from behind team!", + "tailwindOnAddPlayer": "The Tailwind blew from behind\nyour team!", + "tailwindOnAddEnemy": "The Tailwind blew from behind\nthe opposing team!", + "tailwindOnRemove": "Team's Tailwind petered out!", + "tailwindOnRemovePlayer": "Your team's Tailwind petered out!", + "tailwindOnRemoveEnemy": "The opposing team's Tailwind petered out!", + "happyHourOnAdd": "Everyone is caught up in the happy atmosphere!", + "happyHourOnRemove": "The atmosphere returned to normal.", +} as const; diff --git a/src/locales/es/bgm-name.ts b/src/locales/es/bgm-name.ts index ab6de0b81b5..f7316ca1166 100644 --- a/src/locales/es/bgm-name.ts +++ b/src/locales/es/bgm-name.ts @@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = { "missing_entries" : "{{name}}", "battle_kanto_champion": "B2W2 - ¡Vs Campeón de Kanto!", "battle_johto_champion": "B2W2 - ¡Vs Campeón de Johto!", - "battle_hoenn_champion": "B2W2 - ¡Vs Campeón de Hoenn!", + "battle_hoenn_champion_g5": "B2W2 - ¡Vs Campeón de Hoenn!", + "battle_hoenn_champion_g6": "ORAS - ¡Vs Campeón de Hoenn!", "battle_sinnoh_champion": "B2W2 - ¡Vs Campeón de Sinnoh!", "battle_champion_alder": "BW - ¡Vs Campeón de Teselia!", "battle_champion_iris": "B2W2 - ¡Vs Campeón de Teselia!", diff --git a/src/locales/es/config.ts b/src/locales/es/config.ts index ab23a52b7bb..ce9ad19aac3 100644 --- a/src/locales/es/config.ts +++ b/src/locales/es/config.ts @@ -1,6 +1,7 @@ import { ability } from "./ability"; import { abilityTriggers } from "./ability-trigger"; import { arenaFlyout } from "./arena-flyout"; +import { arenaTag } from "./arena-tag"; import { PGFachv, PGMachv } from "./achv"; import { battle } from "./battle"; import { battleInfo } from "./battle-info"; @@ -23,6 +24,7 @@ import { } from "./dialogue"; import { egg } from "./egg"; import { fightUiHandler } from "./fight-ui-handler"; +import { filterBar } from "./filter-bar"; import { gameMode } from "./game-mode"; import { gameStatsUiHandler } from "./game-stats-ui-handler"; import { growth } from "./growth"; @@ -34,7 +36,7 @@ import { move } from "./move"; import { nature } from "./nature"; import { pokeball } from "./pokeball"; import { pokemon } from "./pokemon"; -import { pokemonForm } from "./pokemon-form"; +import { pokemonForm, battlePokemonForm } from "./pokemon-form"; import { pokemonInfo } from "./pokemon-info"; import { pokemonInfoContainer } from "./pokemon-info-container"; import { pokemonSummary } from "./pokemon-summary"; @@ -50,14 +52,17 @@ import { partyUiHandler } from "./party-ui-handler"; import { settings } from "./settings.js"; import { common } from "./common.js"; import { modifierSelectUiHandler } from "./modifier-select-ui-handler"; +import { moveTriggers } from "./move-trigger"; export const esConfig = { ability: ability, abilityTriggers: abilityTriggers, arenaFlyout: arenaFlyout, + arenaTag: arenaTag, battle: battle, battleInfo: battleInfo, battleMessageUiHandler: battleMessageUiHandler, + battlePokemonForm: battlePokemonForm, battlerTags: battlerTags, berry: berry, bgmName: bgmName, @@ -77,6 +82,7 @@ export const esConfig = { PGFdoubleBattleDialogue: PGFdoubleBattleDialogue, egg: egg, fightUiHandler: fightUiHandler, + filterBar: filterBar, gameMode: gameMode, gameStatsUiHandler: gameStatsUiHandler, growth: growth, @@ -105,5 +111,6 @@ export const esConfig = { voucher: voucher, weather: weather, partyUiHandler: partyUiHandler, - modifierSelectUiHandler: modifierSelectUiHandler + modifierSelectUiHandler: modifierSelectUiHandler, + moveTriggers: moveTriggers }; diff --git a/src/locales/es/dialogue.ts b/src/locales/es/dialogue.ts index c1b23b57fe0..d19acc3ec0f 100644 --- a/src/locales/es/dialogue.ts +++ b/src/locales/es/dialogue.ts @@ -106,85 +106,85 @@ export const PGMdialogue: DialogueTranslationEntries = { }, "fisherman_female": { "encounter": { - 1: "Woah! I've hooked a big one!", - 2: "Line's in, ready to reel in success!", - 3: "Ready to make waves!" + 1: "¡Eh! ¡He pescado uno grande!", + 2: "¡La caña está lista, para pescar la victoria!", + 3: "¡Lista para hacer olas!" }, "victory": { - 1: "I'll be back with a stronger hook.", - 2: "I'll reel in victory next time.", - 3: "I'm just sharpening my hooks for the comeback!" + 1: "Volveré con un pez más grande.", + 2: "Pescaré la victoria a la siguiente...", + 3: "¡Estoy afilando mis anzuelos para la próxima!" }, }, "swimmer": { "encounter": { - 1: "Time to dive in!", - 2: "Let's ride the waves of victory!", - 3: "Ready to make a splash!", + 1: "¡Listo para bucear!", + 2: "¡Montemos las olas de la victoria!", + 3: "¡Listo para darme un chapuzón!", }, "victory": { - 1: "Drenched in defeat!", - 2: "A wave of defeat!", - 3: "Back to shore, I guess.", + 1: "¡Empapado en la derrota!", + 2: "¡Las olas de la derrota!", + 3: "Vuelta a la costa, supongo.", }, }, "backpacker": { "encounter": { - 1: "Pack up, game on!", - 2: "Let's see if you can keep pace!", - 3: "Gear up, challenger!", - 4: "I've spent 20 years trying to find myself… But where am I?" + 1: "¡Recoge y vámonos!", + 2: "¡Veamos si puedes mantener la velocidad!", + 3: "¡Sube la marcha, entrenador!", + 4: "Traté de encontrarme un sentido durante 20 años… ¿Pero dónde estoy?" }, "victory": { - 1: "Tripped up this time!", - 2: "Oh, I think I'm lost.", - 3: "Dead end!", - 4: "Wait up a second! Hey! Don't you know who I am?" + 1: "¡Tropecé esta vez!", + 2: "Oh, creo que me perdí.", + 3: "¡Punto muerto!", + 4: "¡Un segundo! ¡Ey! ¿No sabes quién soy?" }, }, "ace_trainer": { "encounter": { - 1: "You seem quite confident.", - 2: "Your Pokémon… Show them to me…", - 3: "Because I'm an Ace Trainer, people think I'm strong.", - 4: "Are you aware of what it takes to be an Ace Trainer?" + 1: "Pareces muy seguro en ti mismo.", + 2: "Enséñame tus Pokémon…", + 3: "Como soy un Entrenador Guay, la gente cree que soy fuerte.", + 4: "¿Sabes lo que toma ser un Entrenador Guay?" }, "victory": { - 1: "Yes… You have good Pokémon…", - 2: "What?! But I'm a battling genius!", - 3: "Of course, you are the main character!", - 4: "OK! OK! You could be an Ace Trainer!" + 1: "Sí, tienes buenos Pokémon…", + 2: "¡¿Cómo?! ¡Si soy un genio combatiendo!", + 3: "Claro, ¡tienes el poder del guión!", + 4: "¡OK! ¡OK! ¡Puedes ser un Entrenador Guay!" }, "defeat": { - 1: "I am devoting my body and soul to Pokémon battles!", - 2: "All within my expectations… Nothing to be surprised about…", - 3: "I thought I'd grow up to be a frail person who looked like they would break if you squeezed them too hard.", - 4: "Of course I'm strong and don't lose. It's important that I win gracefully." + 1: "¡Doy mi cuerpo y alma para los combates Pokémon.", + 2: "Según mis expectativas… Nada de qué sorprenderse…", + 3: "Pensé que crecería como persona frágil que parece que rompe a llorar si le hacen daño muy fuerte.", + 4: "Por supuesto que soy fuerte y no pierdo. Es importante que gane con gracia." } }, "parasol_lady": { "encounter": { - 1: "Time to grace the battlefield with elegance and poise!", + 1: "¡Tiempo de agradar al campo de batalla con elegancia y esmero!", }, "victory": { - 1: "My elegance remains unbroken!", + 1: "¡Mi elegancia es indestructible!", } }, "twins": { "encounter": { - 1: "Get ready, because when we team up, it's double the trouble!", - 2: "Two hearts, one strategy – let's see if you can keep up with our twin power!", - 3: "Hope you're ready for double trouble, because we're about to bring the heat!" + 1: "¡Prepárate, porque cuando somos juntas el problema es doble!", + 2: "Dos almas, una estrategia – ¡veamos si eres capaz de seguir nuestro poder gemelo!", + 3: "¡Espero que estés listo para el doble problema, porque traeremos mucha emoción!" }, "victory": { - 1: "We may have lost this round, but our bond remains unbreakable!", - 2: "Our twin spirit won't be dimmed for long.", - 3: "We'll come back stronger as a dynamic duo!" + 1: "¡Aunque hayamos perdido esta ronda, nuestra unión es indestructible!", + 2: "Nuestro espíritu gemelo no seguirá así por mucho tiempo.", + 3: "¡Volveremos más fuertes como un dúo dinámico!" }, "defeat": { - 1: "Twin power reigns supreme!", - 2: "Two hearts, one triumph!", - 3: "Double the smiles, double the victory dance!" + 1: "¡El poder gemelo triunfa como ninguno!", + 2: "¡Dos almas, un triunfo!", + 3: "¡Doble sonrisa, doble baile de victoria!" } }, "cyclist": { @@ -565,73 +565,73 @@ export const PGMdialogue: DialogueTranslationEntries = { }, "brock": { "encounter": { - 1: "My expertise on Rock-type Pokémon will take you down! Come on!", - 2: "My rock-hard willpower will overwhelm you!", - 3: "Allow me to show you the true strength of my Pokémon!" + 1: "Mi conocimiento en Pokémon tipo Roca te aplastará. ¡Dalo todo!", + 2: "¡Mi determinación tipo Roca te sorprenderá!", + 3: "¡Permíteme enseñarte la verdadera fuerza de mis Pokémon!" }, "victory": { - 1: "Your Pokémon's strength have overcome my rock-hard defenses!", - 2: "The world is huge! I'm glad to have had a chance to battle you.", - 3: "Perhaps I should go back to pursuing my dream as a Pokémon Breeder…" + 1: "¡La fuerza de mis Pokémon superó mi defensa dura como una roca!", + 2: "¡El mundo es enorme! Me encantó tener una oportunidad para combatir contigo.", + 3: "A lo mejor tendría que volver a mi sueño de ser un Criapokémon…" }, "defeat": { - 1: "The best offense is a good defense!\nThat's my way of doing things!", - 2: "Come study rocks with me next time to better learn how to fight them!", - 3: "Hah, all my traveling around the regions is paying off!" + 1: "¡La mejor ofensa es una buena defensa!\n¡Esa es mi manera de hacer las cosas!", + 2: "¡Ven preparado sobre las rocas para saber cómo luchar contra las mías!", + 3: "Ja, ¡todos mis viajes por regiones se notan!" } }, "misty": { "encounter": { - 1: "My policy is an all out offensive with Water-type Pokémon!", - 2: "Hiya, I'll show you the strength of my aquatic Pokémon!", - 3: "My dream was to go on a journey and battle powerful trainers…\nWill you be a sufficient challenge?" + 1: "¡Mi política es muy ofensiva con Pokémon tipo Agua!", + 2: "Oye, ¡te enseñaré la auténtica fuerza de mis Pokémon tipo Agua!", + 3: "Mi sueño era viajar conociendo Entrenadores fuertes…\n¿Serás suficiente desafío?" }, "victory": { - 1: "You really are strong… I'll admit that you are skilled…", - 2: "Grrr… You know you just got lucky, right?!", - 3: "Wow, you're too much! I can't believe you beat me!" + 1: "Eres muy fuerte… Admito tu talento…", + 2: "Grrr… ¡¿Solo tuviste suerte, sabes?!", + 3: "¡Guau, eres demasiado! ¡No me creo que me hayas vencido!" }, "defeat": { - 1: "Was the mighty Misty too much for you?", - 2: "I hope you saw my Pokémon's elegant swimming techniques!", - 3: "Your Pokémon were no match for my pride and joys!" + 1: "¿Fue la valiente Misty demasiado para ti?", + 2: "¡Espero que hayas visto la elegancia en las técnicas de nado de mis Pokémon!", + 3: "¡Tus Pokémon no fueron rival para mi orgullo y felicidad!" } }, "lt_surge": { "encounter": { - 1: "My Electric Pokémon saved me during the war! I'll show you how!", - 2: "Ten-hut! I'll shock you into surrender!", - 3: "I'll zap you just like I do to all my enemies in battle!" + 1: "¡Mis Pokémon eléctricos me salvaron en la guerra! ¡Te enseñaré cómo!", + 2: "¡10 voltios! ¡Te electrocutaré hasta la derrota!", + 3: "¡Te electrocutaré como a todos mis enemigos en combate!" }, "victory": { - 1: "Whoa! Your team's the real deal, kid!", - 2: "Aaargh, you're strong! Even my electric tricks lost against you.", - 3: "That was an absolutely shocking loss!" + 1: "¡Guau! ¡Tu equipo es lo mejor de lo mejor, chaval!", + 2: "¡Aaargh, eres fuerte! Incluso mis trucos electrizantes fallaron.", + 3: "¡Fue una derrota electrizante!" }, "defeat": { - 1: "Oh yeah! When it comes to Electric-type Pokémon, I'm number one in the world!", - 2: "Hahaha! That was an electrifying battle, kid!", - 3: "A Pokémon battle is war, and I have showed you first-hand combat!" + 1: "¡Oh sí! Cuando se trata de Pokémon tipo Eléctrico, ¡soy el número uno!", + 2: "¡Jajaja! ¡Menuda batalla electrizante, chaval!", + 3: "Un combate Pokémon es la guerra, ¡y te he enseñado lo esencial, chaval!" } }, "erika": { "encounter": { - 1: "Ah, the weather is lovely here…\nOh, a battle? Very well then.", - 2: "My Pokémon battling skills rival that of my flower arranging skills.", - 3: "Oh, I hope the pleasant aroma of my Pokémon doesn't put me to sleep again…", - 4: "Seeing flowers in a garden is so soothing." + 1: "El tiempo es maravilloso aquí…\n¿Oh un combate? Perfecto, entonces.", + 2: "Mis dotes como Entrenadora rivalizan mis dotes como florista.", + 3: "Espero que el dulce aroma de mis Pokémon no me dé sueño…", + 4: "Ver flores en un jardín es tan relajante." }, "victory": { - 1: "Oh! I concede defeat.", - 2: "That match was most delightful.", - 3: "Ah, it appears it is my loss…", - 4: "Oh, my goodness." + 1: "¡Oh! Reconozco mi derrota.", + 2: "Este combate fue agradable.", + 3: "Ah, es mi derrota…", + 4: "Oh Dios mío." }, "defeat": { - 1: "I was afraid I would doze off…", - 2: "Oh my, it seems my Grass Pokémon overwhelmed you.", - 3: "That battle was such a soothing experience.", - 4: "Oh… Is that all?" + 1: "Tenía miedo de dormirme…", + 2: "Oh, parece que mis Pokémon tipo planta te sobrecargaron.", + 3: "Este combate fue una experiencia muy relajante.", + 4: "Oh… ¿Eso es todo?" } }, "janine": { diff --git a/src/locales/es/filter-bar.ts b/src/locales/es/filter-bar.ts new file mode 100644 index 00000000000..b55a35c1adf --- /dev/null +++ b/src/locales/es/filter-bar.ts @@ -0,0 +1,33 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const filterBar: SimpleTranslationEntries = { + "genFilter": "Gen.", + "typeFilter": "Tipo", + "caughtFilter": "Caught", + "unlocksFilter": "Otros", + "miscFilter": "Misc", + "sortFilter": "Orden", + "all": "Todo", + "normal": "Normal", + "uncaught": "No Capt.", + "passive": "Passive", + "passiveUnlocked": "Pasiva Desbloq.", + "passiveLocked": "Pasiva Bloq.", + "costReduction": "Cost Reduction", + "costReductionUnlocked": "Cost Reduction Unlocked", + "costReductionLocked": "Cost Reduction Locked", + "ribbon": "Ribbon", + "hasWon": "Ya ha ganado", + "hasNotWon": "Aún no ha ganado", + "hiddenAbility": "Hidden Ability", + "hasHiddenAbility": "Hidden Ability - Yes", + "noHiddenAbility": "Hidden Ability - No", + "pokerus": "Pokerus", + "hasPokerus": "Pokerus - Yes", + "noPokerus": "Pokerus - No", + "sortByNumber": "Núm.", + "sortByCost": "Coste", + "sortByCandies": "# Caramelos", + "sortByIVs": "IVs", + "sortByName": "Nombre", +}; diff --git a/src/locales/es/modifier.ts b/src/locales/es/modifier.ts index 85098cdaaec..b0a3d36e233 100644 --- a/src/locales/es/modifier.ts +++ b/src/locales/es/modifier.ts @@ -10,4 +10,5 @@ export const modifier: SimpleTranslationEntries = { "turnHeldItemTransferApply": "{{pokemonNameWithAffix}}'s {{itemName}} was absorbed\nby {{pokemonName}}'s {{typeName}}!", "contactHeldItemTransferApply": "{{pokemonNameWithAffix}}'s {{itemName}} was snatched\nby {{pokemonName}}'s {{typeName}}!", "enemyTurnHealApply": "{{pokemonNameWithAffix}}\nrestored some HP!", + "bypassSpeedChanceApply": "¡Gracias {{itemName}} {{pokemonName}} puede tener prioridad!", } as const; diff --git a/src/locales/es/move-trigger.ts b/src/locales/es/move-trigger.ts new file mode 100644 index 00000000000..3ff93997cc2 --- /dev/null +++ b/src/locales/es/move-trigger.ts @@ -0,0 +1,62 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const moveTriggers: SimpleTranslationEntries = { + "hitWithRecoil" : "{{pokemonName}} was damaged by the recoil!", + "cutHpPowerUpMove": "{{pokemonName}} cut its own HP to power up its move!", + "absorbedElectricity": "{{pokemonName}} absorbed electricity!", + "switchedStatChanges": "{{pokemonName}} switched stat changes with the target!", + "goingAllOutForAttack": "{{pokemonName}} is going all out for this attack!", + "regainedHealth": "{{pokemonName}} regained\nhealth!", + "keptGoingAndCrashed": "{{pokemonName}} kept going\nand crashed!", + "fled": "{{pokemonName}} fled!", + "cannotBeSwitchedOut": "{{pokemonName}} can't be switched out!", + "swappedAbilitiesWithTarget": "{{pokemonName}} swapped\nabilities with its target!", + "coinsScatteredEverywhere": "Coins were scattered everywhere!", + "attackedByItem": "{{pokemonName}} is about to be attacked by its {{itemName}}!", + "whippedUpAWhirlwind": "{{pokemonName}} whipped\nup a whirlwind!", + "flewUpHigh": "{{pokemonName}} flew\nup high!", + "tookInSunlight": "{{pokemonName}} absorbed light!", + "dugAHole": "{{pokemonName}} burrowed its way under the ground!", + "loweredItsHead": "{{pokemonName}} tucked in its head!", + "isGlowing": "{{pokemonName}} became cloaked in a harsh light!", + "bellChimed": "A bell chimed!", + "foresawAnAttack": "{{pokemonName}} foresaw\nan attack!", + "hidUnderwater": "{{pokemonName}} hid\nunderwater!", + "soothingAromaWaftedThroughArea": "A soothing aroma wafted through the area!", + "sprangUp": "{{pokemonName}} sprang up!", + "choseDoomDesireAsDestiny": "{{pokemonName}} chose\nDoom Desire as its destiny!", + "vanishedInstantly": "{{pokemonName}} vanished\ninstantly!", + "tookTargetIntoSky": "{{pokemonName}} took {{targetName}}\ninto the sky!", + "becameCloakedInFreezingLight": "{{pokemonName}} became cloaked\nin a freezing light!", + "becameCloakedInFreezingAir": "{{pokemonName}} became cloaked\nin freezing air!", + "isChargingPower": "{{pokemonName}} is absorbing power!", + "burnedItselfOut": "{{pokemonName}} burned itself out!", + "startedHeatingUpBeak": "{{pokemonName}} started\nheating up its beak!", + "isOverflowingWithSpacePower": "{{pokemonName}} is overflowing\nwith space power!", + "usedUpAllElectricity": "{{pokemonName}} used up all its electricity!", + "stoleItem": "{{pokemonName}} stole\n{{targetName}}'s {{itemName}}!", + "incineratedItem": "{{pokemonName}} incinerated\n{{targetName}}'s {{itemName}}!", + "knockedOffItem": "{{pokemonName}} knocked off\n{{targetName}}'s {{itemName}}!", + "tookMoveAttack": "{{pokemonName}} took\nthe {{moveName}} attack!", + "cutOwnHpAndMaximizedStat": "{{pokemonName}} cut its own HP\nand maximized its {{statName}}!", + "copiedStatChanges": "{{pokemonName}} copied\n{{targetName}}'s stat changes!", + "magnitudeMessage": "Magnitude {{magnitude}}!", + "tookAimAtTarget": "{{pokemonName}} took aim\nat {{targetName}}!", + "transformedIntoType": "{{pokemonName}} transformed\ninto the {{typeName}} type!", + "copiedMove": "{{pokemonName}} copied\n{{moveName}}!", + "sketchedMove": "{{pokemonName}} sketched\n{{moveName}}!", + "acquiredAbility": "The {{pokemonName}} acquired\n{{abilityName}}!", + "copiedTargetAbility": "{{pokemonName}} copied the {{targetName}}'s\n{{abilityName}}!", + "transformedIntoTarget": "{{pokemonName}} transformed\ninto {{targetName}}!", + "tryingToTakeFoeDown": "{{pokemonName}} is hoping to take its attacker down with it!", + "addType": "{{typeName}} was added to\n{{pokemonName}}!", + "cannotUseMove": "{{pokemonName}} cannot use {{moveName}}!", + "healHp": "{{pokemonName}} had its HP restored.", + "sacrificialFullRestore": "{{pokemonName}}'s Healing Wish\nwas granted!", + "invertStats": "{{pokemonName}}'s stat changes\nwere all reversed!", + "resetStats": "{{pokemonName}}'s stat changes\nwere eliminated!", + "faintCountdown": "{{pokemonName}}\nwill faint in {{turnCount}} turns.", + "copyType": "{{pokemonName}}'s type\nchanged to match {{targetPokemonName}}'s!", + "suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!", + "swapArenaTags": "{{pokemonName}} swapped the battle effects affecting each side of the field!", +} as const; diff --git a/src/locales/es/pokemon-form.ts b/src/locales/es/pokemon-form.ts index 415593b0446..96e40bcfbbd 100644 --- a/src/locales/es/pokemon-form.ts +++ b/src/locales/es/pokemon-form.ts @@ -1,7 +1,6 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; -export const pokemonForm: SimpleTranslationEntries = { - // Battle forms +export const battlePokemonForm: SimpleTranslationEntries = { "mega": "Mega {{pokemonName}}", "mega-x": "Mega {{pokemonName}} X", "mega-y": "Mega {{pokemonName}} Y", @@ -9,6 +8,14 @@ export const pokemonForm: SimpleTranslationEntries = { "gigantamax": "G-Max {{pokemonName}}", "eternamax": "E-Max {{pokemonName}}", + "megaChange": "{{preName}} Mega Evolved\ninto {{pokemonName}}!", + "gigantamaxChange": "{{preName}} Gigantamaxed\ninto {{pokemonName}}!", + "eternamaxChange": "{{preName}} Eternamaxed\ninto {{pokemonName}}!", + "revertChange": "{{pokemonName}} reverted\nto its original form!", + "formChange": "{{preName}} changed form!", +} as const; + +export const pokemonForm: SimpleTranslationEntries = { // Starters forms // 1G "pikachuCosplay": "Coqueta", diff --git a/src/locales/es/starter-select-ui-handler.ts b/src/locales/es/starter-select-ui-handler.ts index 6f7d845ca64..d7c203f49c4 100644 --- a/src/locales/es/starter-select-ui-handler.ts +++ b/src/locales/es/starter-select-ui-handler.ts @@ -7,7 +7,8 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; */ export const starterSelectUiHandler: SimpleTranslationEntries = { "confirmStartTeam": "¿Comenzar con estos Pokémon?", - "invalidParty": "This is not a valid starting party!", + "confirmExit": "Do you want to exit?", + "invalidParty": "¡Este equipo no es válido!", "gen1": "I", "gen2": "II", "gen3": "III", @@ -22,10 +23,11 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "passive": "Pasiva:", "nature": "Natur:", "eggMoves": "Mov. Huevo", - "addToParty": "Añadir a Equipo", + "addToParty": "Añadir al Equipo", + "removeFromParty": "Excluir del Equipo", "toggleIVs": "Mostrar IVs", - "manageMoves": "Gestionar Movs.", - "manageNature": "Gestionar Natur", + "manageMoves": "Cambiar movs.", + "manageNature": "Cambiar natur.", "useCandies": "Usar Caramelos", "selectNature": "Elige Natur.", "selectMoveSwapOut": "Elige el movimiento que sustituir.", diff --git a/src/locales/es/trainers.ts b/src/locales/es/trainers.ts index d5647f83cf6..f881fc04f94 100644 --- a/src/locales/es/trainers.ts +++ b/src/locales/es/trainers.ts @@ -117,7 +117,35 @@ export const trainerClasses: SimpleTranslationEntries = { "worker": "Operario", "worker_female": "Operaria", "workers": "Operarios", - "youngster": "Joven" + "youngster": "Joven", + "rocket_grunt": "Rocket Grunt", + "rocket_grunts": "Rocket Grunts", + "rocket_grunt_female": "Rocket Grunt", + "rocket_admin": "Rocket Admin", + "rocket_admin_female": "Rocket Admin", + "magma_grunt": "Magma Grunt", + "magma_grunt_female": "Magma Grunt", + "magma_grunts": "Magma Grunts", + "magma_admin": "Magma Admin", + "magma_admin_female": "Magma Admin", + "aqua_grunt": "Aqua Grunt", + "aqua_grunt_female": "Aqua Grunt", + "aqua_grunts": "Aqua Grunts", + "aqua_admin": "Aqua Admin", + "aqua_admin_female": "Aqua Admin", + "galactic_grunt": "Galactic Grunt", + "galactic_grunt_female": "Galactic Grunt", + "galactic_grunts": "Galactic Grunts", + "galactic_admin": "Galactic Admin", + "galactic_admin_female": "Galactic Admin", + "plasma_grunt": "Plasma Grunt", + "plasma_grunt_female": "Plasma Grunt", + "plasma_grunts": "Plasma Grunts", + "flare_grunt": "Flare Grunt", + "flare_grunt_female": "Flare Grunt", + "flare_grunts": "Flare Grunts", + "flare_admin": "Flare Admin", + "flare_admin_female": "Flare Admin", } as const; // Names of special trainers like gym leaders, elite four, and the champion diff --git a/src/locales/fr/ability-trigger.ts b/src/locales/fr/ability-trigger.ts index b063a2aca68..f6b9c306cd1 100644 --- a/src/locales/fr/ability-trigger.ts +++ b/src/locales/fr/ability-trigger.ts @@ -59,4 +59,5 @@ export const abilityTriggers: SimpleTranslationEntries = { "postSummonSwordOfRuin": "L’Épée du Fléau de {{pokemonNameWithAffix}}\naffaiblit la {{statName}} des Pokémon alentour !", "postSummonTabletsOfRuin": "Le Bois du Fléau de {{pokemonNameWithAffix}}\naffaiblit l’{{statName}} des Pokémon alentour !", "postSummonBeadsOfRuin": "Les Perles du Fléau de {{pokemonNameWithAffix}}\naffaiblissent la {{statName}} des Pokémon alentour !", + "preventBerryUse": "{{pokemonNameWithAffix}} est tendu\net ne peut plus manger de Baies !", } as const; diff --git a/src/locales/fr/achv.ts b/src/locales/fr/achv.ts index 4ff9bf20f51..d5b80700493 100644 --- a/src/locales/fr/achv.ts +++ b/src/locales/fr/achv.ts @@ -22,7 +22,7 @@ export const PGMachv: AchievementTranslationEntries = { name: "Banquier", }, "10M_MONEY": { - name: "Évadé·e fiscal·e", + name: "Évadé fiscal", }, "DamageAchv": { @@ -45,7 +45,7 @@ export const PGMachv: AchievementTranslationEntries = { description: "Soigner {{healAmount}} {{HP}} en une fois avec une capacité, un talent ou un objet tenu", }, "250_HEAL": { - name: "Infirmier·ère", + name: "Infirmier", }, "1000_HEAL": { name: "Médecin", @@ -74,19 +74,19 @@ export const PGMachv: AchievementTranslationEntries = { description: "Accumuler un total de {{ribbonAmount}} Rubans", }, "10_RIBBONS": { - name: "Maitre·sse de la Ligue", + name: "Maitre de la Ligue", }, "25_RIBBONS": { - name: "Super Maitre·sse de la Ligue", + name: "Super Maitre de la Ligue", }, "50_RIBBONS": { - name: "Hyper Maitre·sse de la Ligue", + name: "Hyper Maitre de la Ligue", }, "75_RIBBONS": { - name: "Rogue Maitre·sse de la Ligue", + name: "Rogue Maitre de la Ligue", }, "100_RIBBONS": { - name: "Master Maitre·sse de la Ligue", + name: "Master Maitre de la Ligue", }, "TRANSFER_MAX_BATTLE_STAT": { @@ -166,7 +166,7 @@ export const PGMachv: AchievementTranslationEntries = { description: "Avoir des IV parfaits sur un Pokémon", }, "CLASSIC_VICTORY": { - name: "Invaincu·e", + name: "Invaincu", description: "Terminer le jeu en mode classique", }, @@ -264,7 +264,278 @@ export const PGMachv: AchievementTranslationEntries = { "MONO_FAIRY": { name: "Hey ! Listen !", }, + "FRESH_START": { + name: "Du premier coup !", + description: "Terminer un challenge « Nouveau départ »." + } } as const; // Achievement translations for the when the player character is female (it for now uses the same translations as the male version) -export const PGFachv: AchievementTranslationEntries = PGMachv; +export const PGFachv: AchievementTranslationEntries = { + "Achievements": { + name: "Succès", + }, + "Locked": { + name: "Verrouillé", + }, + + "MoneyAchv": { + description: "Récolter un total de {{moneyAmount}} ₽", + }, + "10K_MONEY": { + name: "Épargnante", + }, + "100K_MONEY": { + name: "Je possède des thunes", + }, + "1M_MONEY": { + name: "Banquière", + }, + "10M_MONEY": { + name: "Évadée fiscale", + }, + + "DamageAchv": { + description: "Infliger {{damageAmount}} de dégâts en un coup", + }, + "250_DMG": { + name: "Caïd", + }, + "1000_DMG": { + name: "Boxeuse", + }, + "2500_DMG": { + name: "Distributrice de pains", + }, + "10000_DMG": { + name: "One Punch Woman", + }, + + "HealAchv": { + description: "Soigner {{healAmount}} {{HP}} en une fois avec une capacité, un talent ou un objet tenu", + }, + "250_HEAL": { + name: "Infirmière", + }, + "1000_HEAL": { + name: "Médecin", + }, + "2500_HEAL": { + name: "Clerc", + }, + "10000_HEAL": { + name: "Centre Pokémon", + }, + + "LevelAchv": { + description: "Monter un Pokémon au N.{{level}}", + }, + "LV_100": { + name: "Et c’est pas fini !", + }, + "LV_250": { + name: "Élite", + }, + "LV_1000": { + name: "Vers l’infini et au-delà", + }, + + "RibbonAchv": { + description: "Accumuler un total de {{ribbonAmount}} Rubans", + }, + "10_RIBBONS": { + name: "Maitresse de la Ligue", + }, + "25_RIBBONS": { + name: "Super Maitresse de la Ligue", + }, + "50_RIBBONS": { + name: "Hyper Maitresse de la Ligue", + }, + "75_RIBBONS": { + name: "Rogue Maitresse de la Ligue", + }, + "100_RIBBONS": { + name: "Master Maitresse de la Ligue", + }, + + "TRANSFER_MAX_BATTLE_STAT": { + name: "Travail d’équipe", + description: "Utiliser Relais avec au moins une statistique montée à fond", + }, + "MAX_FRIENDSHIP": { + name: "Copinage", + description: "Atteindre le niveau de bonheur maximal avec un Pokémon", + }, + "MEGA_EVOLVE": { + name: "Mégamorph", + description: "Méga-évoluer un Pokémon", + }, + "GIGANTAMAX": { + name: "Kaijū", + description: "Gigamaxer un Pokémon", + }, + "TERASTALLIZE": { + name: "J’aime les STAB", + description: "Téracristalliser un Pokémon", + }, + "STELLAR_TERASTALLIZE": { + name: "Le type enfoui", + description: "Téracristalliser un Pokémon en type Stellaire", + }, + "SPLICE": { + name: "Infinite Fusion", + description: "Fusionner deux Pokémon avec le Pointeau ADN", + }, + "MINI_BLACK_HOLE": { + name: "Item-stellar", + description: "Obtenir un Mini Trou Noir", + }, + "CATCH_MYTHICAL": { + name: "Fabuleux", + description: "Capturer un Pokémon fabuleux", + }, + "CATCH_SUB_LEGENDARY": { + name: "(Semi-)Légendaire", + description: "Capturer un Pokémon semi-légendaire", + }, + "CATCH_LEGENDARY": { + name: "Légendaire", + description: "Capturer un Pokémon légendaire", + }, + "SEE_SHINY": { + name: "Chromatique", + description: "Trouver un Pokémon sauvage chromatique", + }, + "SHINY_PARTY": { + name: "Shasseuse", + description: "Avoir une équipe exclusivement composée de Pokémon chromatiques", + }, + "HATCH_MYTHICAL": { + name: "Œuf fabuleux", + description: "Obtenir un Pokémon fabuleux dans un Œuf", + }, + "HATCH_SUB_LEGENDARY": { + name: "Œuf semi-légendaire", + description: "Obtenir un Pokémon semi-légendaire dans un Œuf", + }, + "HATCH_LEGENDARY": { + name: "Œuf légendaire", + description: "Obtenir un Pokémon légendaire dans un Œuf", + }, + "HATCH_SHINY": { + name: "Œuf chromatique", + description: "Obtenir un Pokémon chromatique dans un Œuf", + }, + "HIDDEN_ABILITY": { + name: "Potentiel enfoui", + description: "Capturer un Pokémon possédant un talent caché", + }, + "PERFECT_IVS": { + name: "Certificat d’authenticité", + description: "Avoir des IV parfaits sur un Pokémon", + }, + "CLASSIC_VICTORY": { + name: "Invaincue", + description: "Terminer le jeu en mode classique", + }, + + "MONO_GEN_ONE": { + name: "Le rival originel", + description: "Terminer un challenge avec uniquement des Pokémon de 1re génération.", + }, + "MONO_GEN_TWO": { + name: "Entre tradition et modernité", + description: "Terminer un challenge avec uniquement des Pokémon de 2e génération.", + }, + "MONO_GEN_THREE": { + name: "Too much water ?", + description: "Terminer un challenge avec uniquement des Pokémon de 3e génération.", + }, + "MONO_GEN_FOUR": { + name: "Réellement la plus difficile ?", + description: "Terminer un challenge avec uniquement des Pokémon de 4e génération.", + }, + "MONO_GEN_FIVE": { + name: "Recast complet", + description: "Terminer un challenge avec uniquement des Pokémon de 5e génération.", + }, + "MONO_GEN_SIX": { + name: "Aristocrate", + description: "Terminer un challenge avec uniquement des Pokémon de 6e génération.", + }, + "MONO_GEN_SEVEN": { + name: "Seulement techniquement", + description: "Terminer un challenge avec uniquement des Pokémon de 7e génération.", + }, + "MONO_GEN_EIGHT": { + name: "L’heure de gloire", + description: "Terminer un challenge avec uniquement des Pokémon de 8e génération.", + }, + "MONO_GEN_NINE": { + name: "Ça va, c’était EZ", + description: "Terminer un challenge avec uniquement des Pokémon de 9e génération.", + }, + + "MonoType": { + description: "Terminer un challenge en monotype {{type}}.", + }, + "MONO_NORMAL": { + name: "Extraordinairement banal", + }, + "MONO_FIGHTING": { + name: "Je connais le kung-fu", + }, + "MONO_FLYING": { + name: "Angry Birds", + }, + "MONO_POISON": { + name: "Touche moi je t’empoisonne !", + }, + "MONO_GROUND": { + name: "Prévisions : Séisme", + }, + "MONO_ROCK": { + name: "Comme un roc", + }, + "MONO_BUG": { + name: "Une chenille !", + }, + "MONO_GHOST": { + name: "SOS Fantômes", + }, + "MONO_STEEL": { + name: "De type Acier !", + }, + "MONO_FIRE": { + name: "Allumer le feu", + }, + "MONO_WATER": { + name: "Vacances en Bretagne", + }, + "MONO_GRASS": { + name: "Ne pas toucher !", + }, + "MONO_ELECTRIC": { + name: "À la masse", + }, + "MONO_PSYCHIC": { + name: "Grocervo", + }, + "MONO_ICE": { + name: "Froid comme la glace", + }, + "MONO_DRAGON": { + name: "Légendes du club, ou presque", + }, + "MONO_DARK": { + name: "Ça va lui passer", + }, + "MONO_FAIRY": { + name: "Hey ! Listen !", + }, + "FRESH_START": { + name: "Du premier coup !", + description: "Terminer un challenge « Nouveau départ »." + } +} as const; diff --git a/src/locales/fr/arena-tag.ts b/src/locales/fr/arena-tag.ts new file mode 100644 index 00000000000..cc97cb4e34f --- /dev/null +++ b/src/locales/fr/arena-tag.ts @@ -0,0 +1,50 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const arenaTag: SimpleTranslationEntries = { + "yourTeam": "votre équipe", + "opposingTeam": "l’équipe adverse", + "arenaOnRemove": "L’effet de la capacité {{moveName}}\ns’est dissipé !", + "arenaOnRemovePlayer": "L’effet de la capacité {{moveName}}\ns’est dissipé sur votre équipe !", + "arenaOnRemoveEnemy": "L’effet de la capacité {{moveName}}\ns’est dissipé sur l’équipe ennemie !", + "mistOnAdd": "La brume enveloppe l’équipe\de {{pokemonNameWithAffix}} !", + "mistApply": "La brume empêche les stats de baisser !", + "reflectOnAdd": "Protection augmente la résistance\naux capacités physiques !", + "reflectOnAddPlayer": "Protection augmente la résistance\nde l’équipe aux capacités physiques !", + "reflectOnAddEnemy": "Protection augmente la résistance\nde l’équipe ennemie aux capacités physiques !", + "lightScreenOnAdd": "Mur Lumière augmente la résistance\naux capacités spéciales !", + "lightScreenOnAddPlayer": "Mur Lumière augmente la résistance\nde l’équipe aux capacités spéciales !", + "lightScreenOnAddEnemy": "Mur Lumière augmente la résistance\nde l’équipe ennemie aux capacités spéciales !", + "auroraVeilOnAdd": "Voile Aurore augmente la résistance\naux capacités physiques et spéciales !", + "auroraVeilOnAddPlayer": "Voile Aurore augmente la résistance\nde l’équipe aux capacités physiques et spéciales !", + "auroraVeilOnAddEnemy": "Voile Aurore augmente la résistance\nde l’équipe ennemie aux capacités physiques et spéciales !", + "conditionalProtectOnAdd": "La capacité {{moveName}}\nprotège l’équipe !", + "conditionalProtectOnAddPlayer": "La capacité {{moveName}}\nprotège votre équipe !", + "conditionalProtectOnAddEnemy": "La capacité {{moveName}}\nprotège l’équipe ennemie !", + "conditionalProtectApply": "{{pokemonNameWithAffix}} est protégé\npar {{moveName}} !", + "matBlockOnAdd": "{{pokemonNameWithAffix}} se prépare\nà utiliser un tatami pour bloquer les attaques !", + "wishTagOnAdd": "Le vœu de{{pokemonNameWithAffix}}\nse réalise !", + "mudSportOnAdd": "La puissance des capacités\nde type Électrik diminue !", + "mudSportOnRemove": "L’effet de Lance-Boue se dissipe !", + "waterSportOnAdd": "La puissance des capacités\nde type Feu diminue !", + "waterSportOnRemove": "L’effet de Tourniquet se dissipe !", + "spikesOnAdd": "Des {{moveName}} s’éparpillent autour de {{opponentDesc}} !", + "spikesActivateTrap": "{{pokemonNameWithAffix}} est blessé\npar les picots !", + "toxicSpikesOnAdd": "Des {{moveName}} s’éparpillent autour de {{opponentDesc}} !", + "toxicSpikesActivateTrapPoison": "{{pokemonNameWithAffix}} absorbe\n{{moveName}} !", + "stealthRockOnAdd": "Des pierres pointues lévitent\nautour de {{opponentDesc}} !", + "stealthRockActivateTrap": "Des pierres pointues\ntranspercent {{pokemonNameWithAffix}} !", + "stickyWebOnAdd": "Le terrain est couvert d’une {{moveName}}\ndu côté de l’équipe ennemie !", + "stickyWebActivateTrap": "{{pokemonName}} ennemi\nest pris dans la toile gluante !", + "trickRoomOnAdd": "{{pokemonNameWithAffix}}\nfausse les dimensions !", + "trickRoomOnRemove": "Les dimensions faussées\nreviennent à la normale !", + "gravityOnAdd": "La gravité s’intensifie !", + "gravityOnRemove": "La gravité est revenue à la normale !", + "tailwindOnAdd": "Un vent arrière souffle !", + "tailwindOnAddPlayer": "Un vent arrière souffle\nsur votre équipe !", + "tailwindOnAddEnemy": "Un vent arrière souffle\nsur l’équipe ennemie !", + "tailwindOnRemove": "Le vent arrière s’arrête !", + "tailwindOnRemovePlayer": "Le vent arrière soufflant\nsur votre équipe s’arrête !", + "tailwindOnRemoveEnemy": "Le vent arrière soufflant\nsur l’équipe ennemie s’arrête !", + "happyHourOnAdd": "L’ambiance est euphorique !", + "happyHourOnRemove": "L’ambiance se calme !", +} as const; diff --git a/src/locales/fr/bgm-name.ts b/src/locales/fr/bgm-name.ts index c6453a919cf..e66c8102e46 100644 --- a/src/locales/fr/bgm-name.ts +++ b/src/locales/fr/bgm-name.ts @@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = { "missing_entries" : "{{name}}", "battle_kanto_champion": "N2B2 - Vs. Maitre de Kanto", "battle_johto_champion": "N2B2 - Vs. Maitre de Johto", - "battle_hoenn_champion": "N2B2 - Vs. Maitre de Hoenn", + "battle_hoenn_champion_g5": "N2B2 - Vs. Maitre de Hoenn", + "battle_hoenn_champion_g6": "ROSA - Vs. Maitre de Hoenn", "battle_sinnoh_champion": "N2B2 - Vs. Maitresse de Sinnoh", "battle_champion_alder": "NB - Vs. Maitre d’Unys", "battle_champion_iris": "N2B2 - Vs. Maitresse d’Unys", @@ -74,16 +75,16 @@ export const bgmName: SimpleTranslationEntries = { "battle_wild": "NB - Vs. Pokémon sauvage", "battle_wild_strong": "NB - Vs. Pokémon puissant sauvage", "end_summit": "PDM ÉSDX - Tour Céleste", - "battle_rocket_grunt": "HGSS Team Rocket Battle", - "battle_aqua_magma_grunt": "ORAS Team Aqua & Magma Battle", - "battle_galactic_grunt": "BDSP Team Galactic Battle", + "battle_rocket_grunt": "HGSS Vs. Team Rocket", + "battle_aqua_magma_grunt": "ROSA Vs. Team Aqua/Magma", + "battle_galactic_grunt": "DÉPS Vs. Team Galaxie", "battle_plasma_grunt": "NB - Vs. Team Plasma", - "battle_flare_grunt": "XY Team Flare Battle", - "battle_rocket_boss": "USUM Giovanni Battle", - "battle_aqua_magma_boss": "ORAS Archie & Maxie Battle", - "battle_galactic_boss": "BDSP Cyrus Battle", - "battle_plasma_boss": "B2W2 Ghetsis Battle", - "battle_flare_boss": "XY Lysandre Battle", + "battle_flare_grunt": "XY - Vs. Team Flare", + "battle_rocket_boss": "USUL - Vs. Giovanni", + "battle_aqua_magma_boss": "ROSA - Vs. Max/Arthur", + "battle_galactic_boss": "DÉPS - Vs. Hélio", + "battle_plasma_boss": "N2B2 - Vs. Ghetis", + "battle_flare_boss": "XY - Vs. Lysandre", // Biome Music "abyss": "PDM EdS - Cratère Obscur", diff --git a/src/locales/fr/challenges.ts b/src/locales/fr/challenges.ts index d88960dbe3b..694cc242e73 100644 --- a/src/locales/fr/challenges.ts +++ b/src/locales/fr/challenges.ts @@ -2,7 +2,7 @@ import { TranslationEntries } from "#app/interfaces/locales"; export const challenges: TranslationEntries = { "title": "Paramètres du Challenge", - "illegalEvolution": "{{pokemon}} s’est transformé en Pokémon\ninéligible pour ce challenge !", + "illegalEvolution": "{{pokemon}} est devenu\ninéligible pour ce challenge !", "singleGeneration": { "name": "Mono-génération", "desc": "Vous ne pouvez choisir que des Pokémon de {{gen}} génération.", @@ -23,4 +23,10 @@ export const challenges: TranslationEntries = { "desc_default": "Vous ne pouvez choisir que des Pokémon du type sélectionné." //type in pokemon-info }, + "freshStart": { + "name": "Nouveau départ", + "desc": "Vous ne pouvez choisir que les starters de base du jeu, comme si vous le recommenciez.", + "value.0": "Non", + "value.1": "Oui", + } } as const; diff --git a/src/locales/fr/config.ts b/src/locales/fr/config.ts index 787c210c1b0..246ae9a073f 100644 --- a/src/locales/fr/config.ts +++ b/src/locales/fr/config.ts @@ -1,6 +1,7 @@ import { ability } from "./ability"; import { abilityTriggers } from "./ability-trigger"; import { arenaFlyout } from "./arena-flyout"; +import { arenaTag } from "./arena-tag"; import { PGFachv, PGMachv } from "./achv"; import { battle } from "./battle"; import { battleInfo } from "./battle-info"; @@ -23,6 +24,7 @@ import { } from "./dialogue"; import { egg } from "./egg"; import { fightUiHandler } from "./fight-ui-handler"; +import { filterBar } from "./filter-bar"; import { gameMode } from "./game-mode"; import { gameStatsUiHandler } from "./game-stats-ui-handler"; import { growth } from "./growth"; @@ -34,7 +36,7 @@ import { move } from "./move"; import { nature } from "./nature"; import { pokeball } from "./pokeball"; import { pokemon } from "./pokemon"; -import { pokemonForm } from "./pokemon-form"; +import { pokemonForm, battlePokemonForm } from "./pokemon-form"; import { pokemonInfo } from "./pokemon-info"; import { pokemonInfoContainer } from "./pokemon-info-container"; import { pokemonSummary } from "./pokemon-summary"; @@ -50,14 +52,17 @@ import { partyUiHandler } from "./party-ui-handler"; import { settings } from "./settings.js"; import { common } from "./common.js"; import { modifierSelectUiHandler } from "./modifier-select-ui-handler"; +import { moveTriggers } from "./move-trigger"; export const frConfig = { ability: ability, abilityTriggers: abilityTriggers, arenaFlyout: arenaFlyout, + arenaTag: arenaTag, battle: battle, battleInfo: battleInfo, battleMessageUiHandler: battleMessageUiHandler, + battlePokemonForm: battlePokemonForm, battlerTags: battlerTags, berry: berry, bgmName: bgmName, @@ -77,6 +82,7 @@ export const frConfig = { PGFdoubleBattleDialogue: PGFdoubleBattleDialogue, egg: egg, fightUiHandler: fightUiHandler, + filterBar: filterBar, gameMode: gameMode, gameStatsUiHandler: gameStatsUiHandler, growth: growth, @@ -105,5 +111,6 @@ export const frConfig = { voucher: voucher, weather: weather, partyUiHandler: partyUiHandler, - modifierSelectUiHandler: modifierSelectUiHandler + modifierSelectUiHandler: modifierSelectUiHandler, + moveTriggers: moveTriggers }; diff --git a/src/locales/fr/dialogue.ts b/src/locales/fr/dialogue.ts index d3ec5f85d5d..ac68aa6413b 100644 --- a/src/locales/fr/dialogue.ts +++ b/src/locales/fr/dialogue.ts @@ -2898,6 +2898,18 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Une fois de plus la Team Rocket s’envole vers d’autres cieux !" }, }, + "rocket_admin": { + "encounter": { + 1: "Oh? You managed to get this far? You must be quite the trainer.", + 2: "That's quite enough of you playing hero, kid.", + 3: "I'll show you how scary an angry adult can be!" + }, + "victory": { + 1: "No! Forgive me Giovanni!", + 2: "How could this be?", + 3: "Urgh... You were too strong..." + }, + }, "magma_grunt": { "encounter": { 1: "N’espère pas recevoir de la pitié si tu te mets sur le chemin de la Team Magma !" @@ -2906,6 +2918,18 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Je…?\nJ’ai perdu ?!" }, }, + "magma_admin": { + "encounter": { + 1: "Hehehe! So you've come all the way here! But you're too late!", + 2: "You're going to meddle in Team Magma's affairs? You're so cute you're disgusting! I'll put you down kiddy!", + 3: "I'm going to give you a little taste of pain! Resign yourself to it!" + }, + "victory": { + 1: "Hehehe... So I lost...", + 2: "You're disgustingly strong!", + 3: "Ahahaha! Ouch!" + }, + }, "aqua_grunt": { "encounter": { 1: "Aucune pitié si tu te mets sur le chemin de la Team Aqua, même pour une gamine !" @@ -2914,6 +2938,18 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Comment ça ?" }, }, + "aqua_admin": { + "encounter": { + 1: "I'm a cut above the grunts you've seen so far. I'm going to puvlerize you!", + 2: "Hahn? What's this? Who's this spoiled brat?", + 3: "What are you doing here? Did you follow us?" + }, + "victory": { + 1: "So I lost too...", + 2: "Ahhh?! Did I go too easy on you?!", + 3: "Wh-what was that?" + }, + }, "galactic_grunt": { "encounter": { 1: "Ne te mets pas en travers de la Team Galaxie !" @@ -2922,6 +2958,18 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Désactivation…" }, }, + "galactic_admin": { + "encounter": { + 1: "I'm one of Team Galactic's Commanders.", + 2: "Anything that opposes Team Galactic must be crushed! Even the very thought of opposition will not be tolerated!", + 3: "What's the matter? Don't tell me you're shaking?" + }, + "victory": { + 1: "This can't be?! I lost?! You... you uppity brat!", + 2: "You, my friend, are tough!", + 3: "Losing to some child... Being careless cost me too much." + }, + }, "plasma_grunt": { "encounter": { 1: "Pas de quatiers à ceux qui ne suivent pas notre idéal !" @@ -2930,6 +2978,18 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Plasmaaaaaaaaa !" }, }, + "plasma_sage": { + "encounter": { + 1: "You could become a threat to Team Plasma, so we will eliminate you here!", + 2: "Oh, for crying out loud... I didn't expect to have to fight!", + 3: "You're an impressive Trainer to have made it this far." + }, + "victory": { + 1: "Ghetsis...", + 2: "It's bitter cold. I'm shivering. I'm suffering.", + 3: "Hmph. You're a smarter Trainer than I expected." + }, + }, "flare_grunt": { "encounter": { 1: "Le style et le bon gout, il n’y a que ça qui compte !" @@ -2938,6 +2998,18 @@ export const PGFdialogue: DialogueTranslationEntries = { 1: "Mon futur me semble guère radieux." }, }, + "flare_admin": { + "encounter": { + 1: "Ah ha ha! It would be my pleasure. Come on, little Trainer! Let's see what you've got!", + 2: "Hmm... You're more powerful than you look. I wonder how much energy there is inside you.", + 3: "I've been waiting for you! I need to do a little research on you! Come, let us begin!" + }, + "victory": { + 1: "You're quite strong. Oh yes-very strong, indeed.", + 2: "Ding-ding-ding! Yup, you did it! To the victor goes the spoils!", + 3: "Wonderful! Amazing! You have tremendous skill and bravery!" + }, + }, "rocket_boss_giovanni_1": { "encounter": { 1: "Bien. Je dois admettre que je suis impressionné de te voir ici !" diff --git a/src/locales/fr/filter-bar.ts b/src/locales/fr/filter-bar.ts new file mode 100644 index 00000000000..13656192116 --- /dev/null +++ b/src/locales/fr/filter-bar.ts @@ -0,0 +1,33 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const filterBar: SimpleTranslationEntries = { + "genFilter": "Gen", + "typeFilter": "Type", + "caughtFilter": "Capturés", + "unlocksFilter": "Débloq.", + "miscFilter": "Divers", + "sortFilter": "Tri", + "all": "Tous", + "normal": "Normal", + "uncaught": "Non-capturé", + "passive": "Passif", + "passiveUnlocked": "Passif débloqué", + "passiveLocked": "Passif verrouillé", + "costReduction": "Cost Reduction", + "costReductionUnlocked": "Cost Reduction Unlocked", + "costReductionLocked": "Cost Reduction Locked", + "ribbon": "Ruban", + "hasWon": "Ruban - Oui", + "hasNotWon": "Ruban - Non", + "hiddenAbility": "Hidden Ability", + "hasHiddenAbility": "Hidden Ability - Yes", + "noHiddenAbility": "Hidden Ability - No", + "pokerus": "Pokerus", + "hasPokerus": "Pokerus - Yes", + "noPokerus": "Pokerus - No", + "sortByNumber": "Par N°", + "sortByCost": "Par cout", + "sortByCandies": "Par bonbons", + "sortByIVs": "Par IV", + "sortByName": "Par nom", +}; diff --git a/src/locales/fr/menu-ui-handler.ts b/src/locales/fr/menu-ui-handler.ts index 70cf05fe984..1270ce6d361 100644 --- a/src/locales/fr/menu-ui-handler.ts +++ b/src/locales/fr/menu-ui-handler.ts @@ -18,10 +18,10 @@ export const menuUiHandler: SimpleTranslationEntries = { "exportSlotSelect": "Sélectionnez l’emplacement depuis lequel exporter les données.", "importData": "Importer données", "exportData": "Exporter données", - "linkDiscord": "Link Discord", - "unlinkDiscord": "Unlink Discord", - "linkGoogle": "Link Google", - "unlinkGoogle": "Unlink Google", + "linkDiscord": "Lier à Discord", + "unlinkDiscord": "Délier Discord", + "linkGoogle": "Lier à Google", + "unlinkGoogle": "Délier Google", "cancel": "Retour", "losingProgressionWarning": "Vous allez perdre votre progression depuis le début du combat. Continuer ?", "noEggs": "Vous ne faites actuellement\néclore aucun Œuf !" diff --git a/src/locales/fr/modifier.ts b/src/locales/fr/modifier.ts index 3cc72600f91..368b186a07b 100644 --- a/src/locales/fr/modifier.ts +++ b/src/locales/fr/modifier.ts @@ -10,4 +10,5 @@ export const modifier: SimpleTranslationEntries = { "turnHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est absorbé·e\npar le {{typeName}} de {{pokemonName}} !", "contactHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est volé·e\npar l’{{typeName}} de {{pokemonName}} !", "enemyTurnHealApply": "{{pokemonNameWithAffix}}\nrestaure un peu ses PV !", + "bypassSpeedChanceApply": "{{itemName}} de {{pokemonName}}\nlui permet d’agir plus vite que d’habitude !", } as const; diff --git a/src/locales/fr/move-trigger.ts b/src/locales/fr/move-trigger.ts new file mode 100644 index 00000000000..d1fbda50b03 --- /dev/null +++ b/src/locales/fr/move-trigger.ts @@ -0,0 +1,62 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const moveTriggers: SimpleTranslationEntries = { + "hitWithRecoil" : "{{pokemonName}} est blessé par le contrecoup !", + "cutHpPowerUpMove": "{{pokemonName}} sacrifie des PV\net augmente la puissance ses capacités !", + "absorbedElectricity": "{{pokemonName}} absorbe de l’électricité !", + "switchedStatChanges": "{{pokemonName}} permute\nles changements de stats avec ceux de sa cible !", + "goingAllOutForAttack": "{{pokemonName}} a pris\ncette capacité au sérieux !", + "regainedHealth": "{{pokemonName}}\nrécupère des PV !", + "keptGoingAndCrashed": "{{pokemonName}}\ns’écrase au sol !", + "fled": "{{pokemonName}}\nprend la fuite !", + "cannotBeSwitchedOut": "Impossible de rappeler {{pokemonName}}\nau combat.", + "swappedAbilitiesWithTarget": "{{pokemonName}} et sa cible\néchangent leurs talents !", + "coinsScatteredEverywhere": "Il pleut des pièces !", + "attackedByItem": "{{pokemonName}} est attaqué\npar son propre objet {{itemName}} !", + "whippedUpAWhirlwind": "{{pokemonName}}se prépare\nà lancer une bourrasque !", + "flewUpHigh": "{{pokemonName}} s’envole !", + "tookInSunlight": "{{pokemonName}}\nabsorbe la lumière !", + "dugAHole": "{{pokemonName}}\nse cache dans le sol !", + "loweredItsHead": "{{pokemonName}}\nbaisse la tête !", + "isGlowing": "{{pokemonName}} est entouré\nd’une lumière intense !", + "bellChimed": "Un grelot sonne !", + "foresawAnAttack": "{{pokemonName}}\nprévoit une attaque !", + "hidUnderwater": "{{pokemonName}}\nse cache sous l’eau !", + "soothingAromaWaftedThroughArea": "Une odeur apaisante flotte dans l’air !", + "sprangUp": "{{pokemonName}}\nse propulse dans les airs !", + "choseDoomDesireAsDestiny": "{{pokemonName}}souhaite\nle déclenchement de la capacité Vœu Destructeur !", + "vanishedInstantly": "{{pokemonName}}\ndisparait instantanément !", + "tookTargetIntoSky": "{{pokemonName}} emporte\n{{targetName}} haut dans le ciel !", + "becameCloakedInFreezingLight": "{{pokemonName}} est baigné\nd’une lumière blafarde !", + "becameCloakedInFreezingAir": "{{pokemonName}} est entouré\nd’un air glacial !", + "isChargingPower": "{{pokemonName}}\nconcentre son énergie !", + "burnedItselfOut": "Le feu intérieur de {{pokemonName}}\ns’est entièrement consumé !", + "startedHeatingUpBeak": "{{pokemonName}}\nfait chauffer son bec !", + "isOverflowingWithSpacePower": "La puissance du cosmos afflue dans le corps\nde {{pokemonName}} !", + "usedUpAllElectricity": "{{pokemonName}}a utilisé\ntoute son électricité !", + "stoleItem": "{{pokemonName}} vole\nl’objet {{itemName}} de {{targetName}} !", + "incineratedItem": "{{pokemonName}} brule\nla {{itemName}} de {{targetName}} !", + "knockedOffItem": "{{pokemonName}} fait tomber\nl’objet {{itemName}} de {{targetName}} !", + "tookMoveAttack": "{{pokemonName}}\nsubit l’attaque {{moveName}} !", + "cutOwnHpAndMaximizedStat": "{{pokemonName}} sacrifie des PV\net monte son {{statName}} au maximum !", + "copiedStatChanges": "{{pokemonName}} copie\nles changements de stats de {{targetName}} !", + "magnitudeMessage": "Ampleur {{magnitude}} !", + "tookAimAtTarget": "{{pokemonName}} vise\n{{targetName}} !", + "transformedIntoType": "{{pokemonName}} prend\nle type {{typeName}} !", + "copiedMove": "{{pokemonName}} copie\nla capacité {{moveName}} !", + "sketchedMove": "{{pokemonName}} utilise Gribouille\npour copier {{moveName}} !", + "acquiredAbility": "Le talent de {{pokemonName}}\ndevient {{abilityName}} !", + "copiedTargetAbility": "{{pokemonName}} copie le talent\n{{abilityName}} de {{targetName}} !", + "transformedIntoTarget": "{{pokemonName}} prend\nl’apparence de {{targetName}} !", + "tryingToTakeFoeDown": "{{pokemonName}} veut entrainer\nson assaillant dans sa chute !", + "addType": "{{pokemonName}} gagne\nle type {{typeName}}.", + "cannotUseMove": "{{pokemonName}} ne peut pas\nutiliser la capacité {{moveName}} !", + "healHp": "{{pokemonName}}\nrécupère des PV !", + "sacrificialFullRestore": "Le Vœu Soin est exaucé et profite\nà {{pokemonName}} !", + "invertStats": "Les changements de stats\nde {{pokemonName}} sont inversés !", + "resetStats": "Les changements de stats\nde {{pokemonName}} ont tous été annulés !", + "faintCountdown": "{{pokemonName}}\nsera K.O. dans {{turnCount}} tours !", + "copyType": "{{pokemonName}} prend le type\nde {{targetPokemonName}} !", + "suppressAbilities": "Le talent de {{pokemonName}}\na été rendu inactif !", + "swapArenaTags": "Les effets affectant chaque côté du terrain\nont été échangés par {{pokemonName}} !", +} as const; diff --git a/src/locales/fr/pokemon-form.ts b/src/locales/fr/pokemon-form.ts index 09714f80f3b..f96931fd0e9 100644 --- a/src/locales/fr/pokemon-form.ts +++ b/src/locales/fr/pokemon-form.ts @@ -1,7 +1,6 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; -export const pokemonForm: SimpleTranslationEntries = { - // Battle forms +export const battlePokemonForm: SimpleTranslationEntries = { "mega": "Méga-{{pokemonName}}", "mega-x": "Méga-{{pokemonName}} X", "mega-y": "Méga-{{pokemonName}} Y", @@ -9,6 +8,14 @@ export const pokemonForm: SimpleTranslationEntries = { "gigantamax": "{{pokemonName}} Gigamax", "eternamax": "{{pokemonName}} Infinimax", + "megaChange": "{{preName}} méga-évolue\nen {{pokemonName}} !", + "gigantamaxChange": "{{preName}} se gigamaxe\nen {{pokemonName}} !", + "eternamaxChange": "{{preName}} devient\n{{pokemonName}} !", + "revertChange": "{{pokemonName}} retourne\nà sa forme initiale !", + "formChange": "{{preName}} change de forme !", +} as const; + +export const pokemonForm: SimpleTranslationEntries = { // Starters forms // 1G "pikachuCosplay": "Cosplayeur", diff --git a/src/locales/fr/starter-select-ui-handler.ts b/src/locales/fr/starter-select-ui-handler.ts index fa45624c0f0..c49c326385f 100644 --- a/src/locales/fr/starter-select-ui-handler.ts +++ b/src/locales/fr/starter-select-ui-handler.ts @@ -7,7 +7,8 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; */ export const starterSelectUiHandler: SimpleTranslationEntries = { "confirmStartTeam": "Commencer avec ces Pokémon ?", - "invalidParty": "This is not a valid starting party!", + "confirmExit": "Do you want to exit?", + "invalidParty": "Cette équipe de départ est invalide !", "gen1": "1G", "gen2": "2G", "gen3": "3G", @@ -23,6 +24,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "nature": "Nature :", "eggMoves": "Capacités Œuf", "addToParty": "Ajouter à l’équipe", + "removeFromParty": "Retirer de l’équipe", "toggleIVs": "Voir les IV", "manageMoves": "Modifier les Capacités", "manageNature": "Modifier la Nature", @@ -33,12 +35,12 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "unlockPassive": "Débloquer Passif", "reduceCost": "Diminuer le cout", "sameSpeciesEgg": "Acheter un Œuf", - "cycleShiny": ": » Chromatiques", - "cycleForm": ": » Formes", - "cycleGender": ": » Sexes", - "cycleAbility": ": » Talents", - "cycleNature": ": » Natures", - "cycleVariant": ": » Variants", + "cycleShiny": ": Chromatique", + "cycleForm": ": Forme", + "cycleGender": ": Sexe", + "cycleAbility": ": Talent", + "cycleNature": ": Nature", + "cycleVariant": ": Variant", "enablePassive": "Activer Passif", "disablePassive": "Désactiver Passif", "locked": "Verrouillé", diff --git a/src/locales/fr/trainers.ts b/src/locales/fr/trainers.ts index fc0639d47b9..84d49eba549 100644 --- a/src/locales/fr/trainers.ts +++ b/src/locales/fr/trainers.ts @@ -127,16 +127,33 @@ export const trainerClasses: SimpleTranslationEntries = { "youngster": "Gamin", "rocket_grunt": "Sbire de la Team Rocket", "rocket_grunt_female": "Sbire de la Team Rocket", + "rocket_grunts": "Sbires de la Team Rocket", + "rocket_admin": "Rocket Admin", + "rocket_admin_female": "Rocket Admin", "magma_grunt": "Sbire de la Team Magma", "magma_grunt_female": "Sbire de la Team Magma", + "magma_grunts": "Sbires de la Team Magma", + "magma_admin": "Magma Admin", + "magma_admin_female": "Magma Admin", "aqua_grunt": "Sbire de la Team Aqua", "aqua_grunt_female": "Sbire de la Team Aqua", + "aqua_grunts": "Sbires de la Team Aqua", + "aqua_admin": "Aqua Admin", + "aqua_admin_female": "Aqua Admin", "galactic_grunt": "Sbire de la Team Galaxie", - "galactic_grunt_female": "Sbire Team Galaxie", + "galactic_grunt_female": "Sbire de la Team Galaxie", + "galactic_grunts": "Sbires de la Team Galaxie", + "galactic_admin": "Galactic Admin", + "galactic_admin_female": "Galactic Admin", "plasma_grunt": "Sbire de la Team Plasma", "plasma_grunt_female": "Sbire de la Team Plasma", + "plasma_grunts": "Sbires de la Team Plasma", + "plasma_sage": "Plasma Sage", "flare_grunt": "Sbire de la Team Flare", "flare_grunt_female": "Sbire de la Team Flare", + "flare_grunts": "Sbires de la Team Flare", + "flare_admin": "Manager de la Team Flare", + "flare_admin_female": "Manageuse de la Team Flare", } as const; // Names of special trainers like gym leaders, elite four, and the champion @@ -265,7 +282,11 @@ export const trainerNames: SimpleTranslationEntries = { "leon": "Tarak", "rival": "Gwenaël", //Male breton name, a celtic language spoken in Brittany (France) and related to the word for "white" (gwenn). Finn meaning is also "white" in irish/goidelic which are also celtic languages. "rival_female": "Papina", //Litteral translation of ivy, also used as Female name in a North-American indigenous language - + "maxie": "Max", + "archie": "Arthur", + "cyrus": "Hélio", + "ghetsis": "Ghetis", + "lysandre": "Lysandre", // Double Names "blue_red_double": "Blue & Red", diff --git a/src/locales/it/ability-trigger.ts b/src/locales/it/ability-trigger.ts index 4e965eacf32..37472dbdeab 100644 --- a/src/locales/it/ability-trigger.ts +++ b/src/locales/it/ability-trigger.ts @@ -59,4 +59,5 @@ export const abilityTriggers: SimpleTranslationEntries = { "postSummonSwordOfRuin": "{{pokemonNameWithAffix}}'s Sword of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}'s Tablets of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}'s Beads of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", + "preventBerryUse": "{{pokemonNameWithAffix}} non riesce a\nmangiare le bacche per l'agitazione!", } as const; diff --git a/src/locales/it/ability.ts b/src/locales/it/ability.ts index 5e01e02a718..3b98f1b389d 100644 --- a/src/locales/it/ability.ts +++ b/src/locales/it/ability.ts @@ -471,7 +471,7 @@ export const ability: AbilityTranslationEntries = { }, honeyGather: { name: "Mielincetta", - description: "The Pokémon gathers Honey after a battle. The Honey is then sold for money.", + description: "Il Pokémon raccoglie del miele dopo ogni battaglia. Esso viene poi venduto.", }, frisk: { name: "Indagine", diff --git a/src/locales/it/achv.ts b/src/locales/it/achv.ts index 0ec9ad3f98a..50baae41790 100644 --- a/src/locales/it/achv.ts +++ b/src/locales/it/achv.ts @@ -10,7 +10,7 @@ export const PGMachv: AchievementTranslationEntries = { }, "MoneyAchv": { - description: "Accumula ₽{{moneyAmount}} PokéDollari", + description: "Accumula {{moneyAmount}} PokéDollari", }, "10K_MONEY": { name: "Benestante", @@ -191,19 +191,19 @@ export const PGMachv: AchievementTranslationEntries = { description: "Completa la modalità sfida di quinta generazione.", }, "MONO_GEN_SIX": { - name: "Quasi Reali", + name: "Vita e Morte", description: "Completa la modalità sfida di sesta generazione.", }, "MONO_GEN_SEVEN": { - name: "Solo In Teoria", + name: "Troppo amichevoli?", description: "Completa la modalità sfida di settima generazione.", }, "MONO_GEN_EIGHT": { - name: "È Champion-time!", + name: "It's champion time!", description: "Completa la modalità sfida di ottava generazione.", }, "MONO_GEN_NINE": { - name: "Non si Stava Impegnando...", + name: "Paradossalmente sbalorditivi", description: "Completa la modalità sfida di nona generazione.", }, diff --git a/src/locales/it/arena-tag.ts b/src/locales/it/arena-tag.ts new file mode 100644 index 00000000000..8bc2302368a --- /dev/null +++ b/src/locales/it/arena-tag.ts @@ -0,0 +1,50 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const arenaTag: SimpleTranslationEntries = { + "yourTeam": "your team", + "opposingTeam": "the opposing team", + "arenaOnRemove": "{{moveName}}'s effect wore off.", + "arenaOnRemovePlayer": "{{moveName}}'s effect wore off\non your side.", + "arenaOnRemoveEnemy": "{{moveName}}'s effect wore off\non the foe's side.", + "mistOnAdd": "{{pokemonNameWithAffix}}'s team became\nshrouded in mist!", + "mistApply": "The mist prevented\nthe lowering of stats!", + "reflectOnAdd": "Reflect reduced the damage of physical moves.", + "reflectOnAddPlayer": "Reflect reduced the damage of physical moves on your side.", + "reflectOnAddEnemy": "Reflect reduced the damage of physical moves on the foe's side.", + "lightScreenOnAdd": "Light Screen reduced the damage of special moves.", + "lightScreenOnAddPlayer": "Light Screen reduced the damage of special moves on your side.", + "lightScreenOnAddEnemy": "Light Screen reduced the damage of special moves on the foe's side.", + "auroraVeilOnAdd": "Aurora Veil reduced the damage of moves.", + "auroraVeilOnAddPlayer": "Aurora Veil reduced the damage of moves on your side.", + "auroraVeilOnAddEnemy": "Aurora Veil reduced the damage of moves on the foe's side.", + "conditionalProtectOnAdd": "{{moveName}} protected team!", + "conditionalProtectOnAddPlayer": "{{moveName}} protected your team!", + "conditionalProtectOnAddEnemy": "{{moveName}} protected the\nopposing team!", + "conditionalProtectApply": "{{moveName}} protected {{pokemonNameWithAffix}}!", + "matBlockOnAdd": "{{pokemonNameWithAffix}} intends to flip up a mat\nand block incoming attacks!", + "wishTagOnAdd": "{{pokemonNameWithAffix}}'s wish\ncame true!", + "mudSportOnAdd": "Electricity's power was weakened!", + "mudSportOnRemove": "The effects of Mud Sport\nhave faded.", + "waterSportOnAdd": "Fire's power was weakened!", + "waterSportOnRemove": "The effects of Water Sport\nhave faded.", + "spikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!", + "spikesActivateTrap": "{{pokemonNameWithAffix}} is hurt\nby the spikes!", + "toxicSpikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!", + "toxicSpikesActivateTrapPoison": "{{pokemonNameWithAffix}} absorbed the {{moveName}}!", + "stealthRockOnAdd": "Pointed stones float in the air\naround {{opponentDesc}}!", + "stealthRockActivateTrap": "Pointed stones dug into\n{{pokemonNameWithAffix}}!", + "stickyWebOnAdd": "A {{moveName}} has been laid out on the ground around the opposing team!", + "stickyWebActivateTrap": "The opposing {{pokemonName}} was caught in a sticky web!", + "trickRoomOnAdd": "{{pokemonNameWithAffix}} twisted\nthe dimensions!", + "trickRoomOnRemove": "The twisted dimensions\nreturned to normal!", + "gravityOnAdd": "Gravity intensified!", + "gravityOnRemove": "Gravity returned to normal!", + "tailwindOnAdd": "The Tailwind blew from behind team!", + "tailwindOnAddPlayer": "The Tailwind blew from behind\nyour team!", + "tailwindOnAddEnemy": "The Tailwind blew from behind\nthe opposing team!", + "tailwindOnRemove": "Team's Tailwind petered out!", + "tailwindOnRemovePlayer": "Your team's Tailwind petered out!", + "tailwindOnRemoveEnemy": "The opposing team's Tailwind petered out!", + "happyHourOnAdd": "Everyone is caught up in the happy atmosphere!", + "happyHourOnRemove": "The atmosphere returned to normal.", +} as const; diff --git a/src/locales/it/battle-info.ts b/src/locales/it/battle-info.ts index 195ad0616e0..00f72e60f6c 100644 --- a/src/locales/it/battle-info.ts +++ b/src/locales/it/battle-info.ts @@ -1,5 +1,5 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; export const battleInfo: SimpleTranslationEntries = { - "generation": "Generazione {{generation}}", + "generation": "{{generation}} generazione", } as const; diff --git a/src/locales/it/battle.ts b/src/locales/it/battle.ts index d728e624ae3..954f52e4a7f 100644 --- a/src/locales/it/battle.ts +++ b/src/locales/it/battle.ts @@ -14,9 +14,9 @@ export const battle: SimpleTranslationEntries = { "switchQuestion": "Vuoi cambiare\n{{pokemonName}}?", "trainerDefeated": "Hai sconfitto\n{{trainerName}}!", "moneyWon": "Hai vinto {{moneyAmount}}₽", - "moneyPickedUp": "You picked up ₽{{moneyAmount}}!", + "moneyPickedUp": "Hai raccolto ₽{{moneyAmount}}!", "pokemonCaught": "Preso! {{pokemonName}} è stato catturato!", - "addedAsAStarter": "{{pokemonName}} has been\nadded as a starter!", + "addedAsAStarter": "{{pokemonName}} è stato\naggiunto agli starter!", "partyFull": "La tua squadra è al completo.\nVuoi liberare un Pokémon per far spazio a {{pokemonName}}?", "pokemon": "Pokémon", "sendOutPokemon": "Vai! {{pokemonName}}!", @@ -28,7 +28,7 @@ export const battle: SimpleTranslationEntries = { "attackFailed": "Ma ha fallito!", "attackMissed": "{{pokemonNameWithAffix}}\nevita l’attacco!", "attackHitsCount": "Colpito {{count}} volta/e!", - "rewardGain": "You received\n{{modifierName}}!", + "rewardGain": "Ricevi\n{{modifierName}}!", "expGain": "{{pokemonName}} ha guadagnato\n{{exp}} Punti Esperienza!", "levelUp": "{{pokemonName}} è salito al\nlivello {{level}}!", "learnMove": "{{pokemonName}} impara\n{{moveName}}!", @@ -71,8 +71,8 @@ export const battle: SimpleTranslationEntries = { "drainMessage": "Viene prelevata energia\n da{{pokemonName}}!", "regainHealth": "{{pokemonName}} ha rigenerato\npunti salute!", "fainted": "{{pokemonNameWithAffix}} non è più in\ngrado di combattere!", - "statsAnd": "and", - "stats": "Stats", + "statsAnd": "e", + "stats": "statistiche", "statRose_one": "{{pokemonNameWithAffix}}'s {{stats}} è aumentato/a!", "statRose_other": "{{pokemonNameWithAffix}}'s {{stats}} rose!", "statSharplyRose_one": "{{pokemonNameWithAffix}}'s {{stats}} è aumentato/a molto!", @@ -89,7 +89,7 @@ export const battle: SimpleTranslationEntries = { "statSeverelyFell_other": "{{pokemonNameWithAffix}}'s {{stats}} severely fell!", "statWontGoAnyLower_one": "{{pokemonNameWithAffix}}'s {{stats}} non può diminuire più di così!", "statWontGoAnyLower_other": "{{pokemonNameWithAffix}}'s {{stats}} won't go any lower!", - "transformedIntoType": "{{pokemonName}} transformed\ninto the {{type}} type!", + "transformedIntoType": "{{pokemonName}} diventa\ndi tipo {{type}} type!", "retryBattle": "Vuoi riprovare dall'inizio della lotta?", "unlockedSomething": "{{unlockedThing}}\nè stato/a sbloccato/a.", "congratulations": "Congratulazioni!", @@ -141,19 +141,19 @@ export const battle: SimpleTranslationEntries = { "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}} resiste\nal colpo!", "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}} ha resistito\ngrazie a Vigore!", "battlerTagsPerishSongLapse": "Il conto alla rovescia di Ultimocanto per {{pokemonNameWithAffix}} scende a {{turnCount}}.", - "battlerTagsCenterOfAttentionOnAdd": "{{pokemonNameWithAffix}} became the center\nof attention!", + "battlerTagsCenterOfAttentionOnAdd": "{{pokemonNameWithAffix}} è al centro\ndell’attenzione!", "battlerTagsTruantLapse": "{{pokemonNameWithAffix}} sta\nciondolando!", "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}} non\ningrana!", "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}} ritrova\nlo slancio!", "battlerTagsHighestStatBoostOnAdd": "{{statName}} di {{pokemonNameWithAffix}}\nviene aumentato/a!", "battlerTagsHighestStatBoostOnRemove": "Gli effetti di {{abilityName}}\ndi {{pokemonNameWithAffix}} sono cessati!", - "battlerTagsMagnetRisenOnAdd": "{{pokemonNameWithAffix}} levitated with electromagnetism!", - "battlerTagsMagnetRisenOnRemove": "{{pokemonNameWithAffix}}'s electromagnetism wore off!", + "battlerTagsMagnetRisenOnAdd": "{{pokemonNameWithAffix}} si solleva in aria\na causa dell’elettromagnetismo!", + "battlerTagsMagnetRisenOnRemove": "L’effetto dell’elettromagnetismo di {{pokemonNameWithAffix}}\nè terminato!", "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}} si prepara\nalla lotta!", "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}} si è rilassato.", "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}} è stato messo sotto sale!", "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} viene colpito da {{moveName}}!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} ha sacrificato metà dei suoi PS per\nlanciare una maledizione su {{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} subisce la maledizione!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} ha usato Accumulo per la\n{{stockpiledCount}}ª volta!" } as const; diff --git a/src/locales/it/bgm-name.ts b/src/locales/it/bgm-name.ts index 01fb86b281d..be9a8f621c7 100644 --- a/src/locales/it/bgm-name.ts +++ b/src/locales/it/bgm-name.ts @@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = { "missing_entries" : "{{name}}", "battle_kanto_champion": "B2W2 Kanto Champion Battle", "battle_johto_champion": "B2W2 Johto Champion Battle", - "battle_hoenn_champion": "B2W2 Hoenn Champion Battle", + "battle_hoenn_champion_g5": "B2W2 Hoenn Champion Battle", + "battle_hoenn_champion_g6": "ORAS Hoenn Champion Battle", "battle_sinnoh_champion": "B2W2 Sinnoh Champion Battle", "battle_champion_alder": "BW Unova Champion Battle", "battle_champion_iris": "B2W2 Unova Champion Battle", diff --git a/src/locales/it/config.ts b/src/locales/it/config.ts index c22ab87949e..ceb52665796 100644 --- a/src/locales/it/config.ts +++ b/src/locales/it/config.ts @@ -1,6 +1,7 @@ import { ability } from "./ability"; import { abilityTriggers } from "./ability-trigger"; import { arenaFlyout } from "./arena-flyout"; +import { arenaTag } from "./arena-tag"; import { PGFachv, PGMachv } from "./achv"; import { battle } from "./battle"; import { battleInfo } from "./battle-info"; @@ -23,6 +24,7 @@ import { } from "./dialogue"; import { egg } from "./egg"; import { fightUiHandler } from "./fight-ui-handler"; +import { filterBar } from "./filter-bar"; import { gameMode } from "./game-mode"; import { gameStatsUiHandler } from "./game-stats-ui-handler"; import { growth } from "./growth"; @@ -34,7 +36,7 @@ import { move } from "./move"; import { nature } from "./nature"; import { pokeball } from "./pokeball"; import { pokemon } from "./pokemon"; -import { pokemonForm } from "./pokemon-form"; +import { pokemonForm, battlePokemonForm } from "./pokemon-form"; import { pokemonInfo } from "./pokemon-info"; import { pokemonInfoContainer } from "./pokemon-info-container"; import { pokemonSummary } from "./pokemon-summary"; @@ -50,14 +52,17 @@ import { partyUiHandler } from "./party-ui-handler"; import { settings } from "./settings.js"; import { common } from "./common.js"; import { modifierSelectUiHandler } from "./modifier-select-ui-handler"; +import { moveTriggers } from "./move-trigger"; export const itConfig = { ability: ability, abilityTriggers: abilityTriggers, arenaFlyout: arenaFlyout, + arenaTag: arenaTag, battle: battle, battleInfo: battleInfo, battleMessageUiHandler: battleMessageUiHandler, + battlePokemonForm: battlePokemonForm, battlerTags: battlerTags, berry: berry, bgmName: bgmName, @@ -77,6 +82,7 @@ export const itConfig = { PGFdoubleBattleDialogue: PGFdoubleBattleDialogue, egg: egg, fightUiHandler: fightUiHandler, + filterBar: filterBar, gameMode: gameMode, gameStatsUiHandler: gameStatsUiHandler, growth: growth, @@ -105,5 +111,6 @@ export const itConfig = { voucher: voucher, weather: weather, partyUiHandler: partyUiHandler, - modifierSelectUiHandler: modifierSelectUiHandler + modifierSelectUiHandler: modifierSelectUiHandler, + moveTriggers: moveTriggers }; diff --git a/src/locales/it/dialogue.ts b/src/locales/it/dialogue.ts index 702b550c45a..3861d530c01 100644 --- a/src/locales/it/dialogue.ts +++ b/src/locales/it/dialogue.ts @@ -391,6 +391,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Team Rocket blasting off again!" }, }, + "rocket_admin": { + "encounter": { + 1: "Oh? You managed to get this far? You must be quite the trainer.", + 2: "That's quite enough of you playing hero, kid.", + 3: "I'll show you how scary an angry adult can be!" + }, + "victory": { + 1: "No! Forgive me Giovanni!", + 2: "How could this be?", + 3: "Urgh... You were too strong..." + }, + }, "magma_grunt": { "encounter": { 1: " If you get in the way of Team Magma, don’t expect any mercy!" @@ -399,6 +411,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Huh? I lost?!" }, }, + "magma_admin": { + "encounter": { + 1: "Hehehe! So you've come all the way here! But you're too late!", + 2: "You're going to meddle in Team Magma's affairs? You're so cute you're disgusting! I'll put you down kiddy!", + 3: "I'm going to give you a little taste of pain! Resign yourself to it!" + }, + "victory": { + 1: "Hehehe... So I lost...", + 2: "You're disgustingly strong!", + 3: "Ahahaha! Ouch!" + }, + }, "aqua_grunt": { "encounter": { 1: "No one who crosses Team Aqua gets any mercy, not even kids!" @@ -407,6 +431,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "You're kidding me!" }, }, + "aqua_admin": { + "encounter": { + 1: "I'm a cut above the grunts you've seen so far. I'm going to puvlerize you!", + 2: "Hahn? What's this? Who's this spoiled brat?", + 3: "What are you doing here? Did you follow us?" + }, + "victory": { + 1: "So I lost too...", + 2: "Ahhh?! Did I go too easy on you?!", + 3: "Wh-what was that?" + }, + }, "galactic_grunt": { "encounter": { 1: "Don't mess with Team Galactic!" @@ -415,6 +451,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Shut down..." }, }, + "galactic_admin": { + "encounter": { + 1: "I'm one of Team Galactic's Commanders.", + 2: "Anything that opposes Team Galactic must be crushed! Even the very thought of opposition will not be tolerated!", + 3: "What's the matter? Don't tell me you're shaking?" + }, + "victory": { + 1: "This can't be?! I lost?! You... you uppity brat!", + 2: "You, my friend, are tough!", + 3: "Losing to some child... Being careless cost me too much." + }, + }, "plasma_grunt": { "encounter": { 1: "We won't tolerate people who have different ideas!" @@ -423,6 +471,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Plasmaaaaaaaaa!" }, }, + "plasma_sage": { + "encounter": { + 1: "You could become a threat to Team Plasma, so we will eliminate you here!", + 2: "Oh, for crying out loud... I didn't expect to have to fight!", + 3: "You're an impressive Trainer to have made it this far." + }, + "victory": { + 1: "Ghetsis...", + 2: "It's bitter cold. I'm shivering. I'm suffering.", + 3: "Hmph. You're a smarter Trainer than I expected." + }, + }, "flare_grunt": { "encounter": { 1: "Fashion is most important to us!" @@ -431,6 +491,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "The future doesn't look bright for me." }, }, + "flare_admin": { + "encounter": { + 1: "Ah ha ha! It would be my pleasure. Come on, little Trainer! Let's see what you've got!", + 2: "Hmm... You're more powerful than you look. I wonder how much energy there is inside you.", + 3: "I've been waiting for you! I need to do a little research on you! Come, let us begin!" + }, + "victory": { + 1: "You're quite strong. Oh yes-very strong, indeed.", + 2: "Ding-ding-ding! Yup, you did it! To the victor goes the spoils!", + 3: "Wonderful! Amazing! You have tremendous skill and bravery!" + }, + }, "rocket_boss_giovanni_1": { "encounter": { 1: "So! I must say, I am impressed you got here!" diff --git a/src/locales/it/filter-bar.ts b/src/locales/it/filter-bar.ts new file mode 100644 index 00000000000..c6fcb2f0623 --- /dev/null +++ b/src/locales/it/filter-bar.ts @@ -0,0 +1,33 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const filterBar: SimpleTranslationEntries = { + "genFilter": "Gen", + "typeFilter": "Tipo", + "caughtFilter": "Caught", + "unlocksFilter": "Altro", + "miscFilter": "Misc", + "sortFilter": "Ordina", + "all": "Tutto", + "normal": "Normale", + "uncaught": "Mancante", + "passive": "Passive", + "passiveUnlocked": "Passiva sbloccata", + "passiveLocked": "Passiva bloccata", + "costReduction": "Cost Reduction", + "costReductionUnlocked": "Cost Reduction Unlocked", + "costReductionLocked": "Cost Reduction Locked", + "ribbon": "Ribbon", + "hasWon": "Ribbon - Yes", + "hasNotWon": "Ribbon - No", + "hiddenAbility": "Hidden Ability", + "hasHiddenAbility": "Hidden Ability - Yes", + "noHiddenAbility": "Hidden Ability - No", + "pokerus": "Pokerus", + "hasPokerus": "Pokerus - Yes", + "noPokerus": "Pokerus - No", + "sortByNumber": "Num. Dex", + "sortByCost": "Costo", + "sortByCandies": "Caramelle", + "sortByIVs": "IVs", + "sortByName": "Nome", +}; diff --git a/src/locales/it/modifier.ts b/src/locales/it/modifier.ts index 85098cdaaec..810524a9e5e 100644 --- a/src/locales/it/modifier.ts +++ b/src/locales/it/modifier.ts @@ -10,4 +10,5 @@ export const modifier: SimpleTranslationEntries = { "turnHeldItemTransferApply": "{{pokemonNameWithAffix}}'s {{itemName}} was absorbed\nby {{pokemonName}}'s {{typeName}}!", "contactHeldItemTransferApply": "{{pokemonNameWithAffix}}'s {{itemName}} was snatched\nby {{pokemonName}}'s {{typeName}}!", "enemyTurnHealApply": "{{pokemonNameWithAffix}}\nrestored some HP!", + "bypassSpeedChanceApply": "{{pokemonName}} agisce più rapidamente del normale grazie al suo {{itemName}}!", } as const; diff --git a/src/locales/it/move-trigger.ts b/src/locales/it/move-trigger.ts new file mode 100644 index 00000000000..60679d844c0 --- /dev/null +++ b/src/locales/it/move-trigger.ts @@ -0,0 +1,62 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const moveTriggers: SimpleTranslationEntries = { + "hitWithRecoil" : "{{pokemonName}} ha subito il contraccolpo!", + "cutHpPowerUpMove": "{{pokemonName}} riduce i suoi PS per potenziare la sua mossa!", + "absorbedElectricity": "{{pokemonName}} assorbe elettricità!", + "switchedStatChanges": "{{pokemonName}} scambia con il bersaglio le modifiche alle statistiche!", + "goingAllOutForAttack": "{{pokemonName}} fa sul serio!", + "regainedHealth": "{{pokemonName}} s'è\nripreso!", + "keptGoingAndCrashed": "{{pokemonName}} si sbilancia e\nsi schianta!", + "fled": "{{pokemonName}} è fuggito!", + "cannotBeSwitchedOut": "{{pokemonName}} non può essere sostituito!", + "swappedAbilitiesWithTarget": "{{pokemonName}} scambia la sua\nabilità con il bersaglio!", + "coinsScatteredEverywhere": "Ci sono monete sparse ovunque!", + "attackedByItem": "{{itemName}} attacca {{pokemonName}}!", + "whippedUpAWhirlwind": "{{pokemonName}} genera un\nuragano!", + "flewUpHigh": "{{pokemonName}} vola\nin alto!", + "tookInSunlight": "{{pokemonName}} assorbe la luce!", + "dugAHole": "{{pokemonName}} si nasconde sottoterra!", + "loweredItsHead": "{{pokemonName}} abbassa la testa!", + "isGlowing": "{{pokemonName}} è avvolto da una luce intensa!", + "bellChimed": " Si sente suonare una campanella!", + "foresawAnAttack": "{{pokemonName}} presagisce\nl’attacco imminente!", + "hidUnderwater": "{{pokemonName}} sparisce\nsott’acqua!", + "soothingAromaWaftedThroughArea": "Un gradevole profumo si diffonde nell’aria!", + "sprangUp": "{{pokemonName}} spicca un gran balzo!", + "choseDoomDesireAsDestiny": "{{pokemonName}} ipoteca\nil futuro con Desiderio Fatale!", + "vanishedInstantly": "{{pokemonName}} sparisce\nimprovvisamente!", + "tookTargetIntoSky": "{{pokemonName}} trascina\nin aria {{targetName}}!", + "becameCloakedInFreezingLight": "{{pokemonName}} è avvolto da\nuna luce fredda!", + "becameCloakedInFreezingAir": "{{pokemonName}} è avvolto da\nun’atmosfera gelida!", + "isChargingPower": "{{pokemonName}} accumula energia!", + "burnedItselfOut": "Le fiamme di {{pokemonName}} si sono spente!", + "startedHeatingUpBeak": "{{pokemonName}} inizia a\nscaldare il becco!", + "isOverflowingWithSpacePower": "La forza dell’universo pervade {{pokemonName}}!", + "usedUpAllElectricity": "{{pokemonName}} ha usato tutta la sua elettricità!", + "stoleItem": "{{pokemonName}} ruba\nil/lo/la {{itemName}} di {{targetName}}!", + "incineratedItem": "{{pokemonName}} incenerisce\nil/lo/la {{itemName}} di {{targetName}}!", + "knockedOffItem": "{{pokemonName}} fa cadere\nil/lo/la {{itemName}} di {{targetName}}!", + "tookMoveAttack": "{{pokemonName}} attira\nl'attacco {{moveName}} su di sé!", + "cutOwnHpAndMaximizedStat": "{{pokemonName}} riduce i suoi PS\ne aumenta al massimo il/la suo/a {{statName}}!", + "copiedStatChanges": "{{pokemonName}} copia\nle modifiche alle statistiche di {{targetName}}!", + "magnitudeMessage": "Magnitudo {{magnitude}}!", + "tookAimAtTarget": "{{pokemonName}} prende la mira\nsu {{targetName}}!", + "transformedIntoType": "{{pokemonName}} è diventato\ndi tipo {{typeName}}!", + "copiedMove": "{{pokemonName}} copia\n{{moveName}}!", + "sketchedMove": "{{pokemonName}} disegna uno schizzo\ndella mossa {{moveName}}!", + "acquiredAbility": "L’abilità di {{pokemonName}}\nè ora {{abilityName}}!", + "copiedTargetAbility": "{{pokemonName}} copia l’abilità {{abilityName}}\ndi {{targetName}}!", + "transformedIntoTarget": "{{pokemonName}} assume le sembianze\ndi {{targetName}}!", + "tryingToTakeFoeDown": "{{pokemonName}} tenta di far subire a chi lo manda KO la sua stessa sorte!", + "addType": "Adesso {{pokemonName}} è anche\ndi tipo {{typeName}}!", + "cannotUseMove": "{{pokemonName}} non può usare {{moveName}}!", + "healHp": "{{pokemonName}} ha recuperato dei PS.", + "sacrificialFullRestore": "{{pokemonName}} riceve i benefici\neffetti di Curardore!", + "invertStats": "Le modifiche alle statistiche di {{pokemonName}}\nvengono invertite!", + "resetStats": "Tutte le modifiche alle statistiche sono state annullate!", + "faintCountdown": "{{pokemonName}}\nandrà KO dopo {{turnCount}} turni.", + "copyType": "{{pokemonName}} assume il tipo\ndi {{targetPokemonName}}!", + "suppressAbilities": "L’abilità di {{pokemonName}}\nperde ogni efficacia!", + "swapArenaTags": "{{pokemonName}} ha invertito gli effetti attivi\nnelle due metà del campo!", +} as const; diff --git a/src/locales/it/pokemon-form.ts b/src/locales/it/pokemon-form.ts index 1831e1f600e..eb5d132bacd 100644 --- a/src/locales/it/pokemon-form.ts +++ b/src/locales/it/pokemon-form.ts @@ -1,7 +1,6 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; -export const pokemonForm: SimpleTranslationEntries = { - // Battle forms +export const battlePokemonForm: SimpleTranslationEntries = { "mega": "Mega {{pokemonName}}", "mega-x": "Mega {{pokemonName}} X", "mega-y": "Mega {{pokemonName}} Y", @@ -9,6 +8,14 @@ export const pokemonForm: SimpleTranslationEntries = { "gigantamax": "GigaMax {{pokemonName}}", "eternamax": "EternaMax {{pokemonName}}", + "megaChange": "{{preName}} si evolve\nin {{pokemonName}}!", + "gigantamaxChange": "{{preName}} si Gigamaxxizza\nin {{pokemonName}}!", + "eternamaxChange": "{{preName}} si Dynamaxxa infinitamente\nin {{pokemonName}}!", + "revertChange": "{{pokemonName}} è tornato\nalla sua forma originaria!", + "formChange": "{{preName}} ha cambiato forma!", +} as const; + +export const pokemonForm: SimpleTranslationEntries = { // Starters forms // 1G "pikachuCosplay": "Cosplay", diff --git a/src/locales/it/starter-select-ui-handler.ts b/src/locales/it/starter-select-ui-handler.ts index 8b42a0db8de..6f43b9415e0 100644 --- a/src/locales/it/starter-select-ui-handler.ts +++ b/src/locales/it/starter-select-ui-handler.ts @@ -7,7 +7,8 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; */ export const starterSelectUiHandler: SimpleTranslationEntries = { "confirmStartTeam": "Vuoi iniziare con questi Pokémon?", - "invalidParty": "This is not a valid starting party!", + "confirmExit": "Do you want to exit?", + "invalidParty": "Questo squadra iniziale non è valida!", "gen1": "1ª", "gen2": "2ª", "gen3": "3ª", @@ -23,6 +24,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "nature": "Natura:", "eggMoves": "Mosse da uova", "addToParty": "Aggiungi al gruppo", + "removeFromParty": "Rimuovi dal gruppo", "toggleIVs": "Vedi/Nascondi IV", "manageMoves": "Gestisci mosse", "manageNature": "Gestisci natura", diff --git a/src/locales/it/status-effect.ts b/src/locales/it/status-effect.ts index 1a402ac30fd..eb676c08c84 100644 --- a/src/locales/it/status-effect.ts +++ b/src/locales/it/status-effect.ts @@ -14,7 +14,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Poison", description: "poisoning", obtain: "{{pokemonNameWithAffix}}\nwas poisoned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas poisoned by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas poisoned by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is hurt\nby poison!", overlap: "{{pokemonNameWithAffix}} is\nalready poisoned!", heal: "{{pokemonNameWithAffix}} was\ncured of its poison!" @@ -23,7 +23,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Toxic", description: "poisoning", obtain: "{{pokemonNameWithAffix}}\nwas badly poisoned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas badly poisoned by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas badly poisoned by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is hurt\nby poison!", overlap: "{{pokemonNameWithAffix}} is\nalready poisoned!", heal: "{{pokemonNameWithAffix}} was\ncured of its poison!" @@ -32,7 +32,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Paralysis", description: "paralysis", obtain: "{{pokemonNameWithAffix}} was paralyzed,\nIt may be unable to move!", - obtainSource: "{{pokemonNameWithAffix}} was paralyzed by {{sourceText}},\nIt may be unable to move!", + obtainSource: "{{pokemonNameWithAffix}} was paralyzed by the {{sourceText}},\nIt may be unable to move!", activation: "{{pokemonNameWithAffix}} is paralyzed!\nIt can't move!", overlap: "{{pokemonNameWithAffix}} is\nalready paralyzed!", heal: "{{pokemonNameWithAffix}} was\nhealed of paralysis!" @@ -41,7 +41,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Sleep", description: "sleep", obtain: "{{pokemonNameWithAffix}}\nfell asleep!", - obtainSource: "{{pokemonNameWithAffix}}\nfell asleep from {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nfell asleep from the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is fast asleep.", overlap: "{{pokemonNameWithAffix}} is\nalready asleep!", heal: "{{pokemonNameWithAffix}} woke up!" @@ -50,7 +50,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Freeze", description: "freezing", obtain: "{{pokemonNameWithAffix}}\nwas frozen solid!", - obtainSource: "{{pokemonNameWithAffix}}\nwas frozen solid by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas frozen solid by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is\nfrozen solid!", overlap: "{{pokemonNameWithAffix}} is\nalready frozen!", heal: "{{pokemonNameWithAffix}} was\ndefrosted!" @@ -59,7 +59,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Burn", description: "burn", obtain: "{{pokemonNameWithAffix}}\nwas burned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas burned by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas burned by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is hurt\nby its burn!", overlap: "{{pokemonNameWithAffix}} is\nalready burned!", heal: "{{pokemonNameWithAffix}} was\nhealed of its burn!" diff --git a/src/locales/it/trainers.ts b/src/locales/it/trainers.ts index 420b9bf9f24..dde79d694ca 100644 --- a/src/locales/it/trainers.ts +++ b/src/locales/it/trainers.ts @@ -118,7 +118,35 @@ export const trainerClasses: SimpleTranslationEntries = { "worker": "Operaio", "worker_female": "Lavoratrice", "workers": "Lavoratori", - "youngster": "Bullo" + "youngster": "Bullo", + "rocket_grunt": "Recluta Team Rocket", + "rocket_grunt_female": "Recluta Team Rocket", + "rocket_grunts": "Reclute Team Rocket", + "rocket_admin": "Rocket Admin", + "rocket_admin_female": "Rocket Admin", + "magma_grunt": "Recluta Team Magma", + "magma_grunt_female": "Recluta Team Magma", + "magma_grunts": "Reclute Team Magma", + "magma_admin": "Magma Admin", + "magma_admin_female": "Magma Admin", + "aqua_grunt": "Recluta Team Idro", + "aqua_grunt_female": "Recluta Team Idro", + "aqua_grunts": "Recluta Team Idro", + "aqua_admin": "Aqua Admin", + "aqua_admin_female": "Aqua Admin", + "galactic_grunt": "Recluta Team Galassia", + "galactic_grunt_female": "Recluta Team Galassia", + "galactic_grunts": "Reclute Team Galassia", + "galactic_admin": "Galactic Admin", + "galactic_admin_female": "Galactic Admin", + "plasma_grunt": "Seguace Plasma", + "plasma_grunt_female": "Seguace Plasma", + "plasma_grunts": "Seguaci Plasma", + "flare_grunt": "Recluta Team Flare", + "flare_grunt_female": "Recluta Team Flare", + "flare_grunts": "Reclute Team Flare", + "flare_admin": "Flare Admin", + "flare_admin_female": "Flare Admin", } as const; // Names of special trainers like gym leaders, elite four, and the champion diff --git a/src/locales/ko/ability-trigger.ts b/src/locales/ko/ability-trigger.ts index 2c28704fc24..61be21bc7ec 100644 --- a/src/locales/ko/ability-trigger.ts +++ b/src/locales/ko/ability-trigger.ts @@ -59,4 +59,5 @@ export const abilityTriggers: SimpleTranslationEntries = { "postSummonSwordOfRuin": "{{pokemonNameWithAffix}}의 재앙의검에 의해\n주위의 {{statName}}[[가]] 약해졌다!", "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}의 재앙의목간에 의해\n주위의 {{statName}}[[가]] 약해졌다!", "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}의 재앙의구슬에 의해\n주위의 {{statName}}[[가]] 약해졌다!", + "preventBerryUse": "{{pokemonNameWithAffix}}[[는]] 긴장해서\n나무열매를 먹을 수 없게 되었다!", } as const; diff --git a/src/locales/ko/achv.ts b/src/locales/ko/achv.ts index d8b8cc54f66..abc0f186fd4 100644 --- a/src/locales/ko/achv.ts +++ b/src/locales/ko/achv.ts @@ -264,6 +264,10 @@ export const PGMachv: AchievementTranslationEntries = { "MONO_FAIRY": { name: "설마 자시안으로?", }, + "FRESH_START": { + name: "첫트!", + description: "새 출발 챌린지 모드 클리어." + }, } as const; // Achievement translations for the when the player character is female (it for now uses the same translations as the male version) diff --git a/src/locales/ko/arena-tag.ts b/src/locales/ko/arena-tag.ts new file mode 100644 index 00000000000..ca1039e2bc0 --- /dev/null +++ b/src/locales/ko/arena-tag.ts @@ -0,0 +1,50 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const arenaTag: SimpleTranslationEntries = { + "yourTeam": "우리 편", + "opposingTeam": "상대 편", + "arenaOnRemove": "{{moveName}}의 효과가 사라졌다!", + "arenaOnRemovePlayer": "우리 편 {{moveName}}의\n효과가 사라졌다!", + "arenaOnRemoveEnemy": "상대 편 {{moveName}}의\n효과가 사라졌다!", + "mistOnAdd": "{{pokemonNameWithAffix}} 편은\n흰안개에 둘러싸였다!", + "mistApply": "흰안개의 효과로\n능력은 떨어지지 않는다!", + "reflectOnAdd": "리플렉터로\n물리공격에 강해졌다!", + "reflectOnAddPlayer": "우리 편은 리플렉터로\n물리공격에 강해졌다!", + "reflectOnAddEnemy": "상대는 리플렉터로\n물리공격에 강해졌다!", + "lightScreenOnAdd": "빛의장막으로\n특수공격에 강해졌다!", + "lightScreenOnAddPlayer": "우리 편은 빛의장막으로\n특수공격에 강해졌다!", + "lightScreenOnAddEnemy": "상대는 빛의장막으로\n특수공격에 강해졌다!", + "auroraVeilOnAdd": "오로라베일로\n물리공격과 특수공격에 강해졌다!", + "auroraVeilOnAddPlayer": "우리 편은 오로라베일로\n물리공격과 특수공격에 강해졌다!", + "auroraVeilOnAddEnemy": "상대는 오로라베일로\n물리공격과 특수공격에 강해졌다!", + "conditionalProtectOnAdd": "팀을\n{{moveName}}[[가]] 보호하고 있다!", + "conditionalProtectOnAddPlayer": "우리 편 주변을\n{{moveName}}[[가]] 보호하고 있다!", + "conditionalProtectOnAddEnemy": "상대 주변을\n{{moveName}}[[가]] 보호하고 있다!", + "conditionalProtectApply": "{{pokemonNameWithAffix}}[[를]]\n{{moveName}}[[가]] 지켜주고 있다!", + "matBlockOnAdd": "{{pokemonNameWithAffix}}[[는]]\n마룻바닥세워막기를 노리고 있다!", + "wishTagOnAdd": "{{pokemonNameWithAffix}}의\n희망사항이 이루어졌다!", + "mudSportOnAdd": "전기의 위력이 약해졌다!", + "mudSportOnRemove": "흙놀이의 효과가\n없어졌다!", + "waterSportOnAdd": "불꽃의 위력이 약해졌다!", + "waterSportOnRemove": "물놀이의 효과가\n없어졌다!", + "spikesOnAdd": "{{opponentDesc}}의 발밑에\n압정이 뿌려졌다!", + "spikesActivateTrap": "{{pokemonNameWithAffix}}[[는]]\n압정뿌리기의 데미지를 입었다!", + "toxicSpikesOnAdd": "{{opponentDesc}}의 발밑에\n독압정이 뿌려졌다!", + "toxicSpikesActivateTrapPoison": "{{pokemonNameWithAffix}}[[는]]\n{{moveName}}[[를]] 흡수했다!", + "stealthRockOnAdd": "{{opponentDesc}} 주변에\n뾰족한 바위가 떠다니기 시작했다!!", + "stealthRockActivateTrap": "{{pokemonNameWithAffix}}에게\n뾰족한 바위가 박혔다!", + "stickyWebOnAdd": "{{opponentDesc}} 발밑에\n{{moveName}}[[가]] 펼쳐졌다!", + "stickyWebActivateTrap": "{{pokemonName}}[[는]]\n끈적끈적네트에 걸렸다!", + "trickRoomOnAdd": "{{pokemonNameWithAffix}}[[는]]\n시공을 뒤틀었다!", + "trickRoomOnRemove": "뒤틀린 시공이 원래대로 되돌아왔다!", + "gravityOnAdd": "중력이 강해졌다!", + "gravityOnRemove": "중력이 원래대로 되돌아왔다!", + "tailwindOnAdd": "순풍이 불기 시작했다!", + "tailwindOnAddPlayer": "우리 편에게\n순풍이 불기 시작했다!", + "tailwindOnAddEnemy": "상대에게\n순풍이 불기 시작했다!", + "tailwindOnRemove": "순풍이 멈췄다!", + "tailwindOnRemovePlayer": "우리 편의\n순풍이 멈췄다!", + "tailwindOnRemoveEnemy": "상대의\n순풍이 멈췄다!", + "happyHourOnAdd": "모두 행복한 기분에\n휩싸였다!", + "happyHourOnRemove": "기분이 원래대로 돌아왔다.", +} as const; diff --git a/src/locales/ko/battle-info.ts b/src/locales/ko/battle-info.ts index 4386f7814b4..357de6003ec 100644 --- a/src/locales/ko/battle-info.ts +++ b/src/locales/ko/battle-info.ts @@ -1,5 +1,5 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; export const battleInfo: SimpleTranslationEntries = { - "generation": "{{generation}}세대", + "generation": "{{generation}}", } as const; diff --git a/src/locales/ko/bgm-name.ts b/src/locales/ko/bgm-name.ts index 69697b07774..81052560fc4 100644 --- a/src/locales/ko/bgm-name.ts +++ b/src/locales/ko/bgm-name.ts @@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = { "missing_entries" : "{{name}}", "battle_kanto_champion": "BW2 관동 챔피언 배틀", "battle_johto_champion": "BW2 성도 챔피언 배틀", - "battle_hoenn_champion": "BW2 호연 챔피언 배틀", + "battle_hoenn_champion_g5": "BW2 호연 챔피언 배틀", + "battle_hoenn_champion_g6": "ORAS 호연 챔피언 배틀", "battle_sinnoh_champion": "BW2 신오 챔피언 배틀", "battle_champion_alder": "BW 하나 챔피언 배틀", "battle_champion_iris": "BW2 하나 챔피언 배틀", diff --git a/src/locales/ko/challenges.ts b/src/locales/ko/challenges.ts index 136417f597b..f84a4f31dc6 100644 --- a/src/locales/ko/challenges.ts +++ b/src/locales/ko/challenges.ts @@ -23,4 +23,10 @@ export const challenges: TranslationEntries = { "desc_default": "선택한 타입의 포켓몬만 사용할 수 있습니다." //type in pokemon-info }, + "freshStart": { + "name": "새 출발", + "desc": "포켓로그를 처음 시작했던 때처럼 강화가 전혀 되지 않은 오리지널 스타팅 포켓몬만 고를 수 있습니다.", + "value.0": "해제", + "value.1": "설정", + } } as const; diff --git a/src/locales/ko/config.ts b/src/locales/ko/config.ts index 4ec47cec036..114950a4d35 100644 --- a/src/locales/ko/config.ts +++ b/src/locales/ko/config.ts @@ -1,7 +1,7 @@ -import { pokemonForm } from "./pokemon-form"; import { ability } from "./ability"; import { abilityTriggers } from "./ability-trigger"; import { arenaFlyout } from "./arena-flyout"; +import { arenaTag } from "./arena-tag"; import { PGFachv, PGMachv } from "./achv"; import { battle } from "./battle"; import { battleInfo } from "./battle-info"; @@ -24,6 +24,7 @@ import { } from "./dialogue"; import { egg } from "./egg"; import { fightUiHandler } from "./fight-ui-handler"; +import { filterBar } from "./filter-bar"; import { gameMode } from "./game-mode"; import { gameStatsUiHandler } from "./game-stats-ui-handler"; import { growth } from "./growth"; @@ -35,6 +36,7 @@ import { move } from "./move"; import { nature } from "./nature"; import { pokeball } from "./pokeball"; import { pokemon } from "./pokemon"; +import { pokemonForm, battlePokemonForm } from "./pokemon-form"; import { pokemonInfo } from "./pokemon-info"; import { pokemonInfoContainer } from "./pokemon-info-container"; import { pokemonSummary } from "./pokemon-summary"; @@ -50,14 +52,17 @@ import { partyUiHandler } from "./party-ui-handler"; import { settings } from "./settings.js"; import { common } from "./common.js"; import { modifierSelectUiHandler } from "./modifier-select-ui-handler"; +import { moveTriggers } from "./move-trigger"; export const koConfig = { ability: ability, abilityTriggers: abilityTriggers, arenaFlyout: arenaFlyout, + arenaTag: arenaTag, battle: battle, battleInfo: battleInfo, battleMessageUiHandler: battleMessageUiHandler, + battlePokemonForm: battlePokemonForm, battlerTags: battlerTags, berry: berry, bgmName: bgmName, @@ -77,6 +82,7 @@ export const koConfig = { PGFdoubleBattleDialogue: PGFdoubleBattleDialogue, egg: egg, fightUiHandler: fightUiHandler, + filterBar: filterBar, gameMode: gameMode, gameStatsUiHandler: gameStatsUiHandler, growth: growth, @@ -105,5 +111,6 @@ export const koConfig = { voucher: voucher, weather: weather, partyUiHandler: partyUiHandler, - modifierSelectUiHandler: modifierSelectUiHandler + modifierSelectUiHandler: modifierSelectUiHandler, + moveTriggers: moveTriggers }; diff --git a/src/locales/ko/dialogue.ts b/src/locales/ko/dialogue.ts index 719b738778d..8e7f09ff373 100644 --- a/src/locales/ko/dialogue.ts +++ b/src/locales/ko/dialogue.ts @@ -391,6 +391,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "로켓단은 다시 떠오를 거니까!" }, }, + "rocket_admin": { + "encounter": { + 1: "어라 어라… 결국 여기까지 오셨습니까? 꽤 우수한 트레이너인가 보군요.", + 2: "영웅 놀이는 여기까지랍니다, 꼬마야.", + 3: "어른이 화를 내면 무섭다는 걸 보여 드리죠!" + }, + "victory": { + 1: "크으… 비주기님 용서해 주세요…!", + 2: "어떻게 이런 일이…", + 3: "아아… 넌 너무 강하다…" + }, + }, "magma_grunt": { "encounter": { 1: " 마그마단을 방해한다면, 자비는 없닷!" @@ -399,6 +411,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "하? 내가 졌어?!" }, }, + "magma_admin": { + "encounter": { + 1: "……아하… ……역시 왔네…그치만 안타깝게 됐어……다 끝났거든", + 2: "……남은……내 일은……너를……막는 것", + 3: "……너랑……인게이지……하고 싶어……아하하하" + }, + "victory": { + 1: "……룰루리", + 2: "……재밌쪄", + 3: "…하아하아……으…하아하아…" + }, + }, "aqua_grunt": { "encounter": { 1: "아쿠아단을 넘본 사람에게는 자비는 없다, 꼬마도 마찬가지야!" @@ -407,6 +431,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "말도 안돼!" }, }, + "aqua_admin": { + "encounter": { + 1: "각오하는 게 좋을 거야! 네 얼굴이 눈물로 범벅이 되게 해주겠어!", + 2: "아앙? 뭐야? 이 건방진 꼬맹이는…", + 3: "…아니 넌!? 일부러 여기까지 쫓아온 거야?" + }, + "victory": { + 1: "하아… 하아…완전 지쳤어", + 2: "크윽…!? 너무 봐줬나…!", + 3: "뭐…뭐라고!?" + }, + }, "galactic_grunt": { "encounter": { 1: "갤럭시단을 방해하지 마!" @@ -415,6 +451,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "사격 중지…… " }, }, + "galactic_admin": { + "encounter": { + 1: "나는 갤럭시단에 있는 간부 중의 한 명.", + 2: "갤럭시단을 방해한다면 일말의 가능성도 모두 제거한다!!", + 3: "왜 그래? 설마 떨고 있는 거야?" + }, + "victory": { + 1: "설마! 내가 졌다고!? 건방진 아이로구나!!", + 2: "…역시 강해!", + 3: "어린아이에게 지다니… 방심이란 무섭구나." + }, + }, "plasma_grunt": { "encounter": { 1: "다른 생각을 가진사람들은 용납하지 않겠다!" @@ -423,6 +471,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "플라-스마-!" }, }, + "plasma_sage": { + "encounter": { + 1: "너는 플라스마단에게 있어 불안요소가 될 것이다. 여기서 제거하겠다!", + 2: "이런 이런… 내가 싸워야만 하다니.", + 3: "여기까지 오다니 대단한 트레이너군." + }, + "victory": { + 1: "게치스…", + 2: "그건 그렇고 춥구먼. 나는 떨고 있다. 괴롭지만 살아 있다.", + 3: "흐음. 의외로 똑똑한 트레이너군." + }, + }, "flare_grunt": { "encounter": { 1: "패션이 우리한텐 가장 중요하다고!" @@ -431,6 +491,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "미래가 밝아 보이질 않네." }, }, + "flare_admin": { + "encounter": { + 1: "왔다! 왔구나! 자! 자! 아직 끝나지 않았다!", + 2: "너 강하구나. 에너지를 얼마나 갖고 있지?", + 3: "기다리고 있었어! 너를 조사하겠다. 자 시작한다!" + }, + "victory": { + 1: "강하구나, 너는. 응, 정말 강해, 너는.", + 2: "그렇지만 보스의 꿈이 이루어져 아름다운 세상이 태어날 것이다!", + 3: "굉장하구나 너! 아주 굉장해! 나는 너를 인정하겠다" + }, + }, "rocket_boss_giovanni_1": { "encounter": { 1: "그래서! 여기까지 오다니, 감탄이 절로 나오는군!" diff --git a/src/locales/ko/filter-bar.ts b/src/locales/ko/filter-bar.ts new file mode 100644 index 00000000000..b4dcb48b581 --- /dev/null +++ b/src/locales/ko/filter-bar.ts @@ -0,0 +1,33 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const filterBar: SimpleTranslationEntries = { + "genFilter": "세대", + "typeFilter": "타입", + "caughtFilter": "포획", + "unlocksFilter": "해금", + "miscFilter": "기타", + "sortFilter": "정렬", + "all": "전체", + "normal": "기본", + "uncaught": "미포획", + "passive": "패시브", + "passiveUnlocked": "패시브 해금", + "passiveLocked": "패시브 잠김", + "costReduction": "코스트 줄이기", + "costReductionUnlocked": "코스트 절감됨", + "costReductionLocked": "코스트 절감 없음", + "ribbon": "클리어 여부", + "hasWon": "클리어 완료", + "hasNotWon": "클리어 안함", + "hiddenAbility": "숨겨진 특성", + "hasHiddenAbility": "숨겨진 특성 보유", + "noHiddenAbility": "숨겨진 특성 없음", + "pokerus": "포켓러스", + "hasPokerus": "포켓러스 감염", + "noPokerus": "포켓러스 없음", + "sortByNumber": "도감번호", + "sortByCost": "코스트", + "sortByCandies": "사탕 수", + "sortByIVs": "개체값", + "sortByName": "이름", +}; diff --git a/src/locales/ko/modifier-type.ts b/src/locales/ko/modifier-type.ts index 28df422645a..f09fba0b09a 100644 --- a/src/locales/ko/modifier-type.ts +++ b/src/locales/ko/modifier-type.ts @@ -58,10 +58,10 @@ export const modifierType: ModifierTypeTranslationEntries = { description: "지니게 하면 {{moveType}}타입 기술의 위력이 20% 상승한다.", }, "PokemonLevelIncrementModifierType": { - description: "포켓몬 1마리의 레벨이 기본 1만큼, 사탕단지의 개수에 따라 최대 {{levels}}까지 상승한다.", + description: "포켓몬 1마리의 레벨이 {{levels}}만큼 상승한다.", }, "AllPokemonLevelIncrementModifierType": { - description: "자신의 모든 포켓몬의 레벨이 기본 1씩, 사탕단지의 개수에 따라 최대 {{levels}}까지 상승한다.", + description: "자신의 모든 포켓몬의 레벨이 {{levels}}만큼 상승한다.", }, "PokemonBaseStatBoosterModifierType": { description: "지니게 하면 {{statName}} 종족값을 10% 올려준다. 개체값이 높을수록 더 많이 누적시킬 수 있다.", @@ -101,7 +101,7 @@ export const modifierType: ModifierTypeTranslationEntries = { }, "TmModifierTypeWithInfo": { name: "No.{{moveId}} {{moveName}}", - description: "포켓몬에게 {{moveName}}를(을) 가르침.\n(C 또는 Shift를 꾹 눌러 정보 확인)", + description: "포켓몬에게 {{moveName}}[[를]] 가르침.\n(C 또는 Shift를 꾹 눌러 정보 확인)", }, "EvolutionItemModifierType": { description: "어느 특정 포켓몬을 진화시킨다.", @@ -153,7 +153,7 @@ export const modifierType: ModifierTypeTranslationEntries = { "REVIVER_SEED": { name: "부활의씨앗", description: "포켓몬이 공격을 받고 쓰러지려 할 때 HP를 절반 회복한다." }, - "WHITE_HERB": { name: "White Herb", description: "An item to be held by a Pokémon. It will restore any lowered stat in battle." }, + "WHITE_HERB": { name: "하양허브", description: "지니게 한 포켓몬의 능력이 떨어졌을 때 원래 상태로 돌아온다." }, "ETHER": { name: "PP에이드" }, "MAX_ETHER": { name: "PP회복" }, diff --git a/src/locales/ko/modifier.ts b/src/locales/ko/modifier.ts index 71508f774c7..98460b118f1 100644 --- a/src/locales/ko/modifier.ts +++ b/src/locales/ko/modifier.ts @@ -10,4 +10,5 @@ export const modifier: SimpleTranslationEntries = { "turnHeldItemTransferApply": "{{pokemonName}}의 {{typeName}}[[는]]\n{{pokemonNameWithAffix}}의 {{itemName}}[[를]] 흡수했다!", "contactHeldItemTransferApply": "{{pokemonName}}의 {{typeName}}[[는]]\n{{pokemonNameWithAffix}}의 {{itemName}}[[를]] 가로챘다!", "enemyTurnHealApply": "{{pokemonNameWithAffix}}의\n체력이 약간 회복되었다!", + "bypassSpeedChanceApply": "{{pokemonName}}[[는]] {{itemName}}[[로]]\n행동이 빨라졌다!", } as const; diff --git a/src/locales/ko/move-trigger.ts b/src/locales/ko/move-trigger.ts new file mode 100644 index 00000000000..9ebf08b1017 --- /dev/null +++ b/src/locales/ko/move-trigger.ts @@ -0,0 +1,62 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const moveTriggers: SimpleTranslationEntries = { + "hitWithRecoil" : "{{pokemonName}}[[는]]\n반동으로 데미지를 입었다!", + "cutHpPowerUpMove": "{{pokemonName}}[[는]]\n체력을 깎아서 자신의 기술을 강화했다!", + "absorbedElectricity": "{{pokemonName}}는(은)\n전기를 흡수했다!", + "switchedStatChanges": "{{pokemonName}}[[는]] 상대와 자신의\n능력 변화를 바꿨다!", + "goingAllOutForAttack": "{{pokemonName}}[[는]]\n전력을 다하기 시작했다!", + "regainedHealth": "{{pokemonName}}[[는]]\n기력을 회복했다!", + "keptGoingAndCrashed": "{{pokemonName}}[[는]]\n의욕이 넘쳐서 땅에 부딪쳤다!", + "fled": "{{pokemonName}}[[는]]\N도망쳤다!", + "cannotBeSwitchedOut": "{{pokemonName}}[[를]]\n돌아오게 할 수 없습니다!", + "swappedAbilitiesWithTarget": "{{pokemonName}}[[는]]\n서로의 특성을 교체했다!", + "coinsScatteredEverywhere": "돈이 주위에 흩어졌다!", + "attackedByItem": "{{itemName}}[[가]]\n{{pokemonName}}에게 덤벼들었다!", + "whippedUpAWhirlwind": "{{pokemonName}}의 주위에서\n공기가 소용돌이친다!", + "flewUpHigh": "{{pokemonName}}는(은)\n하늘 높이 날아올랐다!", + "tookInSunlight": "{{pokemonName}}는(은)\n빛을 흡수했다!", + "dugAHole": "{{pokemonName}}는(은)\n땅으로 파고들었다!", + "loweredItsHead": "{{pokemonName}}는(은)\n목을 움츠렸다!", + "isGlowing": "{{pokemonName}}를(을)\n강렬한 빛이 감쌌다!", + "bellChimed": "방울소리가 울려 퍼졌다!", + "foresawAnAttack": "{{pokemonName}}는(은)\n미래의 공격을 예지했다!", + "hidUnderwater": "{{pokemonName}}는(은)\n물속에 몸을 숨겼다!", + "soothingAromaWaftedThroughArea": "기분 좋은 향기가 퍼졌다!", + "sprangUp": "{{pokemonName}}는(은)\n높이 뛰어올랐다!", + "choseDoomDesireAsDestiny": "{{pokemonName}}는(은)\n파멸의소원을 미래에 맡겼다!", + "vanishedInstantly": "{{pokemonName}}의 모습이\n일순간에 사라졌다!", + "tookTargetIntoSky": "{{pokemonName}}는(은) {{targetName}}를(을)\n상공으로 데려갔다!", + "becameCloakedInFreezingLight": "{{pokemonName}}는(은)\n차가운 빛에 둘러싸였다!", + "becameCloakedInFreezingAir": "{{pokemonName}}는(은)\n차디찬 공기에 둘러싸였다!", + "isChargingPower": "{{pokemonName}}는(은)\n파워를 모으고 있다!", + "burnedItselfOut": "{{pokemonName}}의 불꽃은 다 타 버렸다!", + "startedHeatingUpBeak": "{{pokemonName}}는(은)\n부리를 가열하기 시작했다!", + "isOverflowingWithSpacePower": "{{pokemonName}}에게서\n우주의 힘이 넘쳐난다!", + "usedUpAllElectricity": "{{pokemonName}}[[는]]\n전기를 다 써 버렸다!", + "stoleItem": "{{pokemonName}}[[는]] {{targetName}}[[로]]부터\n{{itemName}}[[을]] 빼앗았다!", + "incineratedItem": "{{pokemonName}}[[는]] {{targetName}}의\n{{itemName}}[[를]] 불태워서 없애버렸다!", + "knockedOffItem": "{{pokemonName}}[[는]] {{targetName}}의\n{{itemName}}[[를]] 탁 쳐서 떨구었다!", + "tookMoveAttack": "{{pokemonName}}[[는]]\n{{moveName}} 공격을 끌어들였다!", + "cutOwnHpAndMaximizedStat": "{{pokemonName}}[[는]] 체력을 깎아서\n{{statName}}[[를]] 풀 파워로 만들었다!", + "copiedStatChanges": "{{pokemonName}}[[는]] {{targetName}}의\n능력 변화를 복사했다!", + "magnitudeMessage": "매그니튜드{{magnitude}}!", + "tookAimAtTarget": "{{pokemonName}}[[는]] 목표를\n{{targetName}}[[로]] 결정했다!", + "transformedIntoType": "{{pokemonName}}[[는]]\n{{typeName}}타입이 됐다!", + "copiedMove": "{{pokemonName}}[[는]]\n{{moveName}}[[를]] 복사했다!", + "sketchedMove": "{{pokemonName}}[[는]]\n{{moveName}}[[를]] 스케치했다!", + "acquiredAbility": "{{pokemonName}}[[는]]\n{{abilityName}}[[가]] 되었다!", + "copiedTargetAbility": "{{pokemonName}}[[는]] {{targetName}}의\n{{abilityName}}[[를]] 복사했다!", + "transformedIntoTarget": "{{pokemonName}}[[는]]\n{{targetName}}[[로]] 변신했다!", + "tryingToTakeFoeDown": "{{pokemonName}}[[는]] 상대를\n길동무로 삼으려 하고 있다!", + "addType": "{{pokemonName}}에게\n{{typeName}}타입이 추가되었다!", + "cannotUseMove": "{{pokemonName}}[[는]]\n{{moveName}}[[를]] 쓸 수 없다!", + "healHp": "{{pokemonName}}의\n체력이 회복되었다!", + "sacrificialFullRestore": "{{pokemonName}}의\n치유소원이 이루어졌다!", + "invertStats": "{{pokemonName}}[[는]]\n능력 변화가 뒤집혔다!", + "resetStats": "{{pokemonName}}의 모든 상태가\n원래대로 되돌아왔다!", + "faintCountdown": "{{pokemonName}}[[는]]\n{{turnCount}}턴 후에 쓰러져 버린다!", + "copyType": "{{pokemonName}}[[는]]\n{{targetPokemonName}}[[와]] 같은 타입이 되었다!", + "suppressAbilities": "{{pokemonName}}의\n특성이 효과를 발휘하지 못하게 되었다!", + "swapArenaTags": "{{pokemonName}}[[는]]\n서로의 필드 효과를 교체했다!", +} as const; diff --git a/src/locales/ko/pokemon-form.ts b/src/locales/ko/pokemon-form.ts index 06bc743f1a1..78c9a762233 100644 --- a/src/locales/ko/pokemon-form.ts +++ b/src/locales/ko/pokemon-form.ts @@ -1,7 +1,6 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; -export const pokemonForm: SimpleTranslationEntries = { - // Battle forms +export const battlePokemonForm: SimpleTranslationEntries = { "mega": "메가{{pokemonName}}", "mega-x": "메가{{pokemonName}}X", "mega-y": "메가{{pokemonName}}Y", @@ -9,6 +8,14 @@ export const pokemonForm: SimpleTranslationEntries = { "gigantamax": "거다이맥스 {{pokemonName}}", "eternamax": "무한다이맥스 {{pokemonName}}", + "megaChange": "{{preName}}[[는]]\n{{pokemonName}}[[로]] 메가진화했다!", + "gigantamaxChange": "{{preName}}[[는]]\n{{pokemonName}}가 되었다!", + "eternamaxChange": "{{preName}}[[는]]\n{{pokemonName}}가 되었다!", + "revertChange": "{{pokemonName}}[[는]]\n원래 모습으로 되돌아왔다!", + "formChange": "{{preName}}[[는]]\n다른 모습으로 변화했다!", +} as const; + +export const pokemonForm: SimpleTranslationEntries = { // Starters forms // 1G "pikachuCosplay": "옷갈아입기", diff --git a/src/locales/ko/starter-select-ui-handler.ts b/src/locales/ko/starter-select-ui-handler.ts index a0c305b4266..25bb006059e 100644 --- a/src/locales/ko/starter-select-ui-handler.ts +++ b/src/locales/ko/starter-select-ui-handler.ts @@ -7,7 +7,8 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; */ export const starterSelectUiHandler: SimpleTranslationEntries = { "confirmStartTeam": "이 포켓몬들로 시작하시겠습니까?", - "invalidParty": "This is not a valid starting party!", + "confirmExit": "나가시겠습니까?", + "invalidParty": "스타팅 포켓몬 파티에 적합하지 않습니다!", "gen1": "1세대", "gen2": "2세대", "gen3": "3세대", @@ -23,6 +24,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "nature": "성격:", "eggMoves": "알 기술", "addToParty": "파티에 추가", + "removeFromParty": "파티에서 제외", "toggleIVs": "개체값 토글", "manageMoves": "기술 관리", "manageNature": "성격 관리", @@ -30,9 +32,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "selectNature": "교체할 성격을 선택해주세요.", "selectMoveSwapOut": "교체할 기술을 선택해주세요.", "selectMoveSwapWith": "교체될 기술을 선택해주세요. 대상:", + "sameSpeciesEgg": "알 구매하기", "unlockPassive": "패시브 해금", "reduceCost": "코스트 줄이기", - "sameSpeciesEgg": "알 구매하기", "cycleShiny": ": 색이 다른", "cycleForm": ": 폼", "cycleGender": ": 암수", diff --git a/src/locales/ko/trainers.ts b/src/locales/ko/trainers.ts index 429ab13b223..3a139026448 100644 --- a/src/locales/ko/trainers.ts +++ b/src/locales/ko/trainers.ts @@ -127,16 +127,33 @@ export const trainerClasses: SimpleTranslationEntries = { "youngster": "반바지 꼬마", "rocket_grunt": "로켓단 조무래기", "rocket_grunt_female": "로켓단 조무래기", + "rocket_grunts": "로켓단 조무래기들", + "rocket_admin": "로켓단 간부", + "rocket_admin_female": "로켓단 간부", "magma_grunt": "마그마단 조무래기", "magma_grunt_female": "마그마단 조무래기", + "magma_grunts": "마그마단 조무래기들", + "magma_admin": "마그마단 간부", + "magma_admin_female": "마그마단 간부", "aqua_grunt": "아쿠아단 조무래기", "aqua_grunt_female": "아쿠아단 조무래기", + "aqua_grunts": "아쿠아단 조무래기들", + "aqua_admin": "아쿠아단 간부", + "aqua_admin_female": "아쿠아단 간부", "galactic_grunt": "갤럭시단 조무래기", "galactic_grunt_female": "갤럭시단 조무래기", + "galactic_grunts": "갤럭시단 조무래기들", + "galactic_admin": "갤럭시단 간부", + "galactic_admin_female": "갤럭시단 간부", "plasma_grunt": "플라스마단 조무래기", "plasma_grunt_female": "플라스마단 조무래기", + "plasma_grunts": "플라스마단 조무래기들", + "plasma_sage": "플라스마단 현인", "flare_grunt": "플레어단 조무래기", "flare_grunt_female": "플레어단 조무래기", + "flare_grunts": "플레어단 조무래기들", + "flare_admin": "플레어단 간부", + "flare_admin_female": "플레어단 간부", } as const; // Names of special trainers like gym leaders, elite four, and the champion diff --git a/src/locales/pt_BR/ability-trigger.ts b/src/locales/pt_BR/ability-trigger.ts index ab845a23d4a..f5d9511f3f6 100644 --- a/src/locales/pt_BR/ability-trigger.ts +++ b/src/locales/pt_BR/ability-trigger.ts @@ -22,7 +22,7 @@ export const abilityTriggers: SimpleTranslationEntries = { "postDefendAbilityGive": "{{pokemonNameWithAffix}} deu a seu alvo\na habilidade {{abilityName}}!", "postDefendMoveDisable": "{{moveName}} de {{pokemonNameWithAffix}}\nfoi desabilitado!", "pokemonTypeChange": "{{pokemonNameWithAffix}} se transformou no tipo {{moveType}}!", - "postAttackStealHeldItem": "{{pokemonNameWithAffix}} roubou\n{{stolenItemType}} de {defenderName}}!", + "postAttackStealHeldItem": "{{pokemonNameWithAffix}} roubou\n{{stolenItemType}} de {{defenderName}}!", "postDefendStealHeldItem": "{{pokemonNameWithAffix}} roubou\n{{stolenItemType}} de {{attackerName}}!", "copyFaintedAllyAbility": "A habilidade {{abilityName}} de {{pokemonNameWithAffix}} foi tomada!", "intimidateImmunity": "{{abilityName}} de {{pokemonNameWithAffix}} previniu-o(a) de ser intimidado(a)!", @@ -59,4 +59,5 @@ export const abilityTriggers: SimpleTranslationEntries = { "postSummonSwordOfRuin": "Sword of Ruin de {{pokemonNameWithAffix}} reduziu a {{statName}}\nde todos os Pokémon em volta!", "postSummonTabletsOfRuin": "Tablets of Ruin de {{pokemonNameWithAffix}} reduziu o {{statName}}\nde todos os Pokémon em volta!", "postSummonBeadsOfRuin": "Beads of Ruin de {{pokemonNameWithAffix}} reduziu a {{statName}}\nde todos os Pokémon em volta!", + "preventBerryUse": "{{pokemonNameWithAffix}} está nervoso\ndemais para comer frutas!", } as const; diff --git a/src/locales/pt_BR/achv.ts b/src/locales/pt_BR/achv.ts index ea77e0c17e9..78c4da6ae2e 100644 --- a/src/locales/pt_BR/achv.ts +++ b/src/locales/pt_BR/achv.ts @@ -227,7 +227,7 @@ export const PGMachv: AchievementTranslationEntries = { name: "Comendo Poeira", }, "MONO_ROCK": { - name: "Duro Como Pedra", + name: "...Tanto Bate Até Que Fura", }, "MONO_BUG": { name: "Vida de Inseto", @@ -265,6 +265,10 @@ export const PGMachv: AchievementTranslationEntries = { "MONO_FAIRY": { name: "Clube das Winx", }, + "FRESH_START": { + name: "De Primeira!", + description: "Complete o desafio de novo começo." + }, } as const; // Achievement translations for the when the player character is female @@ -494,7 +498,7 @@ export const PGFachv: AchievementTranslationEntries = { name: "Comendo Poeira", }, "MONO_ROCK": { - name: "Duro Como Pedra", + name: "...Tanto Bate Até Que Fura", }, "MONO_BUG": { name: "Vida de Inseto", @@ -532,4 +536,8 @@ export const PGFachv: AchievementTranslationEntries = { "MONO_FAIRY": { name: "Clube das Winx", }, + "FRESH_START": { + name: "De Primeira!", + description: "Complete o desafio de novo começo." + }, } as const; diff --git a/src/locales/pt_BR/arena-tag.ts b/src/locales/pt_BR/arena-tag.ts new file mode 100644 index 00000000000..0d3b8ff587f --- /dev/null +++ b/src/locales/pt_BR/arena-tag.ts @@ -0,0 +1,50 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const arenaTag: SimpleTranslationEntries = { + "yourTeam": "sua equipe", + "opposingTeam": "a equipe adversária", + "arenaOnRemove": "O efeito de {{moveName}} acabou.", + "arenaOnRemovePlayer": "O efeito de {{moveName}} acabou\nem sua equipe.", + "arenaOnRemoveEnemy": "O efeito de {{moveName}} acabou\nna equipe adversária.", + "mistOnAdd": "A equipe de {{pokemonNameWithAffix}} está protegida\npela névoa!", + "mistApply": "A névoa previne\na diminuição de atributos!", + "reflectOnAdd": "Reflect reduziu o dano de movimentos físicos.", + "reflectOnAddPlayer": "Reflect reduziu o dano de movimentos físicos em sua equipe.", + "reflectOnAddEnemy": "Reflect reduziu o dano de movimentos físicos na equipe adversária.", + "lightScreenOnAdd": "Light Screen reduziu o dano de movimentos especiais.", + "lightScreenOnAddPlayer": "Light Screen reduziu o dano de movimentos especiais em sua equipe.", + "lightScreenOnAddEnemy": "Light Screen reduziu o dano de movimentos especiais na equipe adversária.", + "auroraVeilOnAdd": "Aurora Veil reduziu o dano de movimentos.", + "auroraVeilOnAddPlayer": "Aurora Veil reduziu o dano de movimentos em sua equipe.", + "auroraVeilOnAddEnemy": "Aurora Veil reduziu o dano de movimentos na equipe adversária.", + "conditionalProtectOnAdd": "{{moveName}} protegeu a equipe!", + "conditionalProtectOnAddPlayer": "{{moveName}} protegeu sua equipe!", + "conditionalProtectOnAddEnemy": "{{moveName}} protegeu a\nequipe adversária!", + "conditionalProtectApply": "{{moveName}} protegeu {{pokemonNameWithAffix}}!", + "matBlockOnAdd": "{{pokemonNameWithAffix}} pretende levantar um tapete\npara bloquear ataques!", + "wishTagOnAdd": "O desejo de {{pokemonNameWithAffix}}\nfoi concedido!", + "mudSportOnAdd": "O poder de movimentos elétricos foi enfraquecido!", + "mudSportOnRemove": "Os efeitos de Mud Sport\nsumiram.", + "waterSportOnAdd": "O poder de movimentos de fogo foi enfraquecido!", + "waterSportOnRemove": "Os efeitos de Water Sport\nsumiram.", + "spikesOnAdd": "{{moveName}} foram espalhados\nno chão ao redor de {{opponentDesc}}!", + "spikesActivateTrap": "{{pokemonNameWithAffix}} foi ferido\npelos espinhos!", + "toxicSpikesOnAdd": "{{moveName}} foram espalhados\nno chão ao redor de {{opponentDesc}}!", + "toxicSpikesActivateTrapPoison": "{{pokemonNameWithAffix}} absorveu os {{moveName}}!", + "stealthRockOnAdd": "Pedras pontiagudas estão flutuando\nao redor de {{opponentDesc}}!", + "stealthRockActivateTrap": "{{pokemonNameWithAffix}} foi atingido\npor pedras pontiagudas!", + "stickyWebOnAdd": "Uma {{moveName}} foi espalhada no chão ao redor da equipe adversária!", + "stickyWebActivateTrap": "{{pokemonName}} adversário foi pego por uma Sticky Web!", + "trickRoomOnAdd": "{{pokemonNameWithAffix}} distorceu\nas dimensões!", + "trickRoomOnRemove": "As dimensões distorcidas\nretornaram ao normal!", + "gravityOnAdd": "A gravidade aumentou!", + "gravityOnRemove": "A gravidade retornou ao normal!", + "tailwindOnAdd": "O Tailwind soprou de trás de sua equipe!", + "tailwindOnAddPlayer": "O Tailwind soprou de trás de\nsua equipe!", + "tailwindOnAddEnemy": "O Tailwind soprou de trás da\nequipe adversária!", + "tailwindOnRemove": "O Tailwind de sua equipe acabou!", + "tailwindOnRemovePlayer": "O Tailwind de sua equipe acabou!", + "tailwindOnRemoveEnemy": "O Tailwind da equipe adversária acabou!", + "happyHourOnAdd": "Todos foram envolvidos por uma atmosfera alegre!", + "happyHourOnRemove": "A atmosfera retornou ao normal.", +} as const; diff --git a/src/locales/pt_BR/battle.ts b/src/locales/pt_BR/battle.ts index 0e6831f9295..824b069f0a4 100644 --- a/src/locales/pt_BR/battle.ts +++ b/src/locales/pt_BR/battle.ts @@ -13,7 +13,7 @@ export const battle: SimpleTranslationEntries = { "trainerGo": "{{trainerName}} escolheu {{pokemonName}}!", "switchQuestion": "Quer trocar\nde {{pokemonName}}?", "trainerDefeated": "Você derrotou\n{{trainerName}}!", - "moneyWon": "Você ganhou\n₽{{moneyAmount}} por ganhar!", + "moneyWon": "Você ganhou\n₽{{moneyAmount}} por vencer!", "moneyPickedUp": "Você pegou ₽{{moneyAmount}} do chão!", "pokemonCaught": "{{pokemonName}} foi capturado!", "addedAsAStarter": "{{pokemonName}} foi adicionado\naos seus iniciais!", diff --git a/src/locales/pt_BR/bgm-name.ts b/src/locales/pt_BR/bgm-name.ts index ae2756e74be..01baf93c2a5 100644 --- a/src/locales/pt_BR/bgm-name.ts +++ b/src/locales/pt_BR/bgm-name.ts @@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = { "missing_entries": "{{name}}", "battle_kanto_champion": "B2W2 Batalha do Campeão de Kanto", "battle_johto_champion": "B2W2 Batalha do Campeão de Johto", - "battle_hoenn_champion": "B2W2 Batalha do Campeão de Hoenn", + "battle_hoenn_champion_g5": "B2W2 Batalha do Campeão de Hoenn", + "battle_hoenn_champion_g6": "ORAS Batalha do Campeão de Hoenn", "battle_sinnoh_champion": "B2W2 Batalha do Campeão de Sinnoh", "battle_champion_alder": "BW Batalha do Campeão de Unova", "battle_champion_iris": "B2W2 Batalha do Campeão de Unova", diff --git a/src/locales/pt_BR/config.ts b/src/locales/pt_BR/config.ts index 0aee484e1ce..5f7582dca63 100644 --- a/src/locales/pt_BR/config.ts +++ b/src/locales/pt_BR/config.ts @@ -2,6 +2,7 @@ import { ability } from "./ability"; import { abilityTriggers } from "./ability-trigger"; import { PGFachv, PGMachv } from "./achv"; import { arenaFlyout } from "./arena-flyout"; +import { arenaTag } from "./arena-tag"; import { battle } from "./battle"; import { battleInfo } from "./battle-info"; import { battleMessageUiHandler } from "./battle-message-ui-handler"; @@ -24,6 +25,7 @@ import { } from "./dialogue"; import { egg } from "./egg"; import { fightUiHandler } from "./fight-ui-handler"; +import { filterBar } from "./filter-bar"; import { gameMode } from "./game-mode"; import { gameStatsUiHandler } from "./game-stats-ui-handler"; import { growth } from "./growth"; @@ -37,7 +39,7 @@ import { nature } from "./nature"; import { partyUiHandler } from "./party-ui-handler"; import { pokeball } from "./pokeball"; import { pokemon } from "./pokemon"; -import { pokemonForm } from "./pokemon-form"; +import { pokemonForm, battlePokemonForm } from "./pokemon-form"; import { pokemonInfo } from "./pokemon-info"; import { pokemonInfoContainer } from "./pokemon-info-container"; import { pokemonSummary } from "./pokemon-summary"; @@ -50,14 +52,17 @@ import { titles, trainerClasses, trainerNames } from "./trainers"; import { tutorial } from "./tutorial"; import { voucher } from "./voucher"; import { terrain, weather } from "./weather"; +import { moveTriggers } from "./move-trigger"; export const ptBrConfig = { ability: ability, abilityTriggers: abilityTriggers, arenaFlyout: arenaFlyout, + arenaTag: arenaTag, battle: battle, battleInfo: battleInfo, battleMessageUiHandler: battleMessageUiHandler, + battlePokemonForm: battlePokemonForm, battlerTags: battlerTags, berry: berry, bgmName: bgmName, @@ -77,6 +82,7 @@ export const ptBrConfig = { PGFdoubleBattleDialogue: PGFdoubleBattleDialogue, egg: egg, fightUiHandler: fightUiHandler, + filterBar: filterBar, gameMode: gameMode, gameStatsUiHandler: gameStatsUiHandler, growth: growth, @@ -105,5 +111,6 @@ export const ptBrConfig = { voucher: voucher, weather: weather, partyUiHandler: partyUiHandler, - modifierSelectUiHandler: modifierSelectUiHandler + modifierSelectUiHandler: modifierSelectUiHandler, + moveTriggers: moveTriggers }; diff --git a/src/locales/pt_BR/filter-bar.ts b/src/locales/pt_BR/filter-bar.ts new file mode 100644 index 00000000000..d08d2d28707 --- /dev/null +++ b/src/locales/pt_BR/filter-bar.ts @@ -0,0 +1,33 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const filterBar: SimpleTranslationEntries = { + "genFilter": "Ger.", + "typeFilter": "Tipo", + "caughtFilter": "Capturado", + "unlocksFilter": "Desbloqueios", + "miscFilter": "Outros", + "sortFilter": "Ordem", + "all": "Tudo", + "normal": "Normal", + "uncaught": "Não Capturado", + "passive": "Passiva", + "passiveUnlocked": "Passiva Desbloqueada", + "passiveLocked": "Passiva Bloqueada", + "costReduction": "Redução de Custo", + "costReductionUnlocked": "Redução de Custo Desbloq.", + "costReductionLocked": "Redução de Custo Bloq.", + "ribbon": "Fita", + "hasWon": "Fita - Sim", + "hasNotWon": "Fita - Não", + "hiddenAbility": "Habilidade Oculta", + "hasHiddenAbility": "Habilidade Oculta - Sim", + "noHiddenAbility": "Habilidade Oculta - Não", + "pokerus": "Pokérus", + "hasPokerus": "Pokérus - Sim", + "noPokerus": "Pokérus - Não", + "sortByNumber": "Número", + "sortByCost": "Custo", + "sortByCandies": "# Doces", + "sortByIVs": "IVs", + "sortByName": "Nome", +}; diff --git a/src/locales/pt_BR/modifier.ts b/src/locales/pt_BR/modifier.ts index 87682a55466..168665205c3 100644 --- a/src/locales/pt_BR/modifier.ts +++ b/src/locales/pt_BR/modifier.ts @@ -10,4 +10,5 @@ export const modifier: SimpleTranslationEntries = { "turnHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} foi absorvido(a)\npelo {{typeName}} de {{pokemonName}}!", "contactHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} foi pego(a)\npela {{typeName}} de {{pokemonName}}!", "enemyTurnHealApply": "{{pokemonNameWithAffix}}\nrestaurou um pouco de seus PS!", + "bypassSpeedChanceApply": "{{pokemonName}} se move mais rápido que o normal graças à sua {{itemName}}!", } as const; diff --git a/src/locales/pt_BR/move-trigger.ts b/src/locales/pt_BR/move-trigger.ts new file mode 100644 index 00000000000..c6f35d8f6d1 --- /dev/null +++ b/src/locales/pt_BR/move-trigger.ts @@ -0,0 +1,62 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const moveTriggers: SimpleTranslationEntries = { + "hitWithRecoil" : "{{pokemonName}} foi ferido pelo dano reverso!", + "cutHpPowerUpMove": "{{pokemonName}} diminuiu seus PS para aumentar o poder do ataque!", + "absorbedElectricity": "{{pokemonName}} absorveu eletricidade!", + "switchedStatChanges": "{{pokemonName}} trocou as mudanças de atributo com o alvo!", + "goingAllOutForAttack": "{{pokemonName}} está arriscando tudo nesse ataque!", + "regainedHealth": "{{pokemonName}} recuperou/nsaúde!", + "keptGoingAndCrashed": "{{pokemonName}} continuou/nindo e bateu!", + "fled": "{{pokemonName}} fugiu!", + "cannotBeSwitchedOut": "{{pokemonName}} não pode ser trocado!", + "swappedAbilitiesWithTarget": "{{pokemonName}} trocou/nde habilidades com o alvo!", + "coinsScatteredEverywhere": "Moedas foram espalhadas por toda parte!", + "attackedByItem": "{{pokemonName}} está prestes a ser atacado por {{itemName}}!", + "whippedUpAWhirlwind": "{{pokemonName}} criou\num redemoinho de vento!", + "flewUpHigh": "{{pokemonName}} voou\nbem alto!", + "tookInSunlight": "{{pokemonName}} absorveu a luz do sol!", + "dugAHole": "{{pokemonName}} cavou um buraco no chão!", + "loweredItsHead": "{{pokemonName}} abaixou sua cabeça!", + "isGlowing": "{{pokemonName}} ficou envolto em uma luz forte!", + "bellChimed": "Um sino tocou!", + "foresawAnAttack": "{{pokemonName}} previu/num ataque!", + "hidUnderwater": "{{pokemonName}} se escondeu/nembaixo d'água!", + "soothingAromaWaftedThroughArea": "Um aroma suave se espalhou pelo ambiente!", + "sprangUp": "{{pokemonName}} se levantou!", + "choseDoomDesireAsDestiny": "{{pokemonName}} escolheu\no Desejo da Perdição como seu destino!", + "vanishedInstantly": "{{pokemonName}} desapareceu/nde repente!", + "tookTargetIntoSky": "{{pokemonName}} levou {{targetName}}\npara o céu!", + "becameCloakedInFreezingLight": "{{pokemonName}} ficou envolto/nem uma luz congelante!", + "becameCloakedInFreezingAir": "{{pokemonName}} ficou envolto/nem ar congelante!", + "isChargingPower": "{{pokemonName}} está absorvendo energia!", + "burnedItselfOut": "{{pokemonName}} apagou seu próprio fogo!", + "startedHeatingUpBeak": "{{pokemonName}} começou\na esquentar seu bico!", + "isOverflowingWithSpacePower": "{{pokemonName}} está sobrecarregado\ncom energia espacial!", + "usedUpAllElectricity": "{{pokemonName}} usou toda a sua eletricidade!", + "stoleItem": "{{pokemonName}} roubou/no(a) {{itemName}} de {{targetName}}!", + "incineratedItem": "{{pokemonName}} incinerou\na {{itemName}} de {{targetName}}!", + "knockedOffItem": "{{pokemonName}} derrubou\no(a) {{itemName}} de {{targetName}}!", + "tookMoveAttack": "{{pokemonName}} pegou\no movimento {{moveName}}!", + "cutOwnHpAndMaximizedStat": "{{pokemonName}} reduziu seus PS\ne maximizou seu atributo de {{statName}}!", + "copiedStatChanges": "{{pokemonName}} copiou\nas mudanças de atributo de {{targetName}}!", + "magnitudeMessage": "Magnitude {{magnitude}}!", + "tookAimAtTarget": "{{pokemonName}} mirou\nem {{targetName}}!", + "transformedIntoType": "{{pokemonName}} se transformou\nem tipo {{typeName}}!", + "copiedMove": "{{pokemonName}} copiou\no movimento {{moveName}}!", + "sketchedMove": "{{pokemonName}} desenhou\no movimento {{moveName}}!", + "acquiredAbility": "{{pokemonName}} adquiriu\na habilidade {{abilityName}}!", + "copiedTargetAbility": "{{pokemonName}} copiou a habilidade\nde {{targetName}}!", + "transformedIntoTarget": "{{pokemonName}} se transformou\nem um(a) {{targetName}}!", + "tryingToTakeFoeDown": "{{pokemonName}} está tentando derrubar o atacante com ele!", + "addType": "{{pokemonName}} recebeu\no tipo {{typeName}}!", + "cannotUseMove": "{{pokemonName}} não pode usar {{moveName}}!", + "healHp": "{{pokemonName}} teve seus PS recuperados.", + "sacrificialFullRestore": "O Healing Wish de {{pokemonName}}\nfoi concedido!", + "invertStats": "As mudanças de atributo de {{pokemonName}}\nforam revertidas!", + "resetStats": "As mudanças de atributo de {{pokemonName}}\nforam eliminadas!", + "faintCountdown": "{{pokemonName}}\nirá desmaiar em {{turnCount}} turnos.", + "copyType": "O tipo de {{pokemonName}}\nmudou para combinar com {{targetPokemonName}}!", + "suppressAbilities": "A habilidade de {{pokemonName}}\nfoi suprimida!", + "swapArenaTags": "{{pokemonName}} trocou os efeitos de batalha que afetam cada lado do campo!", +} as const; diff --git a/src/locales/pt_BR/pokemon-form.ts b/src/locales/pt_BR/pokemon-form.ts index 04d362e7538..6c7c649862a 100644 --- a/src/locales/pt_BR/pokemon-form.ts +++ b/src/locales/pt_BR/pokemon-form.ts @@ -1,7 +1,6 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; -export const pokemonForm: SimpleTranslationEntries = { - // Battle forms +export const battlePokemonForm: SimpleTranslationEntries = { "mega": "Mega {{pokemonName}}", "mega-x": "Mega {{pokemonName}} X", "mega-y": "Mega {{pokemonName}} Y", @@ -9,6 +8,15 @@ export const pokemonForm: SimpleTranslationEntries = { "gigantamax": "G-Max {{pokemonName}}", "eternamax": "E-Max {{pokemonName}}", + "megaChange": "{{preName}} Mega Evoluiu\npara {{pokemonName}}!", + "gigantamaxChange": "{{preName}} Gigantamaxou\npara {{pokemonName}}!", + "eternamaxChange": "{{preName}} Eternamaxou\npara {{pokemonName}}!", + "revertChange": "{{pokemonName}} voltou\npara sua forma original!", + "formChange": "{{preName}} mudou de forma!", +} as const; + +export const pokemonForm: SimpleTranslationEntries = { + // Starters forms // 1G "pikachuCosplay": "Cosplay", diff --git a/src/locales/pt_BR/starter-select-ui-handler.ts b/src/locales/pt_BR/starter-select-ui-handler.ts index bec408f4550..660076da413 100644 --- a/src/locales/pt_BR/starter-select-ui-handler.ts +++ b/src/locales/pt_BR/starter-select-ui-handler.ts @@ -7,6 +7,7 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; */ export const starterSelectUiHandler: SimpleTranslationEntries = { "confirmStartTeam": "Começar com esses Pokémon?", + "confirmExit": "Deseja sair?", "invalidParty": "Essa equipe de iniciais não é válida!", "gen1": "G1", "gen2": "G2", @@ -23,6 +24,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "nature": "Natureza:", "eggMoves": "Mov. de Ovo", "addToParty": "Adicionar à equipe", + "removeFromParty": "Remover da Equipe", "toggleIVs": "Mostrar IVs", "manageMoves": "Mudar Movimentos", "manageNature": "Mudar Natureza", @@ -30,9 +32,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "selectNature": "Escolha uma natureza.", "selectMoveSwapOut": "Escolha um movimento para substituir.", "selectMoveSwapWith": "Escolha o movimento que substituirá", + "sameSpeciesEgg": "Comprar Ovo", "unlockPassive": "Aprender Passiva", "reduceCost": "Reduzir Custo", - "sameSpeciesEgg": "Comprar Ovo", "cycleShiny": ": » Shiny", "cycleForm": ": » Forma", "cycleGender": ": » Gênero", diff --git a/src/locales/pt_BR/trainers.ts b/src/locales/pt_BR/trainers.ts index 57fbe220412..32cc46300d5 100644 --- a/src/locales/pt_BR/trainers.ts +++ b/src/locales/pt_BR/trainers.ts @@ -127,16 +127,33 @@ export const trainerClasses: SimpleTranslationEntries = { "youngster": "Jovem", "rocket_grunt": "Recruta da Equipe Rocket", "rocket_grunt_female": "Recruta da Equipe Rocket", + "rocket_grunts": "Recrutas da Equipe Rocket", + "rocket_admin": "Rocket Admin", + "rocket_admin_female": "Rocket Admin", "magma_grunt": "Recruta da Equipe Magma", "magma_grunt_female": "Recruta da Equipe Magma", + "magma_grunts": "Recrutas da Equipe Magma", + "magma_admin": "Magma Admin", + "magma_admin_female": "Magma Admin", "aqua_grunt": "Recruta da Equipe Aqua", "aqua_grunt_female": "Recruta da Equipe Aqua", + "aqua_grunts": "Recrutas da Equipe Aqua", + "aqua_admin": "Aqua Admin", + "aqua_admin_female": "Aqua Admin", "galactic_grunt": "Recruta da Equipe Galáctica", "galactic_grunt_female": "Recruta da Equipe Galáctica", + "galactic_grunts": "Recrutas da Equipe Galáctica", + "galactic_admin": "Galactic Admin", + "galactic_admin_female": "Galactic Admin", "plasma_grunt": "Recruta da Equipe Plasma", "plasma_grunt_female": "Recruta da Equipe Plasma", + "plasma_grunts": "Recrutas da Equipe Plasma", + "plasma_sage": "Plasma Sage", "flare_grunt": "Recruta da Equipe Flare", "flare_grunt_female": "Recruta da Equipe Flare", + "flare_grunts": "Recrutas da Equipe Flare", + "flare_admin": "Flare Admin", + "flare_admin_female": "Flare Admin", } as const; // Names of special trainers like gym leaders, elite four, and the champion diff --git a/src/locales/zh_CN/ability-trigger.ts b/src/locales/zh_CN/ability-trigger.ts index 9cc1d94847b..0f2201049d2 100644 --- a/src/locales/zh_CN/ability-trigger.ts +++ b/src/locales/zh_CN/ability-trigger.ts @@ -36,7 +36,7 @@ export const abilityTriggers: SimpleTranslationEntries = { "forewarn": "{{pokemonNameWithAffix}}读取了\n{{moveName}}!", "frisk": "{{pokemonNameWithAffix}}察觉到了\n{{opponentName}}的{{opponentAbilityName}}!", "postWeatherLapseHeal": "{{pokemonNameWithAffix}}因{{abilityName}}\n回复了少许HP!", - "postWeatherLapseDamage": "{{pokemonNameWithAffix}}\n因{abilityName}}而受到了伤害!", + "postWeatherLapseDamage": "{{pokemonNameWithAffix}}\n因{{abilityName}}而受到了伤害!", "postTurnLootCreateEatenBerry": "{{pokemonNameWithAffix}}\n收获了{{berryName}}!", "postTurnHeal": "{{pokemonNameWithAffix}}因{{abilityName}}\n回复了少许HP!", "fetchBall": "{{pokemonNameWithAffix}}\n捡回了{{pokeballName}}!", @@ -59,4 +59,5 @@ export const abilityTriggers: SimpleTranslationEntries = { "postSummonSwordOfRuin": "{{pokemonNameWithAffix}}的灾祸之剑\n令周围的宝可梦的{{statName}}减弱了!", "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}的灾祸之简\n令周围的宝可梦的{{statName}}减弱了!", "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}的灾祸之玉\n令周围的宝可梦的{{statName}}减弱了!", + "preventBerryUse": "{{pokemonNameWithAffix}}因太紧张\n而无法食用树果!", } as const; diff --git a/src/locales/zh_CN/achv.ts b/src/locales/zh_CN/achv.ts index 486ff3cc02b..a32f244400d 100644 --- a/src/locales/zh_CN/achv.ts +++ b/src/locales/zh_CN/achv.ts @@ -172,43 +172,43 @@ export const PGMachv: AchievementTranslationEntries = { "MONO_GEN_ONE": { name: "最初的劲敌", - description: "完成仅限第一世代的挑战.", + description: "完成仅限第一世代的挑战", }, "MONO_GEN_TWO": { name: "1.5世代", - description: "完成仅限第二世代的挑战.", + description: "完成仅限第二世代的挑战", }, "MONO_GEN_THREE": { name: "“水太多了”", - description: "完成仅限第三世代的挑战.", + description: "完成仅限第三世代的挑战", }, "MONO_GEN_FOUR": { name: "她真是最强冠军吗?", - description: "完成仅限第四世代的挑战.", + description: "完成仅限第四世代的挑战", }, "MONO_GEN_FIVE": { name: "完全原创", - description: "完成仅限第五世代的挑战.", + description: "完成仅限第五世代的挑战", }, "MONO_GEN_SIX": { name: "女大公", - description: "完成仅限第六世代的挑战.", + description: "完成仅限第六世代的挑战", }, "MONO_GEN_SEVEN": { name: "首届冠军", - description: "完成仅限第七世代的挑战.", + description: "完成仅限第七世代的挑战", }, "MONO_GEN_EIGHT": { name: "冠军时刻!", - description: "完成仅限第八世代的挑战.", + description: "完成仅限第八世代的挑战", }, "MONO_GEN_NINE": { name: "她又放水了", - description: "完成仅限第九世代的挑战.", + description: "完成仅限第九世代的挑战", }, "MonoType": { - description: "完成 {{type}} 单属性挑战.", + description: "完成 {{type}} 单属性挑战", }, "MONO_NORMAL": { name: "异乎寻常的寻常", @@ -264,6 +264,10 @@ export const PGMachv: AchievementTranslationEntries = { "MONO_FAIRY": { name: "林克,醒醒!", }, + "FRESH_START": { + name: "初次尝试!", + description: "完成初次尝试挑战" + } } as const; // Achievement translations for the when the player character is female (it for now uses the same translations as the male version) diff --git a/src/locales/zh_CN/arena-tag.ts b/src/locales/zh_CN/arena-tag.ts new file mode 100644 index 00000000000..027a5667415 --- /dev/null +++ b/src/locales/zh_CN/arena-tag.ts @@ -0,0 +1,50 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const arenaTag: SimpleTranslationEntries = { + "yourTeam": "我方队伍", + "opposingTeam": "敌方队伍", + "arenaOnRemove": "{{moveName}}的效果消失了!", + "arenaOnRemovePlayer": "{{moveName}}在我方的效果消失了!", + "arenaOnRemoveEnemy": "{{moveName}}在敌方的效果消失了!", + "mistOnAdd": "{{pokemonNameWithAffix}}的一方被\n白雾包围了!", + "mistApply": "正受到白雾的保护\n能力不会被降低!", + "reflectOnAdd": "反射壁使\n物理抗性提高了!", + "reflectOnAddPlayer": "反射壁使我方的\n物理抗性提高了!", + "reflectOnAddEnemy": "反射壁使敌方的\n物理抗性提高了!", + "lightScreenOnAdd": "光墙使\n特殊抗性提高了!", + "lightScreenOnAddPlayer": "光墙使我方的\n特殊抗性提高了!", + "lightScreenOnAddEnemy": "光墙使敌方的\n特殊抗性提高了!", + "auroraVeilOnAdd": "极光幕使\n物理和特殊抗性提高了!", + "auroraVeilOnAddPlayer": "极光幕使我方的\n物理和特殊抗性提高了!", + "auroraVeilOnAddEnemy": "极光幕使敌方的\n物理和特殊抗性提高了!", + "conditionalProtectOnAdd": "{{moveName}}\n保护了!", + "conditionalProtectOnAddPlayer": "{{moveName}}\n保护了我方!", + "conditionalProtectOnAddEnemy": "{{moveName}}\n保护了敌方!", + "conditionalProtectApply": "{{moveName}}\n保护了{{pokemonNameWithAffix}}!", + "matBlockOnAdd": "{{pokemonNameWithAffix}}正在\n伺机使出掀榻榻米!", + "wishTagOnAdd": "{{pokemonNameWithAffix}}的\n祈愿实现了!", + "mudSportOnAdd": "电气的威力减弱了!", + "mudSportOnRemove": "玩泥巴的效果消失了!", + "waterSportOnAdd": "火焰的威力减弱了!", + "waterSportOnRemove": "玩水的效果消失了!", + "spikesOnAdd": "{{opponentDesc}}脚下\n散落着{{moveName}}!", + "spikesActivateTrap": "{{pokemonNameWithAffix}}\n受到了撒菱的伤害!", + "toxicSpikesOnAdd": "{{opponentDesc}}脚下\n散落着{{moveName}}!", + "toxicSpikesActivateTrapPoison": "{{pokemonNameWithAffix}}\n吸收了{{moveName}}!", + "stealthRockOnAdd": "{{opponentDesc}}周围\n开始浮现出尖锐的岩石!", + "stealthRockActivateTrap": "尖锐的岩石扎进了\n{{pokemonNameWithAffix}}的体内!", + "stickyWebOnAdd": "对方的脚下\n延伸出了{{moveName}}!", + "stickyWebActivateTrap": "{{pokemonName}}\n被黏黏网粘住了!", + "trickRoomOnAdd": "{{pokemonNameWithAffix}}\n扭曲了时空!", + "trickRoomOnRemove": "扭曲的时空复原了!", + "gravityOnAdd": "重力变强了!", + "gravityOnRemove": "重力复原了!", + "tailwindOnAdd": "从身后\n吹起了顺风!", + "tailwindOnAddPlayer": "从我方身后\n吹起了顺风!", + "tailwindOnAddEnemy": "从敌方身后\n吹起了顺风!", + "tailwindOnRemove": "顺风停止了!", + "tailwindOnRemovePlayer": "我方的顺风停止了!", + "tailwindOnRemoveEnemy": "敌方的顺风停止了!", + "happyHourOnAdd": "大家被欢乐的\n气氛包围了!", + "happyHourOnRemove": "气氛回复到平常了。", +} as const; diff --git a/src/locales/zh_CN/battle.ts b/src/locales/zh_CN/battle.ts index c3c9077b7f1..b07cb79e258 100644 --- a/src/locales/zh_CN/battle.ts +++ b/src/locales/zh_CN/battle.ts @@ -4,17 +4,17 @@ export const battle: SimpleTranslationEntries = { "bossAppeared": "{{bossName}} 出现了。", "trainerAppeared": "{{trainerName}}\n想要和你对战!", "trainerAppearedDouble": "{{trainerName}}\n想要和你对战!", - "trainerSendOut": "{{trainerName}}派出了\n{{pokemonName}}!", + "trainerSendOut": "{{trainerName}}派出了\n{{pokemonName}}!", "singleWildAppeared": "一只野生的{{pokemonName}}出现了!", "multiWildAppeared": "野生的{{pokemonName1}}\n和{{pokemonName2}}出现了!", - "playerComeBack": "回来吧,{{pokemonName}}!", + "playerComeBack": "回来吧,{{pokemonName}}!", "trainerComeBack": "{{trainerName}}收回了{{pokemonName}}!", "playerGo": "去吧!{{pokemonName}}!", "trainerGo": "{{trainerName}}派出了\n{{pokemonName}}!", "switchQuestion": "要更换\n{{pokemonName}}吗?", "trainerDefeated": "你击败了\n{{trainerName}}!", "moneyWon": "你赢得了\n₽{{moneyAmount}}!", - "moneyPickedUp": "捡到了 ₽{{moneyAmount}}!", + "moneyPickedUp": "捡到了₽{{moneyAmount}}!", "pokemonCaught": "{{pokemonName}}被抓住了!", "addedAsAStarter": "增加了{{pokemonName}}作为\n一个新的基础宝可梦!", "partyFull": "你的队伍已满员。是否放生其他宝可梦\n为{{pokemonName}}腾出空间?", @@ -29,9 +29,9 @@ export const battle: SimpleTranslationEntries = { "attackMissed": "没有命中{{pokemonNameWithAffix}}!", "attackHitsCount": "击中{{count}}次!", "rewardGain": "你获得了\n{{modifierName}}!", - "expGain": "{{pokemonName}}获得了 {{exp}} 点经验值!", - "levelUp": "{{pokemonName}}升级到 Lv.{{level}}!", - "learnMove": "{{pokemonName}} 学会了 {{moveName}}!", + "expGain": "{{pokemonName}}获得了{{exp}} 点经验值!", + "levelUp": "{{pokemonName}}升级到Lv.{{level}}!", + "learnMove": "{{pokemonName}}学会了{{moveName}}!", "learnMovePrompt": "{{pokemonName}}想要学习{{moveName}}。", "learnMoveLimitReached": "但是,{{pokemonName}}已经学会了\n四个技能", "learnMoveReplaceQuestion": "要忘记一个技能并学习{{moveName}}吗?", @@ -61,27 +61,27 @@ export const battle: SimpleTranslationEntries = { "hpIsFull": "{{pokemonName}}的体力已满!", "skipItemQuestion": "你确定要跳过拾取道具吗?", "eggHatching": "咦?", - "stealEatBerry": "{{pokemonName}} stole and ate\n{{targetName}}'s {{berryName}}!", + "stealEatBerry": "{{pokemonName}}夺取并吃掉了\n{{targetName}}的{{berryName}}!", "ppHealBerry": "{{pokemonNameWithAffix}}用{{berryName}}\n回复了{{moveName}}的PP!", "hpHealBerry": "{{pokemonNameWithAffix}}用{{berryName}}\n回复了体力!", "ivScannerUseQuestion": "对{{pokemonName}}使用个体值扫描仪?", "wildPokemonWithAffix": "野生的{{pokemonName}}", - "foePokemonWithAffix": "对手 {{pokemonName}}", + "foePokemonWithAffix": "对手的{{pokemonName}}", "useMove": "{{pokemonNameWithAffix}}使用了\n{{moveName}}!", "drainMessage": "{{pokemonName}}\n吸取了体力!", "regainHealth": "{{pokemonName}}\n回复了体力!", "fainted": "{{pokemonNameWithAffix}}\n倒下了!", - "statsAnd": "and", - "stats": "Stats", - "statRose_other": "{{pokemonNameWithAffix}}的 {{stats}}提高了!", - "statSharplyRose_other": "{{pokemonNameWithAffix}}的 {{stats}}大幅提高了!", - "statRoseDrastically_other": "{{pokemonNameWithAffix}}的 {{stats}}极大幅提高了!", - "statWontGoAnyHigher_other": "{{pokemonNameWithAffix}}的 {{stats}}已经无法再提高了!", - "statFell_other": "{{pokemonNameWithAffix}}的 {{stats}}降低了!", - "statHarshlyFell_other": "{{pokemonNameWithAffix}}的 {{stats}}大幅降低了!", - "statSeverelyFell_other": "{{pokemonNameWithAffix}}的 {{stats}}极大幅降低了!", - "statWontGoAnyLower_other": "{{pokemonNameWithAffix}}的 {{stats}}已经无法再降低了!", - "transformedIntoType": "{{pokemonName}} transformed\ninto the {{type}} type!", + "statsAnd": "和", + "stats": "能力", + "statRose_other": "{{pokemonNameWithAffix}}的{{stats}}提高了!", + "statSharplyRose_other": "{{pokemonNameWithAffix}}的{{stats}}大幅提高了!", + "statRoseDrastically_other": "{{pokemonNameWithAffix}}的{{stats}}极大幅提高了!", + "statWontGoAnyHigher_other": "{{pokemonNameWithAffix}}的{{stats}}已经无法再提高了!", + "statFell_other": "{{pokemonNameWithAffix}}的{{stats}}降低了!", + "statHarshlyFell_other": "{{pokemonNameWithAffix}}的{{stats}}大幅降低了!", + "statSeverelyFell_other": "{{pokemonNameWithAffix}}的{{stats}}极大幅降低了!", + "statWontGoAnyLower_other": "{{pokemonNameWithAffix}}的{{stats}}已经无法再降低了!", + "transformedIntoType": "{{pokemonName}}变成了\n{{type}}属性!", "ppReduced": "降低了{{targetName}}的\n{{moveName}}的PP{{reduction}}点!", "retryBattle": "你要从对战开始时重试么?", "unlockedSomething": "{{unlockedThing}}\n已解锁。", @@ -147,5 +147,5 @@ export const battle: SimpleTranslationEntries = { "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}}\n受到了{{moveName}}的伤害!", "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}削减了自己的体力,\n并诅咒了{{pokemonName}}!", "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}\n正受到诅咒!", - "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" + "battlerTagsStockpilingOnAdd": "{{pokemonNameWithAffix}}蓄力了{{stockpiledCount}}次!" } as const; diff --git a/src/locales/zh_CN/bgm-name.ts b/src/locales/zh_CN/bgm-name.ts index 71db565eb05..6039a259fd3 100644 --- a/src/locales/zh_CN/bgm-name.ts +++ b/src/locales/zh_CN/bgm-name.ts @@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = { "missing_entries" : "{{name}}", "battle_kanto_champion": "黑2白2「决战!关都冠军」", "battle_johto_champion": "黑2白2「决战!城都冠军」", - "battle_hoenn_champion": "黑2白2「决战!丰缘冠军」", + "battle_hoenn_champion_g5": "黑2白2「决战!丰缘冠军」", + "battle_hoenn_champion_g6": "Ω红宝石α蓝宝石「决战!丰缘冠军」", "battle_sinnoh_champion": "黑2白2「决战!神奥冠军」", "battle_champion_alder": "黑白「决战!合众冠军」", "battle_champion_iris": "黑2白2「决战!合众冠军」", diff --git a/src/locales/zh_CN/challenges.ts b/src/locales/zh_CN/challenges.ts index 4c1b523ef16..de14d2f6486 100644 --- a/src/locales/zh_CN/challenges.ts +++ b/src/locales/zh_CN/challenges.ts @@ -22,4 +22,10 @@ export const challenges: TranslationEntries = { "desc": "你只能使用{{type}}\n属性的宝可梦", "desc_default": "你只能使用所选\n属性的宝可梦" }, + "freshStart": { + "name": "初次尝试", + "desc": "你只能使用御三家,就像是你第一次玩宝可梦肉鸽一样。", + "value.0": "关闭", + "value.1": "开启", + }, } as const; diff --git a/src/locales/zh_CN/config.ts b/src/locales/zh_CN/config.ts index 84b74c1a20c..24c8b870ffa 100644 --- a/src/locales/zh_CN/config.ts +++ b/src/locales/zh_CN/config.ts @@ -1,6 +1,7 @@ import { ability } from "./ability"; import { abilityTriggers } from "./ability-trigger"; import { arenaFlyout } from "./arena-flyout"; +import { arenaTag } from "./arena-tag"; import { PGFachv, PGMachv } from "./achv"; import { battle } from "./battle"; import { battleInfo } from "./battle-info"; @@ -23,6 +24,7 @@ import { } from "./dialogue"; import { egg } from "./egg"; import { fightUiHandler } from "./fight-ui-handler"; +import { filterBar } from "./filter-bar"; import { gameMode } from "./game-mode"; import { gameStatsUiHandler } from "./game-stats-ui-handler"; import { growth } from "./growth"; @@ -34,7 +36,7 @@ import { move } from "./move"; import { nature } from "./nature"; import { pokeball } from "./pokeball"; import { pokemon } from "./pokemon"; -import { pokemonForm } from "./pokemon-form"; +import { pokemonForm, battlePokemonForm } from "./pokemon-form"; import { pokemonInfo } from "./pokemon-info"; import { pokemonInfoContainer } from "./pokemon-info-container"; import { pokemonSummary } from "./pokemon-summary"; @@ -50,14 +52,17 @@ import { partyUiHandler } from "./party-ui-handler"; import { settings } from "./settings.js"; import { common } from "./common.js"; import { modifierSelectUiHandler } from "./modifier-select-ui-handler"; +import { moveTriggers } from "./move-trigger"; export const zhCnConfig = { ability: ability, abilityTriggers: abilityTriggers, arenaFlyout: arenaFlyout, + arenaTag: arenaTag, battle: battle, battleInfo: battleInfo, battleMessageUiHandler: battleMessageUiHandler, + battlePokemonForm: battlePokemonForm, battlerTags: battlerTags, berry: berry, bgmName: bgmName, @@ -77,6 +82,7 @@ export const zhCnConfig = { PGFdoubleBattleDialogue: PGFdoubleBattleDialogue, egg: egg, fightUiHandler: fightUiHandler, + filterBar: filterBar, gameMode: gameMode, gameStatsUiHandler: gameStatsUiHandler, growth: growth, @@ -105,5 +111,6 @@ export const zhCnConfig = { voucher: voucher, weather: weather, partyUiHandler: partyUiHandler, - modifierSelectUiHandler: modifierSelectUiHandler + modifierSelectUiHandler: modifierSelectUiHandler, + moveTriggers: moveTriggers }; diff --git a/src/locales/zh_CN/dialogue.ts b/src/locales/zh_CN/dialogue.ts index 6afbcd71064..50d6c5f4333 100644 --- a/src/locales/zh_CN/dialogue.ts +++ b/src/locales/zh_CN/dialogue.ts @@ -390,6 +390,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "好讨厌的感觉啊!" }, }, + "rocket_admin": { + "encounter": { + 1: "Oh? You managed to get this far? You must be quite the trainer.", + 2: "That's quite enough of you playing hero, kid.", + 3: "I'll show you how scary an angry adult can be!" + }, + "victory": { + 1: "No! Forgive me Giovanni!", + 2: "How could this be?", + 3: "Urgh... You were too strong..." + }, + }, "magma_grunt": { "encounter": { 1: "如果你挡在熔岩队路上,那就别指望我们手下留情!" @@ -398,6 +410,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "哈?我输了?!" }, }, + "magma_admin": { + "encounter": { + 1: "Hehehe! So you've come all the way here! But you're too late!", + 2: "You're going to meddle in Team Magma's affairs? You're so cute you're disgusting! I'll put you down kiddy!", + 3: "I'm going to give you a little taste of pain! Resign yourself to it!" + }, + "victory": { + 1: "Hehehe... So I lost...", + 2: "You're disgustingly strong!", + 3: "Ahahaha! Ouch!" + }, + }, "aqua_grunt": { "encounter": { 1: "即使是小孩,如果要和海洋队作对,也别指望我们手下留情!" @@ -406,6 +430,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "你在开玩笑吧?" }, }, + "aqua_admin": { + "encounter": { + 1: "I'm a cut above the grunts you've seen so far. I'm going to puvlerize you!", + 2: "Hahn? What's this? Who's this spoiled brat?", + 3: "What are you doing here? Did you follow us?" + }, + "victory": { + 1: "So I lost too...", + 2: "Ahhh?! Did I go too easy on you?!", + 3: "Wh-what was that?" + }, + }, "galactic_grunt": { "encounter": { 1: "别惹银河队!" @@ -414,6 +450,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "停机了…" }, }, + "galactic_admin": { + "encounter": { + 1: "I'm one of Team Galactic's Commanders.", + 2: "Anything that opposes Team Galactic must be crushed! Even the very thought of opposition will not be tolerated!", + 3: "What's the matter? Don't tell me you're shaking?" + }, + "victory": { + 1: "This can't be?! I lost?! You... you uppity brat!", + 2: "You, my friend, are tough!", + 3: "Losing to some child... Being careless cost me too much." + }, + }, "plasma_grunt": { "encounter": { 1: "异端不共戴天!" @@ -422,6 +470,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "等离子子子子子子!" }, }, + "plasma_sage": { + "encounter": { + 1: "You could become a threat to Team Plasma, so we will eliminate you here!", + 2: "Oh, for crying out loud... I didn't expect to have to fight!", + 3: "You're an impressive Trainer to have made it this far." + }, + "victory": { + 1: "Ghetsis...", + 2: "It's bitter cold. I'm shivering. I'm suffering.", + 3: "Hmph. You're a smarter Trainer than I expected." + }, + }, "flare_grunt": { "encounter": { 1: "时尚最重要!" @@ -430,6 +490,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "未来一片黑暗啊…" }, }, + "flare_admin": { + "encounter": { + 1: "Ah ha ha! It would be my pleasure. Come on, little Trainer! Let's see what you've got!", + 2: "Hmm... You're more powerful than you look. I wonder how much energy there is inside you.", + 3: "I've been waiting for you! I need to do a little research on you! Come, let us begin!" + }, + "victory": { + 1: "You're quite strong. Oh yes-very strong, indeed.", + 2: "Ding-ding-ding! Yup, you did it! To the victor goes the spoils!", + 3: "Wonderful! Amazing! You have tremendous skill and bravery!" + }, + }, "rocket_boss_giovanni_1": { "encounter": { 1: "我不得不说,能来到这里,你的确很不简单!" diff --git a/src/locales/zh_CN/filter-bar.ts b/src/locales/zh_CN/filter-bar.ts new file mode 100644 index 00000000000..4ee38521a0a --- /dev/null +++ b/src/locales/zh_CN/filter-bar.ts @@ -0,0 +1,33 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const filterBar: SimpleTranslationEntries = { + "genFilter": "世代", + "typeFilter": "属性", + "caughtFilter": "捕获", + "unlocksFilter": "解锁", + "miscFilter": "混合", + "sortFilter": "排序", + "all": "全部", + "normal": "无闪光", + "uncaught": "未捕获", + "passive": "被动", + "passiveUnlocked": "被动解锁", + "passiveLocked": "被动未解锁", + "costReduction": "Cost Reduction", + "costReductionUnlocked": "Cost Reduction Unlocked", + "costReductionLocked": "Cost Reduction Locked", + "ribbon": "缎带", + "hasWon": "有缎带", + "hasNotWon": "无缎带", + "hiddenAbility": "Hidden Ability", + "hasHiddenAbility": "Hidden Ability - Yes", + "noHiddenAbility": "Hidden Ability - No", + "pokerus": "Pokerus", + "hasPokerus": "Pokerus - Yes", + "noPokerus": "Pokerus - No", + "sortByNumber": "编号", + "sortByCost": "费用", + "sortByCandies": "糖果", + "sortByIVs": "个体", + "sortByName": "名称", +}; diff --git a/src/locales/zh_CN/menu-ui-handler.ts b/src/locales/zh_CN/menu-ui-handler.ts index 461f5bb9956..e5ca6d977df 100644 --- a/src/locales/zh_CN/menu-ui-handler.ts +++ b/src/locales/zh_CN/menu-ui-handler.ts @@ -18,10 +18,10 @@ export const menuUiHandler: SimpleTranslationEntries = { "exportSlotSelect": "选择要导出的存档位。", "importData": "导入数据", "exportData": "导出数据", - "linkDiscord": "Link Discord", - "unlinkDiscord": "Unlink Discord", - "linkGoogle": "Link Google", - "unlinkGoogle": "Unlink Google", + "linkDiscord": "关联Discord", + "unlinkDiscord": "解除关联Discord", + "linkGoogle": "关联Google", + "unlinkGoogle": "解除关联Google", "cancel": "取消", "losingProgressionWarning": "你将失去自战斗开始以来的所有进度。\n是否继续?", "noEggs": "当前没有任何蛋\n正在孵化中!" diff --git a/src/locales/zh_CN/menu.ts b/src/locales/zh_CN/menu.ts index 4ff4ffc3128..332457c949f 100644 --- a/src/locales/zh_CN/menu.ts +++ b/src/locales/zh_CN/menu.ts @@ -17,7 +17,7 @@ export const menu: SimpleTranslationEntries = { "username": "用户名", "password": "密码", "login": "登录", - "Or use": "Or use", + "Or use": "或使用", "register": "注册", "emptyUsername": "用户名不能为空", "invalidLoginUsername": "输入的用户名无效", diff --git a/src/locales/zh_CN/modifier-type.ts b/src/locales/zh_CN/modifier-type.ts index fcdaf9e8d9f..71f5b21ba81 100644 --- a/src/locales/zh_CN/modifier-type.ts +++ b/src/locales/zh_CN/modifier-type.ts @@ -153,7 +153,7 @@ export const modifierType: ModifierTypeTranslationEntries = { "REVIVER_SEED": { name: "复活种子", description: "受到技能攻击伤害濒死时,\n恢复该宝可梦的HP至1/2。" }, - "WHITE_HERB": { name: "White Herb", description: "An item to be held by a Pokémon. It will restore any lowered stat in battle." }, + "WHITE_HERB": { name: "白色香草", description: "当携带它的宝可梦能力降低时,\n仅能回到之前的状态1次。" }, "ETHER": { name: "PP单项小补剂" }, "MAX_ETHER": { name: "PP单项全补剂" }, @@ -184,7 +184,7 @@ export const modifierType: ModifierTypeTranslationEntries = { "SOOTHE_BELL": { name: "安抚之铃" }, - "SCOPE_LENS": { name: "焦点镜", description: "能看见弱点的镜片。携带它的宝可梦的招式 会变得容易击中要害。" }, + "SCOPE_LENS": { name: "焦点镜", description: "能看见弱点的镜片。携带它的宝可梦的招式\n会变得容易击中要害。" }, "LEEK": { name: "大葱", description: "非常长且坚硬的茎。让大葱鸭携带后,\n招式会变得容易击中要害。" }, "EVIOLITE": { name: "进化奇石", description: "携带后,还能进化的宝可梦的\n防御和特防就会提高。" }, @@ -220,8 +220,8 @@ export const modifierType: ModifierTypeTranslationEntries = { "LEFTOVERS": { name: "吃剩的东西", description: "携带后,在每个回合结束时恢复\n最大HP的1/16。" }, "SHELL_BELL": { name: "贝壳之铃", description: "携带后,在攻击对方成功造成伤害时,\n携带者的HP会恢复其所造成伤害的1/8。" }, - "TOXIC_ORB": { name: "剧毒宝珠", description: "触碰后会放出毒的神奇宝珠。携带后,在战斗时会变成剧毒状态。" }, - "FLAME_ORB": { name: "火焰宝珠", description: "触碰后会放出热量的神奇宝珠。携带后,在战斗时会变成灼伤状态。" }, + "TOXIC_ORB": { name: "剧毒宝珠", description: "触碰后会放出毒的神奇宝珠。\n携带后,在战斗时会变成剧毒状态。" }, + "FLAME_ORB": { name: "火焰宝珠", description: "触碰后会放出热量的神奇宝珠。\n携带后,在战斗时会变成灼伤状态。" }, "BATON": { name: "接力棒", description: "允许在切换宝可梦时保留能力变化, 对陷阱\n同样生效。" }, @@ -247,10 +247,10 @@ export const modifierType: ModifierTypeTranslationEntries = { "ENEMY_FUSED_CHANCE": { name: "融合硬币", description: "增加1%野生融合宝可梦出现概率。" }, }, SpeciesBoosterItem: { - "LIGHT_BALL": { name: "电气球", description: "让皮卡丘携带后,攻击和特攻就会提高的神奇之球。" }, - "THICK_CLUB": { name: "粗骨头", description: "某种坚硬的骨头。让卡拉卡拉或嘎啦嘎啦携带后,攻击就会提高。" }, - "METAL_POWDER": { name: "金属粉", description: "让百变怪携带后,防御就会提高的神奇粉末。非常细腻坚硬。" }, - "QUICK_POWDER": { name: "速度粉", description: "让百变怪携带后,速度就会提高的神奇粉末。非常细腻坚硬。" } + "LIGHT_BALL": { name: "电气球", description: "让皮卡丘携带后,\n攻击和特攻就会提高的神奇之球。" }, + "THICK_CLUB": { name: "粗骨头", description: "某种坚硬的骨头。\n让卡拉卡拉或嘎啦嘎啦携带后,攻击就会提高。" }, + "METAL_POWDER": { name: "金属粉", description: "让百变怪携带后,防御就会提高的神奇粉末。\n非常细腻坚硬。" }, + "QUICK_POWDER": { name: "速度粉", description: "让百变怪携带后,速度就会提高的神奇粉末。\n非常细腻坚硬。" } }, TempBattleStatBoosterItem: { "x_attack": "力量强化", diff --git a/src/locales/zh_CN/modifier.ts b/src/locales/zh_CN/modifier.ts index 458931ed9b5..6900e99dfb6 100644 --- a/src/locales/zh_CN/modifier.ts +++ b/src/locales/zh_CN/modifier.ts @@ -5,9 +5,10 @@ export const modifier: SimpleTranslationEntries = { "turnHealApply": "{{pokemonNameWithAffix}}用{{typeName}}\n回复了体力!", "hitHealApply": "{{pokemonNameWithAffix}}用{{typeName}}\n回复了体力!", "pokemonInstantReviveApply": "{{pokemonNameWithAffix}}用{{typeName}}\n恢复了活力!", - "pokemonResetNegativeStatStageApply": "{{pokemonNameWithAffix}}'s lowered stats were restored\nby its {{typeName}}!", + "pokemonResetNegativeStatStageApply": "{{pokemonNameWithAffix}}降低的能力被{{typeName}}\n复原了!", "moneyInterestApply": "用{{typeName}}\n获得了 ₽{{moneyAmount}} 利息!", "turnHeldItemTransferApply": "{{pokemonNameWithAffix}}的{{itemName}}被\n{{pokemonName}}的{{typeName}}吸收了!", "contactHeldItemTransferApply": "{{pokemonNameWithAffix}}的{{itemName}}被\n{{pokemonName}}的{{typeName}}夺取了!", "enemyTurnHealApply": "{{pokemonNameWithAffix}}\n回复了一些体力!", + "bypassSpeedChanceApply": "{{pokemonName}}用了{{itemName}}后,行动变快了!", } as const; diff --git a/src/locales/zh_CN/move-trigger.ts b/src/locales/zh_CN/move-trigger.ts new file mode 100644 index 00000000000..0efe24f76f0 --- /dev/null +++ b/src/locales/zh_CN/move-trigger.ts @@ -0,0 +1,62 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const moveTriggers: SimpleTranslationEntries = { + "hitWithRecoil" : "{{pokemonName}}\n受到了反作用力造成的伤害!", + "cutHpPowerUpMove": "{{pokemonName}}\n削减了体力并提升了招式威力!", + "absorbedElectricity": "{{pokemonName}}\n吸收了电力!", + "switchedStatChanges": "{{pokemonName}}和对手互换了\n自己的能力变化!", + "goingAllOutForAttack": "{{pokemonName}}拿出全力了!", + "regainedHealth": "{{pokemonName}}的\n体力回复了!", + "keptGoingAndCrashed": "{{pokemonName}}因势头过猛\n而撞到了地面!", + "fled": "{{pokemonName}}\n逃走了!", + "cannotBeSwitchedOut": "{{pokemonName}}\n无法被收回!", + "swappedAbilitiesWithTarget": "{{pokemonName}}\n互换了各自的特性!", + "coinsScatteredEverywhere": "金币散落一地!", + "attackedByItem": "{{pokemonName}}被\n{{itemName}}袭击了!", + "whippedUpAWhirlwind": "{{pokemonName}}周围的\n空气产生了旋涡!", + "flewUpHigh": "{{pokemonName}}\n飞向了高空!", + "tookInSunlight": "{{pokemonName}}\n吸收了光!", + "dugAHole": "{{pokemonName}}\n钻入了地里!", + "loweredItsHead": "{{pokemonName}}\n把头缩了进去!", + "isGlowing": "强光包围了{{pokemonName}}\n!", + "bellChimed": "铃声响彻四周!", + "foresawAnAttack": "{{pokemonName}}\n预知了未来的攻击!", + "hidUnderwater": "{{pokemonName}}\n潜入了水中!", + "soothingAromaWaftedThroughArea": "怡人的香气扩散了开来!", + "sprangUp": "{{pokemonName}}\n高高地跳了起来!", + "choseDoomDesireAsDestiny": "{{pokemonName}}\n将破灭之愿托付给了未来!", + "vanishedInstantly": "{{pokemonName}}的身影\n瞬间消失了!", + "tookTargetIntoSky": "{{pokemonName}}将{{targetName}}\n带上了高空!", + "becameCloakedInFreezingLight": "{{pokemonName}}\n被冷光包围了!", + "becameCloakedInFreezingAir": "{{pokemonName}}\n被冰冻的空气包围了!", + "isChargingPower": "{{pokemonName}}\n正在积蓄力量!", + "burnedItselfOut": "{{pokemonName}}的火焰燃尽了!", + "startedHeatingUpBeak": "{{pokemonName}}\n开始给鸟嘴加热了!", + "isOverflowingWithSpacePower": "{{pokemonName}}身上\n溢出了宇宙之力!", + "usedUpAllElectricity": "{{pokemonName}}\n用尽电力了!", + "stoleItem": "{{pokemonName}}从{{targetName}}那里\n夺取了{{itemName}}!", + "incineratedItem": "{{pokemonName}}烧没了\n{{targetName}}的{{itemName}}!", + "knockedOffItem": "{{pokemonName}}拍落了\n{{targetName}}的{{itemName}}!", + "tookMoveAttack": "{{pokemonName}}\n受到了{{moveName}}的攻击!", + "cutOwnHpAndMaximizedStat": "{{pokemonName}}\n削减了体力并释放了全部{{statName}}!", + "copiedStatChanges": "{{pokemonName}}复制了\n{{targetName}}的能力变化!", + "magnitudeMessage": "震级{{magnitude}}!", + "tookAimAtTarget": "{{pokemonName}}将目标对准了\n{{targetName}}!", + "transformedIntoType": "{{pokemonName}} \n变成了{{typeName}}属性!", + "copiedMove": "{{pokemonName}}\n复制了{{moveName}}!", + "sketchedMove": "{{pokemonName}}\n对{{moveName}}进行了写生!", + "acquiredAbility": "{{pokemonName}}的特性\n变为{{abilityName}}了!", + "copiedTargetAbility": "{{pokemonName}}复制了\n{{targetName}}的{{abilityName}}!", + "transformedIntoTarget": "{{pokemonName}}\n变身成了{{targetName}}!", + "tryingToTakeFoeDown": "{{pokemonName}}\n想和对手同归于尽!", + "addType": "{{pokemonName}}\n增加了{{typeName}}属性!", + "cannotUseMove": "{{pokemonName}}\n无法使用{{moveName}}!", + "healHp": "{{pokemonName}}的\n体力回复了!", + "sacrificialFullRestore": "{{pokemonName}}的\n治愈之愿实现了!", + "invertStats": "{{pokemonName}}的\n能力变化颠倒过来了!", + "resetStats": "{{pokemonName}}的\n能力变化复原了!", + "faintCountdown": "{{pokemonName}}\n将在{{turnCount}}回合后灭亡!", + "copyType": "{{pokemonName}}\n变成了{{targetPokemonName}}的属性!", + "suppressAbilities": "{{pokemonName}}的特性\n变得无效了!", + "swapArenaTags": "{{pokemonName}}\n交换了双方的场地效果!", +} as const; diff --git a/src/locales/zh_CN/pokemon-form.ts b/src/locales/zh_CN/pokemon-form.ts index b8135cc78f1..8fb82712e64 100644 --- a/src/locales/zh_CN/pokemon-form.ts +++ b/src/locales/zh_CN/pokemon-form.ts @@ -1,14 +1,21 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; -export const pokemonForm: SimpleTranslationEntries = { - // Battle forms +export const battlePokemonForm: SimpleTranslationEntries = { "mega": "Mega {{pokemonName}}", "mega-x": "Mega {{pokemonName}} X", "mega-y": "Mega {{pokemonName}} Y", - "primal": "原始回归{{pokemonName}}", + "primal": "原始{{pokemonName}}", "gigantamax": "超极巨{{pokemonName}}", "eternamax": "无极巨{{pokemonName}}", + "megaChange": "{{preName}}超级进化成了\n{{pokemonName}}!", + "gigantamaxChange": "{{preName}}超极巨化成了\n{{pokemonName}}!", + "eternamaxChange": "{{preName}}无极巨化成了\n{{pokemonName}}!", + "revertChange": "{{pokemonName}}变回了\n原本的样子!", + "formChange": "{{preName}}变成其他样子了。", +} as const; + +export const pokemonForm: SimpleTranslationEntries = { // Starters forms // 1G "pikachuCosplay": "服装", @@ -53,7 +60,7 @@ export const pokemonForm: SimpleTranslationEntries = { "castformSunny": "晴天", "castformRainy": "雨天", "castformSnowy": "雪天", - "deoxysNormal": "Normal", + "deoxysNormal": "普通", // 4G "burmyPlant": "草木蓑衣", "burmySandy": "砂土蓑衣", @@ -65,8 +72,8 @@ export const pokemonForm: SimpleTranslationEntries = { "rotomFrost": "结冰", "rotomFan": "旋转", "rotomMow": "切割", - "giratinaAltered": "Altered", - "shayminLand": "Land", + "giratinaAltered": "别种", + "shayminLand": "陆上", // 5G "basculinRedStriped": "红条纹", "basculinBlueStriped": "蓝条纹", @@ -75,11 +82,11 @@ export const pokemonForm: SimpleTranslationEntries = { "deerlingSummer": "夏天", "deerlingAutumn": "秋天", "deerlingWinter": "冬天", - "tornadusIncarnate": "Incarnate", - "thundurusIncarnate": "Incarnate", - "landorusIncarnate": "Incarnate", - "keldeoOrdinary": "Ordinary", - "meloettaAria": "Aria", + "tornadusIncarnate": "化身", + "thundurusIncarnate": "化身", + "landorusIncarnate": "化身", + "keldeoOrdinary": "通常", + "meloettaAria": "歌声", // 6G "froakieBattleBond": "牵绊变身", "scatterbugMeadow": "花园花纹", @@ -156,11 +163,11 @@ export const pokemonForm: SimpleTranslationEntries = { "eiscueNoIce": "解冻头", "indeedeeMale": "雄性", "indeedeeFemale": "雌性", - "morpekoFullBelly": "Full Belly", - "zacianHeroOfManyBattles": "Hero Of Many Battles", - "zamazentaHeroOfManyBattles": "Hero Of Many Battles", + "morpekoFullBelly": "满腹花纹", + "zacianHeroOfManyBattles": "百战勇者", + "zamazentaHeroOfManyBattles": "百战勇者", "zarudeDada": "老爹", - "enamorusIncarnate": "Incarnate", + "enamorusIncarnate": "化身", // 9G "squawkabillyGreenPlumage": "绿羽毛", "squawkabillyBluePlumage": "蓝羽毛", @@ -171,16 +178,16 @@ export const pokemonForm: SimpleTranslationEntries = { "tatsugiriStretchy": "平挺姿势", "gimmighoulChest": "宝箱形态", "gimmighoulRoaming": "徒步形态", - "koraidonApexBuild": "Apex Build", - "koraidonLimitedBuild":"Limited Build", - "koraidonSprintingBuild":"Sprinting Build", - "koraidonSwimmingBuild":"Swimming Build", - "koraidonGlidingBuild":"Gliding Build", - "miraidonUltimateMode":"Ultimate Mode", - "miraidonLowPowerMode":"Low Power Mode", - "miraidonDriveMode":"Drive Mode", - "miraidonAquaticMode":"Aquatic Mode", - "miraidonGlideMode":"Glide Mode", + "koraidonApexBuild": "顶尖形态", + "koraidonLimitedBuild":"限制形态", + "koraidonSprintingBuild":"冲刺形态", + "koraidonSwimmingBuild":"游泳形态", + "koraidonGlidingBuild":"滑翔形态", + "miraidonUltimateMode":"极限模式", + "miraidonLowPowerMode":"节能模式", + "miraidonDriveMode":"驾驶模式", + "miraidonAquaticMode":"水上模式", + "miraidonGlideMode":"滑翔模式", "poltchageistCounterfeit": "冒牌货", "poltchageistArtisan": "高档货", "paldeaTaurosCombat": "斗战种", diff --git a/src/locales/zh_CN/starter-select-ui-handler.ts b/src/locales/zh_CN/starter-select-ui-handler.ts index c23ceb66eb0..b8c491288e1 100644 --- a/src/locales/zh_CN/starter-select-ui-handler.ts +++ b/src/locales/zh_CN/starter-select-ui-handler.ts @@ -7,7 +7,8 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; */ export const starterSelectUiHandler: SimpleTranslationEntries = { "confirmStartTeam": "使用这些宝可梦开始游戏吗?", - "invalidParty": "This is not a valid starting party!", + "confirmExit": "Do you want to exit?", + "invalidParty": "初始队伍不可用!", "gen1": "I", "gen2": "II", "gen3": "III", @@ -23,6 +24,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "nature": "性格:", "eggMoves": "蛋招式", "addToParty": "加入队伍", + "removeFromParty": "移出队伍", "toggleIVs": "显示个体", "manageMoves": "管理招式", "manageNature": "管理性格", @@ -30,9 +32,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "selectNature": "选择性格", "selectMoveSwapOut": "选择要替换的招式。", "selectMoveSwapWith": "选择要替换成的招式", + "sameSpeciesEgg": "兑换一颗蛋", "unlockPassive": "解锁被动", "reduceCost": "降低花费", - "sameSpeciesEgg": "兑换一颗蛋", "cycleShiny": ": 闪光", "cycleForm": ": 形态", "cycleGender": ": 性别", diff --git a/src/locales/zh_CN/trainers.ts b/src/locales/zh_CN/trainers.ts index 534685d05d1..1d32fdf6e02 100644 --- a/src/locales/zh_CN/trainers.ts +++ b/src/locales/zh_CN/trainers.ts @@ -127,16 +127,33 @@ export const trainerClasses: SimpleTranslationEntries = { "youngster": "短裤小子", "rocket_grunt": "火箭队手下", "rocket_grunt_female": "火箭队手下", + "rocket_grunts": "火箭队手下们", + "rocket_admin": "Rocket Admin", + "rocket_admin_female": "Rocket Admin", "magma_grunt": "熔岩队手下", "magma_grunt_female": "熔岩队手下", + "magma_grunts": "熔岩队手下们", + "magma_admin": "Magma Admin", + "magma_admin_female": "Magma Admin", "aqua_grunt": "海洋队手下", "aqua_grunt_female": "海洋队手下", + "aqua_grunts": "海洋队手下们", + "aqua_admin": "Aqua Admin", + "aqua_admin_female": "Aqua Admin", "galactic_grunt": "银河队手下", "galactic_grunt_female": "银河队手下", + "galactic_grunts": "银河队手下们", + "galactic_admin": "Galactic Admin", + "galactic_admin_female": "Galactic Admin", "plasma_grunt": "等离子队手下", "plasma_grunt_female": "等离子队手下", + "plasma_grunts": "等离子队手下们", + "plasma_sage": "Plasma Sage", "flare_grunt": "闪焰队手下", "flare_grunt_female": "闪焰队手下", + "flare_grunts": "闪焰队手下们", + "flare_admin": "Flare Admin", + "flare_admin_female": "Flare Admin", } as const; // Names of special trainers like gym leaders, elite four, and the champion diff --git a/src/locales/zh_TW/ability-trigger.ts b/src/locales/zh_TW/ability-trigger.ts index c0b253933ca..baa20614a44 100644 --- a/src/locales/zh_TW/ability-trigger.ts +++ b/src/locales/zh_TW/ability-trigger.ts @@ -59,4 +59,5 @@ export const abilityTriggers: SimpleTranslationEntries = { "postSummonSwordOfRuin": "{{pokemonNameWithAffix}}'s Sword of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}'s Tablets of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}'s Beads of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", + "preventBerryUse": "{{pokemonNameWithAffix}}因太緊張\n而無法食用樹果!", } as const; diff --git a/src/locales/zh_TW/arena-tag.ts b/src/locales/zh_TW/arena-tag.ts new file mode 100644 index 00000000000..8bc2302368a --- /dev/null +++ b/src/locales/zh_TW/arena-tag.ts @@ -0,0 +1,50 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const arenaTag: SimpleTranslationEntries = { + "yourTeam": "your team", + "opposingTeam": "the opposing team", + "arenaOnRemove": "{{moveName}}'s effect wore off.", + "arenaOnRemovePlayer": "{{moveName}}'s effect wore off\non your side.", + "arenaOnRemoveEnemy": "{{moveName}}'s effect wore off\non the foe's side.", + "mistOnAdd": "{{pokemonNameWithAffix}}'s team became\nshrouded in mist!", + "mistApply": "The mist prevented\nthe lowering of stats!", + "reflectOnAdd": "Reflect reduced the damage of physical moves.", + "reflectOnAddPlayer": "Reflect reduced the damage of physical moves on your side.", + "reflectOnAddEnemy": "Reflect reduced the damage of physical moves on the foe's side.", + "lightScreenOnAdd": "Light Screen reduced the damage of special moves.", + "lightScreenOnAddPlayer": "Light Screen reduced the damage of special moves on your side.", + "lightScreenOnAddEnemy": "Light Screen reduced the damage of special moves on the foe's side.", + "auroraVeilOnAdd": "Aurora Veil reduced the damage of moves.", + "auroraVeilOnAddPlayer": "Aurora Veil reduced the damage of moves on your side.", + "auroraVeilOnAddEnemy": "Aurora Veil reduced the damage of moves on the foe's side.", + "conditionalProtectOnAdd": "{{moveName}} protected team!", + "conditionalProtectOnAddPlayer": "{{moveName}} protected your team!", + "conditionalProtectOnAddEnemy": "{{moveName}} protected the\nopposing team!", + "conditionalProtectApply": "{{moveName}} protected {{pokemonNameWithAffix}}!", + "matBlockOnAdd": "{{pokemonNameWithAffix}} intends to flip up a mat\nand block incoming attacks!", + "wishTagOnAdd": "{{pokemonNameWithAffix}}'s wish\ncame true!", + "mudSportOnAdd": "Electricity's power was weakened!", + "mudSportOnRemove": "The effects of Mud Sport\nhave faded.", + "waterSportOnAdd": "Fire's power was weakened!", + "waterSportOnRemove": "The effects of Water Sport\nhave faded.", + "spikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!", + "spikesActivateTrap": "{{pokemonNameWithAffix}} is hurt\nby the spikes!", + "toxicSpikesOnAdd": "{{moveName}} were scattered\nall around {{opponentDesc}}'s feet!", + "toxicSpikesActivateTrapPoison": "{{pokemonNameWithAffix}} absorbed the {{moveName}}!", + "stealthRockOnAdd": "Pointed stones float in the air\naround {{opponentDesc}}!", + "stealthRockActivateTrap": "Pointed stones dug into\n{{pokemonNameWithAffix}}!", + "stickyWebOnAdd": "A {{moveName}} has been laid out on the ground around the opposing team!", + "stickyWebActivateTrap": "The opposing {{pokemonName}} was caught in a sticky web!", + "trickRoomOnAdd": "{{pokemonNameWithAffix}} twisted\nthe dimensions!", + "trickRoomOnRemove": "The twisted dimensions\nreturned to normal!", + "gravityOnAdd": "Gravity intensified!", + "gravityOnRemove": "Gravity returned to normal!", + "tailwindOnAdd": "The Tailwind blew from behind team!", + "tailwindOnAddPlayer": "The Tailwind blew from behind\nyour team!", + "tailwindOnAddEnemy": "The Tailwind blew from behind\nthe opposing team!", + "tailwindOnRemove": "Team's Tailwind petered out!", + "tailwindOnRemovePlayer": "Your team's Tailwind petered out!", + "tailwindOnRemoveEnemy": "The opposing team's Tailwind petered out!", + "happyHourOnAdd": "Everyone is caught up in the happy atmosphere!", + "happyHourOnRemove": "The atmosphere returned to normal.", +} as const; diff --git a/src/locales/zh_TW/bgm-name.ts b/src/locales/zh_TW/bgm-name.ts index 01fb86b281d..be9a8f621c7 100644 --- a/src/locales/zh_TW/bgm-name.ts +++ b/src/locales/zh_TW/bgm-name.ts @@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = { "missing_entries" : "{{name}}", "battle_kanto_champion": "B2W2 Kanto Champion Battle", "battle_johto_champion": "B2W2 Johto Champion Battle", - "battle_hoenn_champion": "B2W2 Hoenn Champion Battle", + "battle_hoenn_champion_g5": "B2W2 Hoenn Champion Battle", + "battle_hoenn_champion_g6": "ORAS Hoenn Champion Battle", "battle_sinnoh_champion": "B2W2 Sinnoh Champion Battle", "battle_champion_alder": "BW Unova Champion Battle", "battle_champion_iris": "B2W2 Unova Champion Battle", diff --git a/src/locales/zh_TW/config.ts b/src/locales/zh_TW/config.ts index 63887a1f3e3..004ed1da1ab 100644 --- a/src/locales/zh_TW/config.ts +++ b/src/locales/zh_TW/config.ts @@ -1,6 +1,7 @@ import { ability } from "./ability"; import { abilityTriggers } from "./ability-trigger"; import { arenaFlyout } from "./arena-flyout"; +import { arenaTag } from "./arena-tag"; import { PGFachv, PGMachv } from "./achv"; import { battle } from "./battle"; import { battleInfo } from "./battle-info"; @@ -23,6 +24,7 @@ import { } from "./dialogue"; import { egg } from "./egg"; import { fightUiHandler } from "./fight-ui-handler"; +import { filterBar } from "./filter-bar"; import { gameMode } from "./game-mode"; import { gameStatsUiHandler } from "./game-stats-ui-handler"; import { growth } from "./growth"; @@ -34,7 +36,7 @@ import { move } from "./move"; import { nature } from "./nature"; import { pokeball } from "./pokeball"; import { pokemon } from "./pokemon"; -import { pokemonForm } from "./pokemon-form"; +import { pokemonForm, battlePokemonForm } from "./pokemon-form"; import { pokemonInfo } from "./pokemon-info"; import { pokemonInfoContainer } from "./pokemon-info-container"; import { pokemonSummary } from "./pokemon-summary"; @@ -50,14 +52,17 @@ import { partyUiHandler } from "./party-ui-handler"; import { settings } from "./settings.js"; import { common } from "./common.js"; import { modifierSelectUiHandler } from "./modifier-select-ui-handler"; +import { moveTriggers } from "./move-trigger"; export const zhTwConfig = { ability: ability, abilityTriggers: abilityTriggers, arenaFlyout: arenaFlyout, + arenaTag: arenaTag, battle: battle, battleInfo: battleInfo, battleMessageUiHandler: battleMessageUiHandler, + battlePokemonForm: battlePokemonForm, battlerTags: battlerTags, berry: berry, bgmName: bgmName, @@ -77,6 +82,7 @@ export const zhTwConfig = { PGFdoubleBattleDialogue: PGFdoubleBattleDialogue, egg: egg, fightUiHandler: fightUiHandler, + filterBar: filterBar, gameMode: gameMode, gameStatsUiHandler: gameStatsUiHandler, growth: growth, @@ -105,5 +111,6 @@ export const zhTwConfig = { voucher: voucher, weather: weather, partyUiHandler: partyUiHandler, - modifierSelectUiHandler: modifierSelectUiHandler + modifierSelectUiHandler: modifierSelectUiHandler, + moveTriggers: moveTriggers }; diff --git a/src/locales/zh_TW/dialogue.ts b/src/locales/zh_TW/dialogue.ts index 0823236bc84..530906eda5b 100644 --- a/src/locales/zh_TW/dialogue.ts +++ b/src/locales/zh_TW/dialogue.ts @@ -390,6 +390,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Team Rocket blasting off again!" }, }, + "rocket_admin": { + "encounter": { + 1: "Oh? You managed to get this far? You must be quite the trainer.", + 2: "That's quite enough of you playing hero, kid.", + 3: "I'll show you how scary an angry adult can be!" + }, + "victory": { + 1: "No! Forgive me Giovanni!", + 2: "How could this be?", + 3: "Urgh... You were too strong..." + }, + }, "magma_grunt": { "encounter": { 1: " If you get in the way of Team Magma, don’t expect any mercy!" @@ -398,6 +410,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Huh? I lost?!" }, }, + "magma_admin": { + "encounter": { + 1: "Hehehe! So you've come all the way here! But you're too late!", + 2: "You're going to meddle in Team Magma's affairs? You're so cute you're disgusting! I'll put you down kiddy!", + 3: "I'm going to give you a little taste of pain! Resign yourself to it!" + }, + "victory": { + 1: "Hehehe... So I lost...", + 2: "You're disgustingly strong!", + 3: "Ahahaha! Ouch!" + }, + }, "aqua_grunt": { "encounter": { 1: "No one who crosses Team Aqua gets any mercy, not even kids!" @@ -406,6 +430,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "You're kidding me!" }, }, + "aqua_admin": { + "encounter": { + 1: "I'm a cut above the grunts you've seen so far. I'm going to puvlerize you!", + 2: "Hahn? What's this? Who's this spoiled brat?", + 3: "What are you doing here? Did you follow us?" + }, + "victory": { + 1: "So I lost too...", + 2: "Ahhh?! Did I go too easy on you?!", + 3: "Wh-what was that?" + }, + }, "galactic_grunt": { "encounter": { 1: "Don't mess with Team Galactic!" @@ -414,6 +450,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Shut down..." }, }, + "galactic_admin": { + "encounter": { + 1: "I'm one of Team Galactic's Commanders.", + 2: "Anything that opposes Team Galactic must be crushed! Even the very thought of opposition will not be tolerated!", + 3: "What's the matter? Don't tell me you're shaking?" + }, + "victory": { + 1: "This can't be?! I lost?! You... you uppity brat!", + 2: "You, my friend, are tough!", + 3: "Losing to some child... Being careless cost me too much." + }, + }, "plasma_grunt": { "encounter": { 1: "We won't tolerate people who have different ideas!" @@ -422,6 +470,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Plasmaaaaaaaaa!" }, }, + "plasma_sage": { + "encounter": { + 1: "You could become a threat to Team Plasma, so we will eliminate you here!", + 2: "Oh, for crying out loud... I didn't expect to have to fight!", + 3: "You're an impressive Trainer to have made it this far." + }, + "victory": { + 1: "Ghetsis...", + 2: "It's bitter cold. I'm shivering. I'm suffering.", + 3: "Hmph. You're a smarter Trainer than I expected." + }, + }, "flare_grunt": { "encounter": { 1: "Fashion is most important to us!" @@ -430,6 +490,18 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "The future doesn't look bright for me." }, }, + "flare_admin": { + "encounter": { + 1: "Ah ha ha! It would be my pleasure. Come on, little Trainer! Let's see what you've got!", + 2: "Hmm... You're more powerful than you look. I wonder how much energy there is inside you.", + 3: "I've been waiting for you! I need to do a little research on you! Come, let us begin!" + }, + "victory": { + 1: "You're quite strong. Oh yes-very strong, indeed.", + 2: "Ding-ding-ding! Yup, you did it! To the victor goes the spoils!", + 3: "Wonderful! Amazing! You have tremendous skill and bravery!" + }, + }, "rocket_boss_giovanni_1": { "encounter": { 1: "So! I must say, I am impressed you got here!" diff --git a/src/locales/zh_TW/filter-bar.ts b/src/locales/zh_TW/filter-bar.ts new file mode 100644 index 00000000000..8916088d884 --- /dev/null +++ b/src/locales/zh_TW/filter-bar.ts @@ -0,0 +1,33 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const filterBar: SimpleTranslationEntries = { + "genFilter": "世代", + "typeFilter": "屬性", + "caughtFilter": "捕獲", + "unlocksFilter": "解鎖", + "miscFilter": "混合", + "sortFilter": "排序", + "all": "全部", + "normal": "通常", + "uncaught": "未捕獲", + "passive": "被動", + "passiveUnlocked": "被動解鎖", + "passiveLocked": "被動未解鎖", + "costReduction": "Cost Reduction", + "costReductionUnlocked": "Cost Reduction Unlocked", + "costReductionLocked": "Cost Reduction Locked", + "ribbon": "緞帶", + "hasWon": "有緞帶", + "hasNotWon": "無緞帶", + "hiddenAbility": "Hidden Ability", + "hasHiddenAbility": "Hidden Ability - Yes", + "noHiddenAbility": "Hidden Ability - No", + "pokerus": "Pokerus", + "hasPokerus": "Pokerus - Yes", + "noPokerus": "Pokerus - No", + "sortByNumber": "編號", + "sortByCost": "花費", + "sortByCandies": "糖果", + "sortByIVs": "個體值", + "sortByName": "名稱", +}; diff --git a/src/locales/zh_TW/modifier.ts b/src/locales/zh_TW/modifier.ts index 5174ae68362..7909e8150a0 100644 --- a/src/locales/zh_TW/modifier.ts +++ b/src/locales/zh_TW/modifier.ts @@ -10,4 +10,5 @@ export const modifier: SimpleTranslationEntries = { "turnHeldItemTransferApply": "{{pokemonNameWithAffix}}的{{itemName}}被\n{{pokemonName}}的{{typeName}}吸收了!", "contactHeldItemTransferApply": "{{pokemonNameWithAffix}}的{{itemName}}被\n{{pokemonName}}的{{typeName}}奪取了!", "enemyTurnHealApply": "{{pokemonNameWithAffix}}\n回復了一些體力!", + "bypassSpeedChanceApply": "{{pokemonName}}用了{{itemName}}後,行動變快了!", } as const; diff --git a/src/locales/zh_TW/move-trigger.ts b/src/locales/zh_TW/move-trigger.ts new file mode 100644 index 00000000000..019aa84390c --- /dev/null +++ b/src/locales/zh_TW/move-trigger.ts @@ -0,0 +1,62 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const moveTriggers: SimpleTranslationEntries = { + "hitWithRecoil" : "{{pokemonName}}\n受到了反作用力造成的傷害!", + "cutHpPowerUpMove": "{{pokemonName}}\n削減體力並提升了招式威力!", + "absorbedElectricity": "{{pokemonName}}\n吸收了电力!", + "switchedStatChanges": "{{pokemonName}}和對手互換了\n自身的能力變化!", + "goingAllOutForAttack": "{{pokemonName}}拿出全力了!", + "regainedHealth": "{{pokemonName}}的\n體力回復了!", + "keptGoingAndCrashed": "{{pokemonName}}因勢頭過猛\n而撞到了地面!", + "fled": "{{pokemonName}}\n逃走了!", + "cannotBeSwitchedOut": "{{pokemonName}}\n無法被收回!", + "swappedAbilitiesWithTarget": "{{pokemonName}}\n互換了各自的特性!", + "coinsScatteredEverywhere": "金幣散落一地!", + "attackedByItem": "{{pokemonName}}被\n{{itemName}}襲擊了!", + "whippedUpAWhirlwind": "{{pokemonName}}周圍的\n空氣產生了旋渦!", + "flewUpHigh": "{{pokemonName}}\n飛向了高空!", + "tookInSunlight": "{{pokemonName}}\n吸收了光線!", + "dugAHole": "{{pokemonName}}\n鑽進了地下!", + "loweredItsHead": "{{pokemonName}}\n把頭縮了進去!", + "isGlowing": "強光包圍了\n{{pokemonName}}!", + "bellChimed": "鈴聲響徹四周!", + "foresawAnAttack": "{{pokemonName}}\n預知了未來的攻擊!", + "hidUnderwater": "{{pokemonName}}\n潛入了水中!", + "soothingAromaWaftedThroughArea": "怡人的香氣擴散了開來!", + "sprangUp": "{{pokemonName}}\n高高地跳了起來!", + "choseDoomDesireAsDestiny": "{{pokemonName}}\n將破滅之願託付給了未來!", + "vanishedInstantly": "{{pokemonName}}的身影\n瞬間消失了!", + "tookTargetIntoSky": "{{pokemonName}}將{{targetName}}\n帶上了高空!", + "becameCloakedInFreezingLight": "{{pokemonName}}\n被冷光包圍了!", + "becameCloakedInFreezingAir": "{{pokemonName}}\n被冰凍的空氣包圍了!", + "isChargingPower": "{{pokemonName}}\n正在積蓄力量!", + "burnedItselfOut": "{{pokemonName}}的火焰燃盡了!", + "startedHeatingUpBeak": "{{pokemonName}}\n開始給鳥嘴加熱了!", + "isOverflowingWithSpacePower": "{{pokemonName}}湧起了宇宙的力量!", + "usedUpAllElectricity": "{{pokemonName}}\n用盡了電力!", + "stoleItem": "{{pokemonName}}从{{targetName}}那裏\n奪取了{{itemName}}!", + "incineratedItem": "{{pokemonName}}燒掉了\n{{targetName}}的{{itemName}}!", + "knockedOffItem": "{{pokemonName}}拍落了\n{{targetName}}的{{itemName}}!", + "tookMoveAttack": "{{pokemonName}}\n受到了{{moveName}}的攻擊!", + "cutOwnHpAndMaximizedStat": "{{pokemonName}}\n削減體力並釋放了全部{{statName}}!", + "copiedStatChanges": "{{pokemonName}}複製了\n{{targetName}}的能力變化!", + "magnitudeMessage": "震級{{magnitude}}!", + "tookAimAtTarget": "{{pokemonName}}將目標對準了\n{{targetName}}!", + "transformedIntoType": "{{pokemonName}} \n變成了{{typeName}}屬性!", + "copiedMove": "{{pokemonName}}\n複製了{{moveName}}!", + "sketchedMove": "{{pokemonName}}\n對{{moveName}}進行了寫生!", + "acquiredAbility": "{{pokemonName}}的特性\n變为{{abilityName}}了!", + "copiedTargetAbility": "{{pokemonName}}複製了\n{{targetName}}的{{abilityName}}!", + "transformedIntoTarget": "{{pokemonName}}\n變身成了{{targetName}}!", + "tryingToTakeFoeDown": "{{pokemonName}}\n想和對手同歸於盡!", + "addType": "{{pokemonName}}\n增加了{{typeName}}屬性!", + "cannotUseMove": "{{pokemonName}}\n無法使用{{moveName}}!", + "healHp": "{{pokemonName}}的\n體力回復了!", + "sacrificialFullRestore": "{{pokemonName}}的\n治癒之願實現了!", + "invertStats": "{{pokemonName}}的\n能力變化顛倒過來了!", + "resetStats": "{{pokemonName}}的\n能力變化復原了!", + "faintCountdown": "{{pokemonName}}\n將在{{turnCount}}回合後滅亡!", + "copyType": "{{pokemonName}}變成了{{targetPokemonName}}的屬性!", + "suppressAbilities": "{{pokemonName}}的特性\n變得無效了!", + "swapArenaTags": "{{pokemonName}}\n交換了雙方的場地效果!", +} as const; diff --git a/src/locales/zh_TW/pokemon-form.ts b/src/locales/zh_TW/pokemon-form.ts index 2ab936b36da..aa30840fcc0 100644 --- a/src/locales/zh_TW/pokemon-form.ts +++ b/src/locales/zh_TW/pokemon-form.ts @@ -1,7 +1,6 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; -export const pokemonForm: SimpleTranslationEntries = { - // Battle forms +export const battlePokemonForm: SimpleTranslationEntries = { "mega": "Mega {{pokemonName}}", "mega-x": "Mega {{pokemonName}} X", "mega-y": "Mega {{pokemonName}} Y", @@ -9,6 +8,14 @@ export const pokemonForm: SimpleTranslationEntries = { "gigantamax": "G-Max {{pokemonName}}", "eternamax": "E-Max {{pokemonName}}", + "megaChange": "{{preName}}超級進化成了\n{{pokemonName}}!", + "gigantamaxChange": "{{preName}}超極巨化成了\n{{pokemonName}}!", + "eternamaxChange": "{{preName}}無極巨化成了\n{{pokemonName}}!", + "revertChange": "{{pokemonName}}變回了\n原本的樣子!", + "formChange": "{{preName}}變為其他樣子了。", +} as const; + +export const pokemonForm: SimpleTranslationEntries = { // Starters forms // 1G "pikachuCosplay": "Cosplay", diff --git a/src/locales/zh_TW/starter-select-ui-handler.ts b/src/locales/zh_TW/starter-select-ui-handler.ts index c3b78c8078d..1202bf45f0e 100644 --- a/src/locales/zh_TW/starter-select-ui-handler.ts +++ b/src/locales/zh_TW/starter-select-ui-handler.ts @@ -7,7 +7,8 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; */ export const starterSelectUiHandler: SimpleTranslationEntries = { "confirmStartTeam": "使用這些寶可夢開始嗎?", - "invalidParty": "This is not a valid starting party!", + "confirmExit": "Do you want to exit?", + "invalidParty": "此為無效隊伍!", "gen1": "I", "gen2": "II", "gen3": "III", @@ -24,6 +25,7 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "eggMoves": "孵化招式", "start": "開始", "addToParty": "加入隊伍", + "removeFromParty": "移出隊伍", "toggleIVs": "查看個體值", "manageMoves": "管理技能", "manageNature": "管理性格", @@ -31,9 +33,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "selectNature": "選擇性格", "selectMoveSwapOut": "選擇想要替換走的招式", "selectMoveSwapWith": "選擇想要替換成的招式", + "sameSpeciesEgg": "買蛋", "unlockPassive": "解鎖被動", "reduceCost": "降低花費", - "sameSpeciesEgg": "買蛋", "cycleShiny": ": 閃光", "cycleForm": ": 形態", "cycleGender": ": 性別", diff --git a/src/locales/zh_TW/status-effect.ts b/src/locales/zh_TW/status-effect.ts index 1a402ac30fd..eb676c08c84 100644 --- a/src/locales/zh_TW/status-effect.ts +++ b/src/locales/zh_TW/status-effect.ts @@ -14,7 +14,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Poison", description: "poisoning", obtain: "{{pokemonNameWithAffix}}\nwas poisoned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas poisoned by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas poisoned by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is hurt\nby poison!", overlap: "{{pokemonNameWithAffix}} is\nalready poisoned!", heal: "{{pokemonNameWithAffix}} was\ncured of its poison!" @@ -23,7 +23,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Toxic", description: "poisoning", obtain: "{{pokemonNameWithAffix}}\nwas badly poisoned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas badly poisoned by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas badly poisoned by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is hurt\nby poison!", overlap: "{{pokemonNameWithAffix}} is\nalready poisoned!", heal: "{{pokemonNameWithAffix}} was\ncured of its poison!" @@ -32,7 +32,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Paralysis", description: "paralysis", obtain: "{{pokemonNameWithAffix}} was paralyzed,\nIt may be unable to move!", - obtainSource: "{{pokemonNameWithAffix}} was paralyzed by {{sourceText}},\nIt may be unable to move!", + obtainSource: "{{pokemonNameWithAffix}} was paralyzed by the {{sourceText}},\nIt may be unable to move!", activation: "{{pokemonNameWithAffix}} is paralyzed!\nIt can't move!", overlap: "{{pokemonNameWithAffix}} is\nalready paralyzed!", heal: "{{pokemonNameWithAffix}} was\nhealed of paralysis!" @@ -41,7 +41,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Sleep", description: "sleep", obtain: "{{pokemonNameWithAffix}}\nfell asleep!", - obtainSource: "{{pokemonNameWithAffix}}\nfell asleep from {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nfell asleep from the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is fast asleep.", overlap: "{{pokemonNameWithAffix}} is\nalready asleep!", heal: "{{pokemonNameWithAffix}} woke up!" @@ -50,7 +50,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Freeze", description: "freezing", obtain: "{{pokemonNameWithAffix}}\nwas frozen solid!", - obtainSource: "{{pokemonNameWithAffix}}\nwas frozen solid by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas frozen solid by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is\nfrozen solid!", overlap: "{{pokemonNameWithAffix}} is\nalready frozen!", heal: "{{pokemonNameWithAffix}} was\ndefrosted!" @@ -59,7 +59,7 @@ export const statusEffect: StatusEffectTranslationEntries = { name: "Burn", description: "burn", obtain: "{{pokemonNameWithAffix}}\nwas burned!", - obtainSource: "{{pokemonNameWithAffix}}\nwas burned by {{sourceText}}!", + obtainSource: "{{pokemonNameWithAffix}}\nwas burned by the {{sourceText}}!", activation: "{{pokemonNameWithAffix}} is hurt\nby its burn!", overlap: "{{pokemonNameWithAffix}} is\nalready burned!", heal: "{{pokemonNameWithAffix}} was\nhealed of its burn!" diff --git a/src/locales/zh_TW/trainers.ts b/src/locales/zh_TW/trainers.ts index 594363ce009..0efae11bbea 100644 --- a/src/locales/zh_TW/trainers.ts +++ b/src/locales/zh_TW/trainers.ts @@ -118,7 +118,34 @@ export const trainerClasses: SimpleTranslationEntries = { "worker": "工人", "worker_female": "工人", "workers": "工人組合", - "youngster": "短褲小子" + "youngster": "短褲小子", + "rocket_grunts": "火箭队手下們", + "rocket_admin": "Rocket Admin", + "rocket_admin_female": "Rocket Admin", + "magma_grunt": "熔岩队手下", + "magma_grunt_female": "熔岩队手下", + "magma_grunts": "熔岩队手下們", + "magma_admin": "Magma Admin", + "magma_admin_female": "Magma Admin", + "aqua_grunt": "海洋队手下", + "aqua_grunt_female": "海洋队手下", + "aqua_grunts": "海洋队手下們", + "aqua_admin": "Aqua Admin", + "aqua_admin_female": "Aqua Admin", + "galactic_grunt": "银河队手下", + "galactic_grunt_female": "银河队手下", + "galactic_grunts": "银河队手下們", + "galactic_admin": "Galactic Admin", + "galactic_admin_female": "Galactic Admin", + "plasma_grunt": "等离子队手下", + "plasma_grunt_female": "等离子队手下", + "plasma_grunts": "等离子队手下們", + "plasma_sage": "Plasma Sage", + "flare_grunt": "闪焰队手下", + "flare_grunt_female": "闪焰队手下", + "flare_grunts": "闪焰队手下們", + "flare_admin": "Flare Admin", + "flare_admin_female": "Flare Admin", } as const; // Names of special trainers like gym leaders, elite four, and the champion diff --git a/src/messages.ts b/src/messages.ts index 2259e78abfc..555a6f30ef1 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -2,17 +2,6 @@ import { BattleSpec } from "#enums/battle-spec"; import Pokemon from "./field/pokemon"; import i18next from "i18next"; -/** - * Builds a message by concatenating the Pokemon name with its potential affix and the given text - * @param pokemon {@linkcode Pokemon} name and battle context will be retrieved from this instance for {@linkcode getPokemonNameWithAffix} - * @param {string} content any text - * @returns {string} ex: "Wild Gengar fainted!", "Ectoplasma sauvage est K.O!" - * @see {@linkcode getPokemonNameWithAffix} for the Pokemon's name and potentiel affix - */ -export function getPokemonMessage(pokemon: Pokemon, content: string): string { - return `${getPokemonNameWithAffix(pokemon)}${content}`; -} - /** * Retrieves the Pokemon's name, potentially with an affix indicating its role (wild or foe) in the current battle context, translated * @param pokemon {@linkcode Pokemon} name and battle context will be retrieved from this instance diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index fb2264fab8f..9c7c3f8949a 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -572,7 +572,7 @@ export class PokemonLevelIncrementModifierType extends PokemonModifierType { if (hasCandyJar) { levels += hasCandyJar.stackCount; } - return i18next.t("modifierType:ModifierType.PokemonLevelIncrementModifierType.description", {levels }); + return i18next.t("modifierType:ModifierType.PokemonLevelIncrementModifierType.description", { levels }); } } @@ -1569,7 +1569,7 @@ const modifierPool: ModifierPool = { p => !p.getHeldItems().some(i => i instanceof Modifiers.PokemonResetNegativeStatStageModifier && i.stackCount >= i.getMaxHeldItemCount(p)) && (checkedAbilities.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => selfStatLowerMoves.includes(m.moveId)))).length; // If a party member has one of the above moves or abilities and doesn't have max herbs, the herb will appear more frequently - return 3*(weightMultiplier? 2: 1)+(weightMultiplier? weightMultiplier-1: 0); + return 0 * (weightMultiplier ? 2 : 1) + (weightMultiplier ? weightMultiplier * 0 : 0); }, 10), new WeightedModifierType(modifierTypes.REVIVER_SEED, 4), new WeightedModifierType(modifierTypes.CANDY_JAR, 5), @@ -1637,7 +1637,7 @@ const wildModifierPool: ModifierPool = { }), [ModifierTier.ULTRA]: [ new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10), - new WeightedModifierType(modifierTypes.WHITE_HERB, 2) + new WeightedModifierType(modifierTypes.WHITE_HERB, 0) ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }), @@ -1666,13 +1666,12 @@ const trainerModifierPool: ModifierPool = { m.setTier(ModifierTier.GREAT); return m; }), [ModifierTier.ULTRA]: [ - new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 5), - new WeightedModifierType(modifierTypes.WHITE_HERB, 1), + new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10), + new WeightedModifierType(modifierTypes.WHITE_HERB, 0), ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }), [ModifierTier.ROGUE]: [ - new WeightedModifierType(modifierTypes.REVIVER_SEED, 2), new WeightedModifierType(modifierTypes.FOCUS_BAND, 2), new WeightedModifierType(modifierTypes.LUCKY_EGG, 4), new WeightedModifierType(modifierTypes.QUICK_CLAW, 1), @@ -1685,6 +1684,7 @@ const trainerModifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.KINGS_ROCK, 1), new WeightedModifierType(modifierTypes.LEFTOVERS, 1), new WeightedModifierType(modifierTypes.SHELL_BELL, 1), + new WeightedModifierType(modifierTypes.SCOPE_LENS, 1), ].map(m => { m.setTier(ModifierTier.MASTER); return m; }) diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 4467f82cb85..91041dc7564 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -9,7 +9,7 @@ import { addTextObject, TextStyle } from "../ui/text"; import { Type } from "../data/type"; import { EvolutionPhase } from "../evolution-phase"; import { FusionSpeciesFormEvolution, pokemonEvolutions, pokemonPrevolutions } from "../data/pokemon-evolutions"; -import {getPokemonMessage, getPokemonNameWithAffix} from "../messages"; +import { getPokemonNameWithAffix } from "../messages"; import * as Utils from "../utils"; import { TempBattleStat } from "../data/temp-battle-stat"; import { getBerryEffectFunc, getBerryPredicate } from "../data/berry"; @@ -1088,7 +1088,7 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier { const hasQuickClaw = this.type instanceof ModifierTypes.PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW"; if (isCommandFight && hasQuickClaw) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " used its Quick Claw to move faster!")); + pokemon.scene.queueMessage(i18next.t("modifier:bypassSpeedChanceApply", { pokemonName: getPokemonNameWithAffix(pokemon), itemName: i18next.t("modifierType:ModifierType.QUICK_CLAW.name") })); } return true; } @@ -1576,11 +1576,11 @@ export class PokemonNatureChangeModifier extends ConsumablePokemonModifier { const pokemon = args[0] as Pokemon; pokemon.natureOverride = this.nature; let speciesId = pokemon.species.speciesId; - pokemon.scene.gameData.dexData[speciesId].natureAttr |= Math.pow(2, this.nature + 1); + pokemon.scene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1); while (pokemonPrevolutions.hasOwnProperty(speciesId)) { speciesId = pokemonPrevolutions[speciesId]; - pokemon.scene.gameData.dexData[speciesId].natureAttr |= Math.pow(2, this.nature + 1); + pokemon.scene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1); } return true; @@ -2334,7 +2334,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { * @see {@linkcode modifierTypes[MINI_BLACK_HOLE]} */ export class TurnHeldItemTransferModifier extends HeldItemTransferModifier { - readonly isTransferrable: boolean = false; + readonly isTransferrable: boolean = true; constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) { super(type, pokemonId, stackCount); } diff --git a/src/overrides.ts b/src/overrides.ts index abc67095bd4..9dd394354aa 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -53,6 +53,10 @@ class DefaultOverrides { readonly XP_MULTIPLIER_OVERRIDE: number = null; /** default 1000 */ readonly STARTING_MONEY_OVERRIDE: integer = 0; + /** Sets all shop item prices to 0 */ + readonly WAIVE_SHOP_FEES_OVERRIDE: boolean = false; + /** Sets reroll price to 0 */ + readonly WAIVE_ROLL_FEE_OVERRIDE: boolean = false; readonly FREE_CANDY_UPGRADE_OVERRIDE: boolean = false; readonly POKEBALL_OVERRIDE: { active: boolean; pokeballs: PokeballCounts } = { active: false, diff --git a/src/phases.ts b/src/phases.ts index 15fd1975d1c..c4062b470a2 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -5,7 +5,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMov import { Mode } from "./ui/ui"; import { Command } from "./ui/command-ui-handler"; import { Stat } from "./data/pokemon-stat"; -import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, overrideModifiers, overrideHeldItems, BypassSpeedChanceModifier, TurnStatusEffectModifier, PokemonResetNegativeStatStageModifier } from "./modifier/modifier"; +import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, overrideModifiers, overrideHeldItems, BypassSpeedChanceModifier, TurnStatusEffectModifier, PokemonResetNegativeStatStageModifier } from "./modifier/modifier"; import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler"; import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball"; import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims"; @@ -20,7 +20,7 @@ import { ModifierTier } from "./modifier/modifier-tier"; import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, RememberMoveModifierType, TmModifierType, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; import { BattlerTagLapseType, CenterOfAttentionTag, EncoreTag, ProtectedTag, SemiInvulnerableTag, TrappedTag } from "./data/battler-tags"; -import { getPokemonMessage, getPokemonNameWithAffix } from "./messages"; +import { getPokemonNameWithAffix } from "./messages"; import { Starter } from "./ui/starter-select-ui-handler"; import { Gender } from "./data/gender"; import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather"; @@ -37,7 +37,7 @@ import { vouchers } from "./system/voucher"; import { clientSessionId, loggedInUser, updateUserInfo } from "./account"; import { SessionSaveData } from "./system/game-data"; import { addPokeballCaptureStars, addPokeballOpenParticles } from "./field/anims"; -import { SpeciesFormChangeActiveTrigger, SpeciesFormChangeManualTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangePreMoveTrigger } from "./data/pokemon-forms"; +import { SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangePreMoveTrigger } from "./data/pokemon-forms"; import { battleSpecDialogue, getCharVariantFromDialogue, miscDialogue } from "./data/dialogue"; import ModifierSelectUiHandler, { SHOP_OPTIONS_ROW_LIMIT } from "./ui/modifier-select-ui-handler"; import { SettingKeys } from "./system/settings/settings"; @@ -642,6 +642,10 @@ export class SelectStarterPhase extends Phase { this.scene.arena.init(); this.scene.sessionPlayTime = 0; this.scene.lastSavePlayTime = 0; + // Ensures Keldeo (or any future Pokemon that have this type of form change) starts in the correct form + this.scene.getParty().forEach((p: PlayerPokemon) => { + this.scene.triggerPokemonFormChange(p, SpeciesFormChangeMoveLearnedTrigger); + }); this.end(); }); } @@ -1392,10 +1396,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { // First check if they're somehow still in play, if so remove them. if (partyMember.isOnField()) { - partyMember.hideInfo(); - partyMember.setVisible(false); - this.scene.field.remove(partyMember); - this.scene.triggerPokemonFormChange(partyMember, SpeciesFormChangeActiveTrigger, true); + partyMember.leaveField(); } const party = this.getParty(); @@ -1437,7 +1438,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { this.scene.time.delayedCall(750, () => this.summon()); } else { const trainerName = this.scene.currentBattle.trainer.getName(!(this.fieldIndex % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER); - const pokemonName = getPokemonNameWithAffix(this.getPokemon()); + const pokemonName = this.getPokemon().getNameToRender(); const message = i18next.t("battle:trainerSendOut", { trainerName, pokemonName }); this.scene.pbTrayEnemy.hide(); @@ -1588,8 +1589,6 @@ export class SwitchSummonPhase extends SummonPhase { } } - // if doReturn === False OR slotIndex !== -1 (slotIndex is valid) and the pokemon doesn't exist/is false - // then switchAndSummon(), manually pick pokemon to switch into if (!this.doReturn || (this.slotIndex !== -1 && !(this.player ? this.scene.getParty() : this.scene.getEnemyParty())[this.slotIndex])) { if (this.player) { return this.switchAndSummon(); @@ -1613,7 +1612,7 @@ export class SwitchSummonPhase extends SummonPhase { }) ); this.scene.playSound("pb_rel"); - pokemon.hideInfo(); + pokemon.hideInfo(); // this is also done by pokemon.leaveField(), but needs to go earlier for animation purposes pokemon.tint(getPokeballTintColor(pokemon.pokeball), 1, 250, "Sine.easeIn"); this.scene.tweens.add({ targets: pokemon, @@ -1621,9 +1620,9 @@ export class SwitchSummonPhase extends SummonPhase { ease: "Sine.easeIn", scale: 0.5, onComplete: () => { - pokemon.setVisible(false); - this.scene.field.remove(pokemon); - this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true); + // 250ms delay on leaveField is necessary to avoid calling hideInfo() twice + // and double-animating the stats panel slideout + this.scene.time.delayedCall(250, () => pokemon.leaveField(!this.batonPass)); this.scene.time.delayedCall(750, () => this.switchAndSummon()); } }); @@ -1631,34 +1630,34 @@ export class SwitchSummonPhase extends SummonPhase { switchAndSummon() { const party = this.player ? this.getParty() : this.scene.getEnemyParty(); - const switchedPokemon = party[this.slotIndex]; + const switchedInPokemon = party[this.slotIndex]; this.lastPokemon = this.getPokemon(); applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, this.lastPokemon); - if (this.batonPass && switchedPokemon) { - (this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.transferTagsBySourceId(this.lastPokemon.id, switchedPokemon.id)); - if (!this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedPokemon.id)) { + if (this.batonPass && switchedInPokemon) { + (this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.transferTagsBySourceId(this.lastPokemon.id, switchedInPokemon.id)); + if (!this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedInPokemon.id)) { const batonPassModifier = this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === this.lastPokemon.id) as SwitchEffectTransferModifier; - if (batonPassModifier && !this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedPokemon.id)) { - this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedPokemon, false); + if (batonPassModifier && !this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedInPokemon.id)) { + this.scene.tryTransferHeldItemModifier(batonPassModifier, switchedInPokemon, false); } } } - if (switchedPokemon) { + if (switchedInPokemon) { party[this.slotIndex] = this.lastPokemon; - party[this.fieldIndex] = switchedPokemon; + party[this.fieldIndex] = switchedInPokemon; const showTextAndSummon = () => { this.scene.ui.showText(this.player ? - i18next.t("battle:playerGo", { pokemonName: getPokemonNameWithAffix(switchedPokemon) }) : + i18next.t("battle:playerGo", { pokemonName: getPokemonNameWithAffix(switchedInPokemon) }) : i18next.t("battle:trainerGo", { trainerName: this.scene.currentBattle.trainer.getName(!(this.fieldIndex % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER), - pokemonName: getPokemonNameWithAffix(this.getPokemon()) + pokemonName: this.getPokemon().getNameToRender() }) ); // Ensure improperly persisted summon data (such as tags) is cleared upon switching if (!this.batonPass) { - party[this.fieldIndex].resetBattleData(); - party[this.fieldIndex].resetSummonData(); + switchedInPokemon.resetBattleData(); + switchedInPokemon.resetSummonData(); } this.summon(); }; @@ -1878,14 +1877,11 @@ export class TurnInitPhase extends FieldPhase { this.scene.unshiftPhase(new GameOverPhase(this.scene)); } else if (allowedPokemon.length >= this.scene.currentBattle.getBattlerCount() || (this.scene.currentBattle.double && !allowedPokemon[0].isActive(true))) { // If there is at least one pokemon in the back that is legal to switch in, force a switch. - p.switchOut(false, true); + p.switchOut(false); } else { // If there are no pokemon in the back but we're not game overing, just hide the pokemon. // This should only happen in double battles. - p.hideInfo(); - p.setVisible(false); - this.scene.field.remove(p); - this.scene.triggerPokemonFormChange(p, SpeciesFormChangeActiveTrigger, true); + p.leaveField(); } if (allowedPokemon.length === 1 && this.scene.currentBattle.double) { this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true)); @@ -2170,6 +2166,15 @@ export class CommandPhase extends FieldPhase { } } +/** + * Phase for determining an enemy AI's action for the next turn. + * During this phase, the enemy decides whether to switch (if it has a trainer) + * or to use a move from its moveset. + * + * For more information on how the Enemy AI works, see docs/enemy-ai.md + * @see {@linkcode Pokemon.getMatchupScore} + * @see {@linkcode EnemyPokemon.getNextMove} + */ export class EnemyCommandPhase extends FieldPhase { protected fieldIndex: integer; @@ -2188,6 +2193,15 @@ export class EnemyCommandPhase extends FieldPhase { const trainer = battle.trainer; + /** + * If the enemy has a trainer, decide whether or not the enemy should switch + * to another member in its party. + * + * This block compares the active enemy Pokemon's {@linkcode Pokemon.getMatchupScore | matchup score} + * against the active player Pokemon with the enemy party's other non-fainted Pokemon. If a party + * member's matchup score is 3x the active enemy's score (or 2x for "boss" trainers), + * the enemy will switch to that Pokemon. + */ if (trainer && !enemyPokemon.getMoveQueue().length) { const opponents = enemyPokemon.getOpponents(); @@ -2219,6 +2233,7 @@ export class EnemyCommandPhase extends FieldPhase { } } + /** Select a move to use (and a target to use it against, if applicable) */ const nextMove = enemyPokemon.getNextMove(); this.scene.currentBattle.turnCommands[this.fieldIndex + BattlerIndex.ENEMY] = @@ -2316,6 +2331,8 @@ export class TurnStartPhase extends FieldPhase { return aIndex < bIndex ? -1 : aIndex > bIndex ? 1 : 0; }); + let orderIndex = 0; + for (const o of moveOrder) { const pokemon = field[o]; @@ -2328,6 +2345,7 @@ export class TurnStartPhase extends FieldPhase { switch (turnCommand.command) { case Command.FIGHT: const queuedMove = turnCommand.move; + pokemon.turnData.order = orderIndex++; if (!queuedMove) { continue; } @@ -2409,7 +2427,7 @@ export class BerryPhase extends FieldPhase { pokemon.getOpponents().map((opp) => applyAbAttrs(PreventBerryUseAbAttr, opp, cancelled)); if (cancelled.value) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is too\nnervous to eat berries!")); + pokemon.scene.queueMessage(i18next.t("abilityTriggers:preventBerryUse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } else { this.scene.unshiftPhase( new CommonAnimPhase(this.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM) @@ -2665,13 +2683,14 @@ export class MovePhase extends BattlePhase { if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) { if (this.pokemon.turnData.attacksReceived.length) { const attack = this.pokemon.turnData.attacksReceived[0]; - this.targets[0] = attack.attackingPosition; + this.targets[0] = attack.sourceBattlerIndex; // account for metal burst and comeuppance hitting remaining targets in double battles // counterattack will redirect to remaining ally if original attacker faints if (this.scene.currentBattle.double && this.move.getMove().hasFlag(MoveFlags.REDIRECT_COUNTER)) { - if (!this.scene.getEnemyField()[this.targets[0]]) { - this.targets[0] = this.scene.getEnemyField().find(p => p.isActive(true)).getBattlerIndex(); + if (this.scene.getField()[this.targets[0]].hp === 0) { + const opposingField = this.pokemon.isPlayer() ? this.scene.getEnemyField() : this.scene.getPlayerField(); + this.targets[0] = opposingField.find(p => p.hp > 0)?.getBattlerIndex(); } } } @@ -2951,6 +2970,8 @@ export class MoveEffectPhase extends PokemonPhase { // Move animation only needs one target new MoveAnim(move.id as Moves, user, this.getTarget()?.getBattlerIndex()).play(this.scene, () => { + /** Has the move successfully hit a target (for damage) yet? */ + let hasHit: boolean = false; for (const target of targets) { if (!targetHitChecks[target.getBattlerIndex()]) { this.stopMultiHit(target); @@ -2966,7 +2987,6 @@ export class MoveEffectPhase extends PokemonPhase { const isProtected = !this.move.getMove().checkFlag(MoveFlags.IGNORE_PROTECT, user, target) && target.findTags(t => t instanceof ProtectedTag).find(t => target.lapseTag(t.tagType)); const firstHit = (user.turnData.hitsLeft === user.turnData.hitCount); - const firstTarget = (moveHistoryEntry.result === MoveResult.PENDING); if (firstHit) { user.pushMoveHistory(moveHistoryEntry); @@ -2976,6 +2996,18 @@ export class MoveEffectPhase extends PokemonPhase { const hitResult = !isProtected ? target.apply(user, move) : HitResult.NO_EFFECT; + const dealsDamage = [ + HitResult.EFFECTIVE, + HitResult.SUPER_EFFECTIVE, + HitResult.NOT_VERY_EFFECTIVE, + HitResult.ONE_HIT_KO + ].includes(hitResult); + + const firstTarget = dealsDamage && !hasHit; + if (firstTarget) { + hasHit = true; + } + const lastHit = (user.turnData.hitsLeft === 1 || !this.getTarget()?.isActive()); if (lastHit) { @@ -2983,7 +3015,7 @@ export class MoveEffectPhase extends PokemonPhase { } applyAttrs.push(new Promise(resolve => { - applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.PRE_APPLY && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit), + applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && attr.trigger === MoveEffectTrigger.PRE_APPLY && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit) && hitResult !== HitResult.NO_EFFECT, user, target, move).then(() => { if (hitResult !== HitResult.FAIL) { const chargeEffect = !!move.getAttrs(ChargeAttr).find(ca => ca.usedChargeEffect(user, this.getTarget(), move)); @@ -2993,7 +3025,7 @@ export class MoveEffectPhase extends PokemonPhase { if (hitResult !== HitResult.NO_EFFECT) { applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && (attr as MoveEffectAttr).trigger === MoveEffectTrigger.POST_APPLY && !(attr as MoveEffectAttr).selfTarget && (!attr.firstHitOnly || firstHit) && (!attr.lastHitOnly || lastHit), user, target, this.move.getMove()).then(() => { - if (hitResult < HitResult.NO_EFFECT && !target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr)) { + if (dealsDamage && !target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr)) { const flinched = new Utils.BooleanHolder(false); user.scene.applyModifiers(FlinchChanceModifier, user.isPlayer(), user, flinched); if (flinched.value) { @@ -3321,7 +3353,7 @@ export class StatChangePhase extends PokemonPhase { applyPostStatChangeAbAttrs(PostStatChangeAbAttr, pokemon, filteredStats, this.levels, this.selfTarget); - //Look for any other stat change phases; if this is the last one, do White Herb check + // Look for any other stat change phases; if this is the last one, do White Herb check const existingPhase = this.scene.findPhase(p => p instanceof StatChangePhase && p.battlerIndex === this.battlerIndex); if (!(existingPhase instanceof StatChangePhase)) { // Apply White Herb if needed @@ -3596,6 +3628,14 @@ export class PostTurnStatusEffectPhase extends PokemonPhase { this.end(); } } + + override end() { + if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) { + this.scene.initFinalBossPhaseTwo(this.getPokemon()); + } else { + super.end(); + } + } } export class MessagePhase extends Phase { @@ -3703,34 +3743,12 @@ export class DamagePhase extends PokemonPhase { } } - end() { - switch (this.scene.currentBattle.battleSpec) { - case BattleSpec.FINAL_BOSS: - const pokemon = this.getPokemon(); - if (pokemon instanceof EnemyPokemon && pokemon.isBoss() && !pokemon.formIndex && pokemon.bossSegmentIndex < 1) { - this.scene.fadeOutBgm(Utils.fixedInt(2000), false); - this.scene.ui.showDialogue(battleSpecDialogue[BattleSpec.FINAL_BOSS].firstStageWin, pokemon.species.name, null, () => { - this.scene.addEnemyModifier(getModifierType(modifierTypes.MINI_BLACK_HOLE).newModifier(pokemon) as PersistentModifier, false, true); - pokemon.generateAndPopulateMoveset(1); - this.scene.setFieldScale(0.75); - this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); - this.scene.currentBattle.double = true; - const availablePartyMembers = this.scene.getParty().filter(p => p.isAllowedInBattle()); - if (availablePartyMembers.length > 1) { - this.scene.pushPhase(new ToggleDoublePositionPhase(this.scene, true)); - if (!availablePartyMembers[1].isOnField()) { - this.scene.pushPhase(new SummonPhase(this.scene, 1)); - } - } - - super.end(); - }); - return; - } - break; + override end() { + if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) { + this.scene.initFinalBossPhaseTwo(this.getPokemon()); + } else { + super.end(); } - - super.end(); } } @@ -3801,11 +3819,10 @@ export class FaintPhase extends PokemonPhase { const nonFaintedPartyMemberCount = nonFaintedLegalPartyMembers.length; if (!nonFaintedPartyMemberCount) { this.scene.unshiftPhase(new GameOverPhase(this.scene)); - } else if (nonFaintedPartyMemberCount >= this.scene.currentBattle.getBattlerCount() || (this.scene.currentBattle.double && !nonFaintedLegalPartyMembers[0].isActive(true))) { - this.scene.pushPhase(new SwitchPhase(this.scene, this.fieldIndex, true, false)); - } - if (nonFaintedPartyMemberCount === 1 && this.scene.currentBattle.double) { + } else if (nonFaintedPartyMemberCount === 1 && this.scene.currentBattle.double) { this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true)); + } else if (nonFaintedPartyMemberCount >= this.scene.currentBattle.getBattlerCount()) { + this.scene.pushPhase(new SwitchPhase(this.scene, this.fieldIndex, true, false)); } } else { this.scene.unshiftPhase(new VictoryPhase(this.scene, this.battlerIndex)); @@ -4468,6 +4485,11 @@ export class SwitchPhase extends BattlePhase { return super.end(); } + // Skip if the fainted party member has been revived already + if (this.isModal && !this.scene.getParty()[this.fieldIndex].isFainted()) { + return super.end(); + } + // Check if there is any space still in field if (this.isModal && this.scene.getPlayerField().filter(p => p.isAllowedInBattle() && p.isActive(true)).length >= this.scene.currentBattle.getBattlerCount()) { return super.end(); @@ -5031,7 +5053,7 @@ export class AttemptCapturePhase extends PokemonPhase { Promise.all([pokemon.hideInfo(), this.scene.gameData.setPokemonCaught(pokemon)]).then(() => { if (this.scene.getParty().length === 6) { const promptRelease = () => { - this.scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: getPokemonNameWithAffix(pokemon) }), null, () => { + this.scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => { this.scene.pokemonInfoContainer.makeRoomForConfirmUi(1, true); this.scene.ui.setMode(Mode.CONFIRM, () => { const newPokemon = this.scene.addPlayerPokemon(pokemon.species, pokemon.level, pokemon.abilityIndex, pokemon.formIndex, pokemon.gender, pokemon.shiny, pokemon.variant, pokemon.ivs, pokemon.nature, pokemon); @@ -5178,9 +5200,11 @@ export class SelectModifierPhase extends BattlePhase { this.scene.unshiftPhase(new SelectModifierPhase(this.scene, this.rerollCount + 1, typeOptions.map(o => o.type.tier))); this.scene.ui.clearText(); this.scene.ui.setMode(Mode.MESSAGE).then(() => super.end()); - this.scene.money -= rerollCost; - this.scene.updateMoneyText(); - this.scene.animateMoneyChanged(false); + if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { + this.scene.money -= rerollCost; + this.scene.updateMoneyText(); + this.scene.animateMoneyChanged(false); + } this.scene.playSound("buy"); } break; @@ -5221,7 +5245,7 @@ export class SelectModifierPhase extends BattlePhase { break; } - if (cost && this.scene.money < cost) { + if (cost && (this.scene.money < cost) && !Overrides.WAIVE_ROLL_FEE_OVERRIDE) { this.scene.ui.playError(); return false; } @@ -5231,9 +5255,11 @@ export class SelectModifierPhase extends BattlePhase { if (cost) { result.then(success => { if (success) { - this.scene.money -= cost; - this.scene.updateMoneyText(); - this.scene.animateMoneyChanged(false); + if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { + this.scene.money -= cost; + this.scene.updateMoneyText(); + this.scene.animateMoneyChanged(false); + } this.scene.playSound("buy"); (this.scene.ui.getHandler() as ModifierSelectUiHandler).updateCostText(); } else { @@ -5313,7 +5339,9 @@ export class SelectModifierPhase extends BattlePhase { getRerollCost(typeOptions: ModifierTypeOption[], lockRarities: boolean): integer { let baseValue = 0; - if (lockRarities) { + if (Overrides.WAIVE_ROLL_FEE_OVERRIDE) { + return baseValue; + } else if (lockRarities) { const tierValues = [50, 125, 300, 750, 2000]; for (const opt of typeOptions) { baseValue += tierValues[opt.type.tier]; diff --git a/src/plugins/vite/vite-minify-json-plugin.ts b/src/plugins/vite/vite-minify-json-plugin.ts new file mode 100644 index 00000000000..57130669075 --- /dev/null +++ b/src/plugins/vite/vite-minify-json-plugin.ts @@ -0,0 +1,57 @@ +import path from "path"; +import fs from "fs"; +import { type Plugin as VitePlugin } from "vite"; + +/** + * Crawl a directory (recursively if wanted) for json files and minifies found ones. + * @param dir the directory to crawl + * @param recursive if true, will crawl subdirectories + */ +function applyToDir(dir: string, recursive?: boolean) { + const files = fs.readdirSync(dir).filter((file) => !/^\..*/.test(file)); + + for (const file of files) { + const filePath = path.join(dir, file); + const stat = fs.lstatSync(filePath); + + if (stat.isDirectory() && recursive) { + applyToDir(filePath, recursive); // only if recursive is true + } else if (path.extname(file) === ".json") { + const contents = fs.readFileSync(filePath, "utf8"); + const minifiedContent = JSON.stringify(JSON.parse(contents)); + + fs.writeFileSync(filePath, minifiedContent, "utf8"); + } + } +} + +/** + * Plugin to mnify json files in the build folder after the bundling is done. + * @param basePath base path/es starting inside the build dir (e.g. will always start with "/dist" if dist is the build dir) + * @param recursive if true, will crawl subdirectories + */ +export function minifyJsonPlugin(basePath: string | string[], recursive?: boolean): VitePlugin { + let buildDir = "dist"; // Default build dir + + return { + name: "flx-minify-json", + apply: "build", + configResolved(config) { + buildDir = config.build.outDir; // Read the build output directory from Vite config + }, + async closeBundle() { + console.log("Minifying JSON files..."); + const basePathes = Array.isArray(basePath) ? basePath : [basePath]; + + basePathes.forEach((basePath) => { + const baseDir = path.resolve(buildDir, basePath); + if (fs.existsSync(baseDir)) { + applyToDir(baseDir, recursive); + } else { + console.error(`Path ${baseDir} does not exist!`); + } + }); + console.log("Finished minifying JSON files!"); + }, + }; +} diff --git a/src/system/game-data.ts b/src/system/game-data.ts index bbc74ee13e3..161b5a2c49b 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -41,7 +41,6 @@ import { Moves } from "#enums/moves"; import { PlayerGender } from "#enums/player-gender"; import { Species } from "#enums/species"; import { applyChallenges, ChallengeType } from "#app/data/challenge.js"; -import { Abilities } from "#app/enums/abilities.js"; export const defaultStarterSpecies: Species[] = [ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, @@ -350,7 +349,7 @@ export class GameData { this.scene.ui.savingIcon.show(); const data = this.getSystemSaveData(); - const maxIntAttrValue = Math.pow(2, 31); + const maxIntAttrValue = 0x80000000; const systemData = JSON.stringify(data, (k: any, v: any) => typeof v === "bigint" ? v <= maxIntAttrValue ? Number(v) : v.toString() : v); localStorage.setItem(`data_${loggedInUser.username}`, encrypt(systemData, bypassLogin)); @@ -852,14 +851,6 @@ export class GameData { const handleSessionData = async (sessionDataStr: string) => { try { const sessionData = this.parseSessionData(sessionDataStr); - for (let i = 0; i <= 5; i++) { - const speciesToCheck = getPokemonSpecies(sessionData.party[i]?.species); - if (sessionData.party[i]?.abilityIndex === 1) { - if (speciesToCheck.ability1 === speciesToCheck.ability2 && speciesToCheck.abilityHidden !== Abilities.NONE && speciesToCheck.abilityHidden !== speciesToCheck.ability1) { - sessionData.party[i].abilityIndex = 2; - } - } - } resolve(sessionData); } catch (err) { reject(err); @@ -1172,7 +1163,7 @@ export class GameData { } const sessionData = useCachedSession ? this.parseSessionData(decrypt(localStorage.getItem(`sessionData${scene.sessionSlotId ? scene.sessionSlotId : ""}_${loggedInUser.username}`), bypassLogin)) : this.getSessionSaveData(scene); - const maxIntAttrValue = Math.pow(2, 31); + const maxIntAttrValue = 0x80000000; const systemData = useCachedSystem ? this.parseSystemData(decrypt(localStorage.getItem(`data_${loggedInUser.username}`), bypassLogin)) : this.getSystemSaveData(); const request = { @@ -1377,7 +1368,7 @@ export class GameData { const entry = data[defaultStarterSpecies[ds]] as DexEntry; entry.seenAttr = defaultStarterAttr; entry.caughtAttr = defaultStarterAttr; - entry.natureAttr = Math.pow(2, defaultStarterNatures[ds] + 1); + entry.natureAttr = 1 << (defaultStarterNatures[ds] + 1); for (const i in entry.ivs) { entry.ivs[i] = 10; } @@ -1444,10 +1435,10 @@ export class GameData { dexEntry.caughtAttr |= dexAttr; if (speciesStarters.hasOwnProperty(species.speciesId)) { this.starterData[species.speciesId].abilityAttr |= pokemon.abilityIndex !== 1 || pokemon.species.ability2 - ? Math.pow(2, pokemon.abilityIndex) + ? 1 << pokemon.abilityIndex : AbilityAttr.ABILITY_HIDDEN; } - dexEntry.natureAttr |= Math.pow(2, pokemon.nature + 1); + dexEntry.natureAttr |= 1 << (pokemon.nature + 1); const hasPrevolution = pokemonPrevolutions.hasOwnProperty(species.speciesId); const newCatch = !caughtAttr; @@ -1483,7 +1474,7 @@ export class GameData { } if (!hasPrevolution && (!pokemon.scene.gameMode.isDaily || hasNewAttr || fromEgg)) { - this.addStarterCandy(species, (1 * (pokemon.isShiny() ? 5 * Math.pow(2, pokemon.variant || 0) : 1)) * (fromEgg || pokemon.isBoss() ? 2 : 1)); + this.addStarterCandy(species, (1 * (pokemon.isShiny() ? 5 * (1 << (pokemon.variant ?? 0)) : 1)) * (fromEgg || pokemon.isBoss() ? 2 : 1)); } } @@ -1554,7 +1545,7 @@ export class GameData { this.starterData[speciesId].eggMoves = 0; } - const value = Math.pow(2, eggMoveIndex); + const value = 1 << eggMoveIndex; if (this.starterData[speciesId].eggMoves & value) { resolve(false); @@ -1646,7 +1637,7 @@ export class GameData { getSpeciesDefaultNature(species: PokemonSpecies): Nature { const dexEntry = this.dexData[species.speciesId]; for (let n = 0; n < 25; n++) { - if (dexEntry.natureAttr & Math.pow(2, n + 1)) { + if (dexEntry.natureAttr & (1 << (n + 1))) { return n as Nature; } } @@ -1654,7 +1645,7 @@ export class GameData { } getSpeciesDefaultNatureAttr(species: PokemonSpecies): integer { - return Math.pow(2, this.getSpeciesDefaultNature(species)); + return 1 << (this.getSpeciesDefaultNature(species)); } getDexAttrLuck(dexAttr: bigint): integer { @@ -1664,7 +1655,7 @@ export class GameData { getNaturesForAttr(natureAttr: integer): Nature[] { const ret: Nature[] = []; for (let n = 0; n < 25; n++) { - if (natureAttr & Math.pow(2, n + 1)) { + if (natureAttr & (1 << (n + 1))) { ret.push(n); } } @@ -1706,7 +1697,7 @@ export class GameData { } getFormAttr(formIndex: integer): bigint { - return BigInt(Math.pow(2, 7 + formIndex)); + return BigInt(1 << (7 + formIndex)); } consolidateDexData(dexData: DexData): void { @@ -1716,7 +1707,7 @@ export class GameData { entry.hatchedCount = 0; } if (!entry.hasOwnProperty("natureAttr") || (entry.caughtAttr && !entry.natureAttr)) { - entry.natureAttr = this.defaultDexData[k].natureAttr || Math.pow(2, Utils.randInt(25, 1)); + entry.natureAttr = this.defaultDexData[k].natureAttr || (1 << Utils.randInt(25, 1)); } } } diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 7e8f1e21c07..ca072c9eec8 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -38,6 +38,7 @@ export default class PokemonData { public friendship: integer; public metLevel: integer; public metBiome: Biome | -1; + public metSpecies: Species; public luck: integer; public pauseEvolutions: boolean; public pokerus: boolean; @@ -83,6 +84,7 @@ export default class PokemonData { this.friendship = source.friendship !== undefined ? source.friendship : getPokemonSpecies(this.species).baseFriendship; this.metLevel = source.metLevel || 5; this.metBiome = source.metBiome !== undefined ? source.metBiome : -1; + this.metSpecies = source.metSpecies; this.luck = source.luck !== undefined ? source.luck : (source.shiny ? (source.variant + 1) : 0); if (!forHistory) { this.pauseEvolutions = !!source.pauseEvolutions; diff --git a/src/test/abilities/ability_timing.test.ts b/src/test/abilities/ability_timing.test.ts index 84d4390652e..bb025d7fc53 100644 --- a/src/test/abilities/ability_timing.test.ts +++ b/src/test/abilities/ability_timing.test.ts @@ -1,13 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; import { CommandPhase, MessagePhase, TurnInitPhase } from "#app/phases"; +import i18next, { initI18n } from "#app/plugins/i18n"; +import GameManager from "#test/utils/gameManager"; import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import i18next, { initI18n } from "#app/plugins/i18n"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Ability Timing", () => { @@ -26,14 +26,14 @@ describe("Ability Timing", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.PIDGEY); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INTIMIDATE); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(Array(4).fill(Moves.SPLASH)); + game.override.enemySpecies(Species.PIDGEY); + game.override.enemyAbility(Abilities.INTIMIDATE); + game.override.enemyMoveset(SPLASH_ONLY); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.ICE_BEAM]); + game.override.ability(Abilities.BALL_FETCH); + game.override.moveset([Moves.SPLASH, Moves.ICE_BEAM]); }); it("should trigger after switch check", async() => { diff --git a/src/test/abilities/aura_break.test.ts b/src/test/abilities/aura_break.test.ts index 28813b5206f..a34475cb1ad 100644 --- a/src/test/abilities/aura_break.test.ts +++ b/src/test/abilities/aura_break.test.ts @@ -1,13 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { MoveEffectPhase } from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; import { allMoves } from "#app/data/move.js"; +import { MoveEffectPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Aura Break", () => { let phaserGame: Phaser.Game; @@ -27,18 +27,18 @@ describe("Abilities - Aura Break", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.MOONBLAST, Moves.DARK_PULSE, Moves.MOONBLAST, Moves.DARK_PULSE]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.AURA_BREAK); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); + game.override.battleType("single"); + game.override.moveset([Moves.MOONBLAST, Moves.DARK_PULSE, Moves.MOONBLAST, Moves.DARK_PULSE]); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.AURA_BREAK); + game.override.enemySpecies(Species.SHUCKLE); }); it("reverses the effect of fairy aura", async () => { const moveToCheck = allMoves[Moves.MOONBLAST]; const basePower = moveToCheck.power; - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.FAIRY_AURA); + game.override.ability(Abilities.FAIRY_AURA); vi.spyOn(moveToCheck, "calculateBattlePower"); await game.startBattle([Species.PIKACHU]); @@ -52,7 +52,7 @@ describe("Abilities - Aura Break", () => { const moveToCheck = allMoves[Moves.DARK_PULSE]; const basePower = moveToCheck.power; - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.DARK_AURA); + game.override.ability(Abilities.DARK_AURA); vi.spyOn(moveToCheck, "calculateBattlePower"); await game.startBattle([Species.PIKACHU]); diff --git a/src/test/abilities/battery.test.ts b/src/test/abilities/battery.test.ts index 06f388371e9..2345e63d987 100644 --- a/src/test/abilities/battery.test.ts +++ b/src/test/abilities/battery.test.ts @@ -1,13 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; import { allMoves } from "#app/data/move.js"; import { Abilities } from "#app/enums/abilities.js"; import { MoveEffectPhase, TurnEndPhase } from "#app/phases.js"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Battery", () => { let phaserGame: Phaser.Game; @@ -27,11 +27,11 @@ describe("Abilities - Battery", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.BREAKING_SWIPE, Moves.SPLASH, Moves.DAZZLING_GLEAM]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.battleType("double"); + game.override.enemySpecies(Species.SHUCKLE); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.moveset([Moves.TACKLE, Moves.BREAKING_SWIPE, Moves.SPLASH, Moves.DAZZLING_GLEAM]); + game.override.enemyMoveset(SPLASH_ONLY); }); it("raises the power of allies' special moves by 30%", async () => { diff --git a/src/test/abilities/battle_bond.test.ts b/src/test/abilities/battle_bond.test.ts index 1ebefb99f32..ce41f9b6603 100644 --- a/src/test/abilities/battle_bond.test.ts +++ b/src/test/abilities/battle_bond.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import { Status, StatusEffect } from "#app/data/status-effect.js"; +import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { TurnEndPhase } from "#app/phases.js"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import Overrides from "#app/overrides"; -import { Moves } from "#enums/moves"; -import { Abilities } from "#enums/abilities"; -import { Species } from "#enums/species"; -import { Status, StatusEffect } from "#app/data/status-effect.js"; -import { TurnEndPhase } from "#app/phases.js"; -import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -28,19 +27,19 @@ describe("Abilities - BATTLE BOND", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BATTLE_BOND); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.battleType("single"); + game.override.ability(Abilities.BATTLE_BOND); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); }); test( "check if fainted pokemon switches to base form on arena reset", async () => { - const baseForm = 1, - ashForm = 2; - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(4); - vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue({ + const baseForm = 1; + const ashForm = 2; + game.override.startingWave(4); + game.override.starterForms({ [Species.GRENINJA]: ashForm, }); diff --git a/src/test/abilities/costar.test.ts b/src/test/abilities/costar.test.ts index f26c4f70758..ef3fb3a2ab0 100644 --- a/src/test/abilities/costar.test.ts +++ b/src/test/abilities/costar.test.ts @@ -1,13 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; -import GameManager from "../utils/gameManager"; -import Phaser from "phaser"; -import Overrides from "#app/overrides"; import { BattleStat } from "#app/data/battle-stat.js"; -import { CommandPhase, MessagePhase } from "#app/phases.js"; -import { getMovePosition } from "../utils/gameManagerUtils"; import { Abilities } from "#app/enums/abilities.js"; import { Moves } from "#app/enums/moves.js"; import { Species } from "#app/enums/species.js"; +import { CommandPhase, MessagePhase } from "#app/phases.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -27,23 +27,21 @@ describe("Abilities - COSTAR", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.COSTAR); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.NASTY_PLOT]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.battleType("double"); + game.override.ability(Abilities.COSTAR); + game.override.moveset([Moves.SPLASH, Moves.NASTY_PLOT]); + game.override.enemyMoveset(SPLASH_ONLY); }); test( "ability copies positive stat changes", async () => { - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); + game.override.enemyAbility(Abilities.BALL_FETCH); await game.startBattle([Species.MAGIKARP, Species.MAGIKARP, Species.FLAMIGO]); let [leftPokemon, rightPokemon] = game.scene.getPlayerField(); - expect(leftPokemon).toBeDefined(); - expect(rightPokemon).toBeDefined(); game.doAttack(getMovePosition(game.scene, 0, Moves.NASTY_PLOT)); await game.phaseInterceptor.to(CommandPhase); @@ -68,13 +66,11 @@ describe("Abilities - COSTAR", () => { test( "ability copies negative stat changes", async () => { - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INTIMIDATE); + game.override.enemyAbility(Abilities.INTIMIDATE); await game.startBattle([Species.MAGIKARP, Species.MAGIKARP, Species.FLAMIGO]); let [leftPokemon, rightPokemon] = game.scene.getPlayerField(); - expect(leftPokemon).toBeDefined(); - expect(rightPokemon).toBeDefined(); expect(leftPokemon.summonData.battleStats[BattleStat.ATK]).toBe(-2); expect(leftPokemon.summonData.battleStats[BattleStat.ATK]).toBe(-2); diff --git a/src/test/abilities/disguise.test.ts b/src/test/abilities/disguise.test.ts index 0a542780ebc..3a6fd540d27 100644 --- a/src/test/abilities/disguise.test.ts +++ b/src/test/abilities/disguise.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import { Status, StatusEffect } from "#app/data/status-effect.js"; +import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { TurnEndPhase } from "#app/phases.js"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import Overrides from "#app/overrides"; -import { Moves } from "#enums/moves"; -import { Abilities } from "#enums/abilities"; -import { Species } from "#enums/species"; -import { Status, StatusEffect } from "#app/data/status-effect.js"; -import { TurnEndPhase } from "#app/phases.js"; -import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -28,10 +27,10 @@ describe("Abilities - DISGUISE", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.DISGUISE); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.battleType("single"); + game.override.ability(Abilities.DISGUISE); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); }); test( @@ -39,8 +38,8 @@ describe("Abilities - DISGUISE", () => { async () => { const baseForm = 0, bustedForm = 1; - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(4); - vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue({ + game.override.startingWave(4); + game.override.starterForms({ [Species.MIMIKYU]: bustedForm, }); @@ -71,11 +70,11 @@ describe("Abilities - DISGUISE", () => { const baseForm = 0, bustedForm = 1; - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DARK_PULSE, Moves.DARK_PULSE, Moves.DARK_PULSE, Moves.DARK_PULSE]); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(20); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(20); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue({ + game.override.enemyMoveset([Moves.DARK_PULSE, Moves.DARK_PULSE, Moves.DARK_PULSE, Moves.DARK_PULSE]); + game.override.startingLevel(20); + game.override.enemyLevel(20); + game.override.enemySpecies(Species.MAGIKARP); + game.override.starterForms({ [Species.MIMIKYU]: baseForm, }); diff --git a/src/test/abilities/dry_skin.test.ts b/src/test/abilities/dry_skin.test.ts index 3d97c414862..6da5ad08571 100644 --- a/src/test/abilities/dry_skin.test.ts +++ b/src/test/abilities/dry_skin.test.ts @@ -1,12 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { TurnEndPhase } from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; import { Species } from "#app/enums/species.js"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Dry Skin", () => { let phaserGame: Phaser.Game; @@ -24,17 +24,17 @@ describe("Abilities - Dry Skin", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.DRY_SKIN); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.CHARMANDER); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.UNNERVE); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.CHANDELURE); + game.override.battleType("single"); + game.override.disableCrits(); + game.override.enemyAbility(Abilities.DRY_SKIN); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemySpecies(Species.CHARMANDER); + game.override.ability(Abilities.UNNERVE); + game.override.starterSpecies(Species.CHANDELURE); }); it("during sunlight, lose 1/8 of maximum health at the end of each turn", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SUNNY_DAY, Moves.SPLASH]); + game.override.moveset([Moves.SUNNY_DAY, Moves.SPLASH]); await game.startBattle(); @@ -55,7 +55,7 @@ describe("Abilities - Dry Skin", () => { }); it("during rain, gain 1/8 of maximum health at the end of each turn", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.RAIN_DANCE, Moves.SPLASH]); + game.override.moveset([Moves.RAIN_DANCE, Moves.SPLASH]); await game.startBattle(); @@ -78,12 +78,11 @@ describe("Abilities - Dry Skin", () => { }); it("opposing fire attacks do 25% more damage", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.FLAMETHROWER]); + game.override.moveset([Moves.FLAMETHROWER]); await game.startBattle(); const enemy = game.scene.getEnemyPokemon(); - expect(enemy).toBeDefined(); const initialHP = 1000; enemy.hp = initialHP; @@ -94,7 +93,7 @@ describe("Abilities - Dry Skin", () => { expect(enemy.hp > 0); enemy.hp = initialHP; - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); + game.override.enemyAbility(Abilities.NONE); // second turn game.doAttack(getMovePosition(game.scene, 0, Moves.FLAMETHROWER)); @@ -105,7 +104,7 @@ describe("Abilities - Dry Skin", () => { }); it("opposing water attacks heal 1/4 of maximum health and deal no damage", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.WATER_GUN]); + game.override.moveset([Moves.WATER_GUN]); await game.startBattle(); @@ -120,7 +119,7 @@ describe("Abilities - Dry Skin", () => { }); it("opposing water attacks do not heal if they were protected from", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.WATER_GUN]); + game.override.moveset([Moves.WATER_GUN]); await game.startBattle(); @@ -128,7 +127,7 @@ describe("Abilities - Dry Skin", () => { expect(enemy).not.toBe(undefined); enemy.hp = 1; - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); + game.override.enemyMoveset([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); game.doAttack(getMovePosition(game.scene, 0, Moves.WATER_GUN)); await game.phaseInterceptor.to(TurnEndPhase); @@ -136,7 +135,7 @@ describe("Abilities - Dry Skin", () => { }); it("multi-strike water attacks only heal once", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.WATER_GUN, Moves.WATER_SHURIKEN]); + game.override.moveset([Moves.WATER_GUN, Moves.WATER_SHURIKEN]); await game.startBattle(); diff --git a/src/test/abilities/hustle.test.ts b/src/test/abilities/hustle.test.ts index 853dd9bc904..63e54dfb157 100644 --- a/src/test/abilities/hustle.test.ts +++ b/src/test/abilities/hustle.test.ts @@ -1,14 +1,14 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { DamagePhase, MoveEffectPhase } from "#app/phases.js"; +import { allMoves } from "#app/data/move.js"; import { Abilities } from "#app/enums/abilities.js"; import { Stat } from "#app/enums/stat.js"; -import { allMoves } from "#app/data/move.js"; +import { DamagePhase, MoveEffectPhase } from "#app/phases.js"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Hustle", () => { let phaserGame: Phaser.Game; @@ -26,14 +26,14 @@ describe("Abilities - Hustle", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HUSTLE); - vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.GIGA_DRAIN, Moves.FISSURE]); - vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(5); - vi.spyOn(overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); - vi.spyOn(overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(5); - vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); - vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); + game.override.ability(Abilities.HUSTLE); + game.override.moveset([Moves.TACKLE, Moves.GIGA_DRAIN, Moves.FISSURE]); + game.override.startingLevel(5); + game.override.disableCrits(); + game.override.enemyLevel(5); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemySpecies(Species.SHUCKLE); + game.override.enemyAbility(Abilities.BALL_FETCH); }); it("increases the user's Attack stat by 50%", async () => { @@ -79,8 +79,8 @@ describe("Abilities - Hustle", () => { }); it("does not affect OHKO moves", async () => { - vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(30); + game.override.startingLevel(100); + game.override.enemyLevel(30); await game.startBattle([Species.PIKACHU]); const pikachu = game.scene.getPlayerPokemon(); diff --git a/src/test/abilities/ice_face.test.ts b/src/test/abilities/ice_face.test.ts index 1b00ef748eb..a08a6a01b60 100644 --- a/src/test/abilities/ice_face.test.ts +++ b/src/test/abilities/ice_face.test.ts @@ -1,19 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - MoveEffectPhase, - MoveEndPhase, - TurnEndPhase, - TurnInitPhase, -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; +import { QuietFormChangePhase } from "#app/form-change-phase"; +import { MoveEffectPhase, MoveEndPhase, TurnEndPhase, TurnInitPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; import { BattlerTagType } from "#enums/battler-tag-type"; -import { QuietFormChangePhase } from "#app/form-change-phase"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Abilities - Ice Face", () => { let phaserGame: Phaser.Game; @@ -33,10 +27,10 @@ describe("Abilities - Ice Face", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.EISCUE); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ICE_FACE); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.ICE_BEAM, Moves.TOXIC_THREAD, Moves.HAIL]); + game.override.battleType("single"); + game.override.enemySpecies(Species.EISCUE); + game.override.enemyAbility(Abilities.ICE_FACE); + game.override.moveset([Moves.TACKLE, Moves.ICE_BEAM, Moves.TOXIC_THREAD, Moves.HAIL]); }); it("takes no damage from physical move and transforms to Noice", async () => { @@ -54,8 +48,8 @@ describe("Abilities - Ice Face", () => { }); it("takes no damage from the first hit of multihit physical move and transforms to Noice", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SURGING_STRIKES]); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(1); + game.override.moveset([Moves.SURGING_STRIKES]); + game.override.enemyLevel(1); await game.startBattle([Species.HITMONLEE]); game.doAttack(getMovePosition(game.scene, 0, Moves.SURGING_STRIKES)); @@ -109,8 +103,8 @@ describe("Abilities - Ice Face", () => { }); it("transforms to Ice Face when Hail or Snow starts", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.QUICK_ATTACK]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.HAIL, Moves.HAIL, Moves.HAIL, Moves.HAIL]); + game.override.moveset([Moves.QUICK_ATTACK]); + game.override.enemyMoveset([Moves.HAIL, Moves.HAIL, Moves.HAIL, Moves.HAIL]); await game.startBattle([Species.MAGIKARP]); @@ -131,8 +125,8 @@ describe("Abilities - Ice Face", () => { }); it("transforms to Ice Face when summoned on arena with active Snow or Hail", async () => { - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SNOWSCAPE]); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.moveset([Moves.SNOWSCAPE]); await game.startBattle([Species.EISCUE, Species.NINJASK]); @@ -158,8 +152,8 @@ describe("Abilities - Ice Face", () => { }); it("will not revert to its Ice Face if there is already Hail when it changes into Noice", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemySpecies(Species.SHUCKLE); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); await game.startBattle([Species.EISCUE]); @@ -178,7 +172,7 @@ describe("Abilities - Ice Face", () => { }); it("persists form change when switched out", async () => { - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK]); + game.override.enemyMoveset([Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK]); await game.startBattle([Species.EISCUE, Species.MAGIKARP]); @@ -202,10 +196,10 @@ describe("Abilities - Ice Face", () => { }); it("reverts to Ice Face on arena reset", async () => { - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(4); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(4); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue({ + game.override.startingWave(4); + game.override.startingLevel(4); + game.override.enemySpecies(Species.MAGIKARP); + game.override.starterForms({ [Species.EISCUE]: noiceForm, }); @@ -227,7 +221,7 @@ describe("Abilities - Ice Face", () => { }); it("cannot be suppressed", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.GASTRO_ACID]); + game.override.moveset([Moves.GASTRO_ACID]); await game.startBattle([Species.MAGIKARP]); @@ -243,7 +237,7 @@ describe("Abilities - Ice Face", () => { }); it("cannot be swapped with another ability", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SKILL_SWAP]); + game.override.moveset([Moves.SKILL_SWAP]); await game.startBattle([Species.MAGIKARP]); @@ -259,7 +253,7 @@ describe("Abilities - Ice Face", () => { }); it("cannot be copied", async () => { - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.TRACE); + game.override.ability(Abilities.TRACE); await game.startBattle([Species.MAGIKARP]); diff --git a/src/test/abilities/intimidate.test.ts b/src/test/abilities/intimidate.test.ts index 2ff909def2e..2c2b68bc5df 100644 --- a/src/test/abilities/intimidate.test.ts +++ b/src/test/abilities/intimidate.test.ts @@ -1,17 +1,17 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { CommandPhase, DamagePhase, EncounterPhase, EnemyCommandPhase, SelectStarterPhase, TurnInitPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; import { Mode } from "#app/ui/ui"; import { BattleStat } from "#app/data/battle-stat"; -import { generateStarter, getMovePosition } from "#app/test/utils/gameManagerUtils"; +import { generateStarter, getMovePosition } from "#test/utils/gameManagerUtils"; import { Command } from "#app/ui/command-ui-handler"; import { Status, StatusEffect } from "#app/data/status-effect"; import { GameModes, getGameMode } from "#app/game-mode"; +import { CommandPhase, DamagePhase, EncounterPhase, EnemyCommandPhase, SelectStarterPhase, TurnInitPhase } from "#app/phases"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Intimidate", () => { let phaserGame: Phaser.Game; @@ -29,13 +29,13 @@ describe("Abilities - Intimidate", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INTIMIDATE); - vi.spyOn(Overrides, "OPP_PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INTIMIDATE); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.battleType("single"); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.INTIMIDATE); + game.override.enemyPassiveAbility(Abilities.HYDRATION); + game.override.ability(Abilities.INTIMIDATE); + game.override.startingWave(3); + game.override.enemyMoveset(SPLASH_ONLY); }); it("single - wild with switch", async () => { @@ -68,7 +68,7 @@ describe("Abilities - Intimidate", () => { }, 20000); it("single - boss should only trigger once then switch", async () => { - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(10); + game.override.startingWave(10); await game.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); game.onNextPrompt( "CheckSwitchPhase", @@ -97,7 +97,7 @@ describe("Abilities - Intimidate", () => { }, 20000); it("single - trainer should only trigger once with switch", async () => { - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override.startingWave(5); await game.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); game.onNextPrompt( "CheckSwitchPhase", @@ -126,8 +126,8 @@ describe("Abilities - Intimidate", () => { }, 200000); it("double - trainer should only trigger once per pokemon", async () => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override.battleType("double"); + game.override.startingWave(5); await game.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); game.onNextPrompt( "CheckSwitchPhase", @@ -152,8 +152,8 @@ describe("Abilities - Intimidate", () => { }, 20000); it("double - wild: should only trigger once per pokemon", async () => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); + game.override.battleType("double"); + game.override.startingWave(3); await game.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); game.onNextPrompt( "CheckSwitchPhase", @@ -178,8 +178,8 @@ describe("Abilities - Intimidate", () => { }, 20000); it("double - boss: should only trigger once per pokemon", async () => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(10); + game.override.battleType("double"); + game.override.startingWave(10); await game.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); game.onNextPrompt( "CheckSwitchPhase", @@ -204,8 +204,8 @@ describe("Abilities - Intimidate", () => { }, 20000); it("single - wild next wave opp triger once, us: none", async () => { - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(2); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.AERIAL_ACE]); + game.override.startingWave(2); + game.override.moveset([Moves.AERIAL_ACE]); await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); @@ -230,8 +230,8 @@ describe("Abilities - Intimidate", () => { }, 20000); it("single - wild next turn - no retrigger on next turn", async () => { - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(2); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); + game.override.startingWave(2); + game.override.moveset([Moves.SPLASH]); await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); @@ -254,9 +254,9 @@ describe("Abilities - Intimidate", () => { }, 20000); it("single - trainer should only trigger once and each time he switch", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.VOLT_SWITCH, Moves.VOLT_SWITCH, Moves.VOLT_SWITCH, Moves.VOLT_SWITCH]); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override.moveset([Moves.SPLASH]); + game.override.enemyMoveset([Moves.VOLT_SWITCH, Moves.VOLT_SWITCH, Moves.VOLT_SWITCH, Moves.VOLT_SWITCH]); + game.override.startingWave(5); await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); @@ -293,9 +293,9 @@ describe("Abilities - Intimidate", () => { }, 200000); it("single - trainer should only trigger once whatever turn we are", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override.moveset([Moves.SPLASH]); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.startingWave(5); await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); @@ -332,13 +332,9 @@ describe("Abilities - Intimidate", () => { }, 20000); it("double - wild vs only 1 on player side", async () => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); - vi.spyOn(Overrides, "OPP_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{ name: "COIN_CASE" }]); + game.override.battleType("double"); + game.override.startingWave(3); await game.runToSummon([Species.MIGHTYENA]); - // Get rid of any modifiers that may alter power - game.scene.clearEnemyHeldItemModifiers(); - game.scene.clearEnemyModifiers(); await game.phaseInterceptor.to(CommandPhase, false); const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); @@ -350,8 +346,8 @@ describe("Abilities - Intimidate", () => { }, 20000); it("double - wild vs only 1 alive on player side", async () => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); + game.override.battleType("double"); + game.override.startingWave(3); await game.runToTitle(); game.onNextPrompt("TitlePhase", Mode.TITLE, () => { diff --git a/src/test/abilities/intrepid_sword.test.ts b/src/test/abilities/intrepid_sword.test.ts index 1fae6555688..bc83c9bb44b 100644 --- a/src/test/abilities/intrepid_sword.test.ts +++ b/src/test/abilities/intrepid_sword.test.ts @@ -1,13 +1,10 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; +import { BattleStat } from "#app/data/battle-stat"; +import { CommandPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { Abilities } from "#enums/abilities"; +import { Species } from "#enums/species"; import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import {Abilities} from "#enums/abilities"; -import {Species} from "#enums/species"; -import { - CommandPhase, -} from "#app/phases"; -import {BattleStat} from "#app/data/battle-stat"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Abilities - Intrepid Sword", () => { @@ -26,10 +23,10 @@ describe("Abilities - Intrepid Sword", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.ZACIAN); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INTREPID_SWORD); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INTREPID_SWORD); + game.override.battleType("single"); + game.override.enemySpecies(Species.ZACIAN); + game.override.enemyAbility(Abilities.INTREPID_SWORD); + game.override.ability(Abilities.INTREPID_SWORD); }); it("INTREPID SWORD on player", async() => { diff --git a/src/test/abilities/libero.test.ts b/src/test/abilities/libero.test.ts index 015e6a44e24..c38ec082169 100644 --- a/src/test/abilities/libero.test.ts +++ b/src/test/abilities/libero.test.ts @@ -1,18 +1,18 @@ +import { allMoves } from "#app/data/move.js"; +import { Type } from "#app/data/type.js"; +import { Weather, WeatherType } from "#app/data/weather.js"; +import { PlayerPokemon } from "#app/field/pokemon.js"; +import { MoveEffectPhase, TurnEndPhase } from "#app/phases.js"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Biome } from "#enums/biome"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; -import GameManager from "../utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { Abilities } from "#enums/abilities"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "../utils/gameManagerUtils"; -import { MoveEffectPhase, TurnEndPhase } from "#app/phases.js"; -import { allMoves } from "#app/data/move.js"; -import { BattlerTagType } from "#enums/battler-tag-type"; -import { Weather, WeatherType } from "#app/data/weather.js"; -import { Type } from "#app/data/type.js"; -import { Biome } from "#enums/biome"; -import { PlayerPokemon } from "#app/field/pokemon.js"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -32,17 +32,17 @@ describe("Abilities - Protean", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.LIBERO); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.ENDURE, Moves.ENDURE, Moves.ENDURE, Moves.ENDURE]); + game.override.battleType("single"); + game.override.ability(Abilities.LIBERO); + game.override.startingLevel(100); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyMoveset([Moves.ENDURE, Moves.ENDURE, Moves.ENDURE, Moves.ENDURE]); }); test( "ability applies and changes a pokemon's type", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); + game.override.moveset([Moves.SPLASH]); await game.startBattle([Species.MAGIKARP]); @@ -60,7 +60,7 @@ describe("Abilities - Protean", () => { test.skip( "ability applies only once per switch in", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.AGILITY]); + game.override.moveset([Moves.SPLASH, Moves.AGILITY]); await game.startBattle([Species.MAGIKARP, Species.BULBASAUR]); @@ -100,7 +100,7 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move has a variable type", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.WEATHER_BALL]); + game.override.moveset([Moves.WEATHER_BALL]); await game.startBattle([Species.MAGIKARP]); @@ -123,8 +123,8 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the type has changed by another ability", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.REFRIGERATE); + game.override.moveset([Moves.TACKLE]); + game.override.passiveAbility(Abilities.REFRIGERATE); await game.startBattle([Species.MAGIKARP]); @@ -146,7 +146,7 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move calls another move", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.NATURE_POWER]); + game.override.moveset([Moves.NATURE_POWER]); await game.startBattle([Species.MAGIKARP]); @@ -165,7 +165,7 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move is delayed / charging", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DIG]); + game.override.moveset([Moves.DIG]); await game.startBattle([Species.MAGIKARP]); @@ -183,8 +183,8 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move misses", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.moveset([Moves.TACKLE]); + game.override.enemyMoveset(SPLASH_ONLY); await game.startBattle([Species.MAGIKARP]); @@ -206,8 +206,8 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move is protected against", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); + game.override.moveset([Moves.TACKLE]); + game.override.enemyMoveset([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); await game.startBattle([Species.MAGIKARP]); @@ -225,8 +225,8 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move fails because of type immunity", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.GASTLY); + game.override.moveset([Moves.TACKLE]); + game.override.enemySpecies(Species.GASTLY); await game.startBattle([Species.MAGIKARP]); @@ -244,7 +244,7 @@ describe("Abilities - Protean", () => { test( "ability is not applied if pokemon's type is the same as the move's type", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); + game.override.moveset([Moves.SPLASH]); await game.startBattle([Species.MAGIKARP]); @@ -263,7 +263,7 @@ describe("Abilities - Protean", () => { test( "ability is not applied if pokemon is terastallized", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); + game.override.moveset([Moves.SPLASH]); await game.startBattle([Species.MAGIKARP]); @@ -283,7 +283,7 @@ describe("Abilities - Protean", () => { test( "ability is not applied if pokemon uses struggle", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.STRUGGLE]); + game.override.moveset([Moves.STRUGGLE]); await game.startBattle([Species.MAGIKARP]); @@ -301,7 +301,7 @@ describe("Abilities - Protean", () => { test( "ability is not applied if the pokemon's move fails", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.BURN_UP]); + game.override.moveset([Moves.BURN_UP]); await game.startBattle([Species.MAGIKARP]); @@ -319,8 +319,8 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's Trick-or-Treat fails", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TRICK_OR_TREAT]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.GASTLY); + game.override.moveset([Moves.TRICK_OR_TREAT]); + game.override.enemySpecies(Species.GASTLY); await game.startBattle([Species.MAGIKARP]); @@ -338,7 +338,7 @@ describe("Abilities - Protean", () => { test( "ability applies correctly and the pokemon curses itself", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.CURSE]); + game.override.moveset([Moves.CURSE]); await game.startBattle([Species.MAGIKARP]); diff --git a/src/test/abilities/magic_guard.test.ts b/src/test/abilities/magic_guard.test.ts new file mode 100644 index 00000000000..18e28284f72 --- /dev/null +++ b/src/test/abilities/magic_guard.test.ts @@ -0,0 +1,471 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { Species } from "#enums/species"; +import { TurnEndPhase, MoveEffectPhase } from "#app/phases"; +import { Moves } from "#enums/moves"; +import { ArenaTagType } from "#enums/arena-tag-type"; +import { ArenaTagSide, getArenaTag } from "#app/data/arena-tag"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { WeatherType } from "#app/data/weather.js"; +import { StatusEffect, getStatusEffectCatchRateMultiplier } from "#app/data/status-effect"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; + +const TIMEOUT = 20 * 1000; // 20 sec timeout + +describe("Abilities - Magic Guard", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + /** Player Pokemon overrides */ + game.override.ability(Abilities.MAGIC_GUARD); + game.override.moveset([Moves.SPLASH]); + game.override.startingLevel(100); + + /** Enemy Pokemon overrides */ + game.override.enemySpecies(Species.SNORLAX); + game.override.enemyAbility(Abilities.INSOMNIA); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyLevel(100); + }); + + //Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/Magic_Guard_(Ability) + + it( + "ability should prevent damage caused by weather", + async () => { + game.override.weather(WeatherType.SANDSTORM); + + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + const enemyPokemon = game.scene.getEnemyPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) has not taken damage from weather + * - The enemy Pokemon (without Magic Guard) has taken damage from weather + */ + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + }, TIMEOUT + ); + + it( + "ability should prevent damage caused by status effects but other non-damage effects still apply", + async () => { + //Toxic keeps track of the turn counters -> important that Magic Guard keeps track of post-Toxic turns + game.override.statusEffect(StatusEffect.POISON); + + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) has not taken damage from poison + * - The Pokemon's CatchRateMultiplier should be 1.5 + */ + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + expect(getStatusEffectCatchRateMultiplier(leadPokemon.status.effect)).toBe(1.5); + }, TIMEOUT + ); + + it( + "ability effect should not persist when the ability is replaced", + async () => { + game.override.enemyMoveset([Moves.WORRY_SEED,Moves.WORRY_SEED,Moves.WORRY_SEED,Moves.WORRY_SEED]); + game.override.statusEffect(StatusEffect.POISON); + + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (that just lost its Magic Guard ability) has taken damage from poison + */ + expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); + }, TIMEOUT + ); + + + it("Magic Guard prevents damage caused by burn but other non-damaging effects are still applied", + async () => { + game.override.enemyStatusEffect(StatusEffect.BURN); + game.override.enemyAbility(Abilities.MAGIC_GUARD); + + await game.startBattle([Species.MAGIKARP]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + + const enemyPokemon = game.scene.getEnemyPokemon(); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The enemy Pokemon (with Magic Guard) has not taken damage from burn + * - The enemy Pokemon's physical attack damage is halved (TBD) + * - The enemy Pokemon's hypothetical CatchRateMultiplier should be 1.5 + */ + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(getStatusEffectCatchRateMultiplier(enemyPokemon.status.effect)).toBe(1.5); + }, TIMEOUT + ); + + it("Magic Guard prevents damage caused by toxic but other non-damaging effects are still applied", + async () => { + game.override.enemyStatusEffect(StatusEffect.TOXIC); + game.override.enemyAbility(Abilities.MAGIC_GUARD); + + await game.startBattle([Species.MAGIKARP]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + + const enemyPokemon = game.scene.getEnemyPokemon(); + + const toxicStartCounter = enemyPokemon.status.turnCount; + //should be 0 + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The enemy Pokemon (with Magic Guard) has not taken damage from toxic + * - The enemy Pokemon's status effect duration should be incremented + * - The enemy Pokemon's hypothetical CatchRateMultiplier should be 1.5 + */ + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + expect(enemyPokemon.status.turnCount).toBeGreaterThan(toxicStartCounter); + expect(getStatusEffectCatchRateMultiplier(enemyPokemon.status.effect)).toBe(1.5); + }, TIMEOUT + ); + + + it("Magic Guard prevents damage caused by entry hazards", async () => { + //Adds and applies Spikes to both sides of the arena + const newTag = getArenaTag(ArenaTagType.SPIKES, 5, Moves.SPIKES, 0, 0, ArenaTagSide.BOTH); + game.scene.arena.tags.push(newTag); + + await game.startBattle([Species.MAGIKARP]); + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + + const enemyPokemon = game.scene.getEnemyPokemon(); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) has not taken damage from spikes + * - The enemy Pokemon (without Magic Guard) has taken damage from spikes + */ + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + }, TIMEOUT + ); + + it("Magic Guard does not prevent poison from Toxic Spikes", async () => { + //Adds and applies Spikes to both sides of the arena + const playerTag = getArenaTag(ArenaTagType.TOXIC_SPIKES, 5, Moves.TOXIC_SPIKES, 0, 0, ArenaTagSide.PLAYER); + const enemyTag = getArenaTag(ArenaTagType.TOXIC_SPIKES, 5, Moves.TOXIC_SPIKES, 0, 0, ArenaTagSide.ENEMY); + game.scene.arena.tags.push(playerTag); + game.scene.arena.tags.push(enemyTag); + + await game.startBattle([Species.MAGIKARP]); + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + + const enemyPokemon = game.scene.getEnemyPokemon(); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - Both Pokemon gain the poison status effect + * - The player Pokemon (with Magic Guard) has not taken damage from poison + * - The enemy Pokemon (without Magic Guard) has taken damage from poison + */ + expect(leadPokemon.status.effect).toBe(StatusEffect.POISON); + expect(enemyPokemon.status.effect).toBe(StatusEffect.POISON); + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + }, TIMEOUT + ); + + it("Magic Guard prevents against damage from volatile status effects", + async () => { + await game.startBattle([Species.DUSKULL]); + game.override.moveset([Moves.CURSE]); + game.override.enemyAbility(Abilities.MAGIC_GUARD); + + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.CURSE)); + + const enemyPokemon = game.scene.getEnemyPokemon(); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) has cut its HP to inflict curse + * - The enemy Pokemon (with Magic Guard) is cursed + * - The enemy Pokemon (with Magic Guard) does not lose HP from being cursed + */ + expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); + expect(enemyPokemon.getTag(BattlerTagType.CURSED)).not.toBe(undefined); + expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); + }, TIMEOUT + ); + + it("Magic Guard prevents crash damage", async () => { + game.override.moveset([Moves.HIGH_JUMP_KICK]); + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.HIGH_JUMP_KICK)); + await game.phaseInterceptor.to(MoveEffectPhase, false); + vi.spyOn(game.scene.getCurrentPhase() as MoveEffectPhase, "hitCheck").mockReturnValueOnce(false); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) misses High Jump Kick but does not lose HP as a result + */ + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + }, TIMEOUT + ); + + it("Magic Guard prevents damage from recoil", async () => { + game.override.moveset([Moves.TAKE_DOWN]); + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.TAKE_DOWN)); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) uses a recoil move but does not lose HP from recoil + */ + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + }, TIMEOUT + ); + + it("Magic Guard does not prevent damage from Struggle's recoil", async () => { + game.override.moveset([Moves.STRUGGLE]); + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.STRUGGLE)); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) uses Struggle but does lose HP from Struggle's recoil + */ + expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); + }, TIMEOUT + ); + + //This tests different move attributes than the recoil tests above + it("Magic Guard prevents self-damage from attacking moves", async () => { + game.override.moveset([Moves.STEEL_BEAM]); + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.STEEL_BEAM)); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) uses a move with an HP cost but does not lose HP from using it + */ + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + }, TIMEOUT + ); + + /* + it("Magic Guard does not prevent self-damage from confusion", async () => { + await game.startBattle([Species.MAGIKARP]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.CHARM)); + + await game.phaseInterceptor.to(TurnEndPhase); + }); +*/ + + it("Magic Guard does not prevent self-damage from non-attacking moves", async () => { + game.override.moveset([Moves.BELLY_DRUM]); + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.BELLY_DRUM)); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) uses a non-attacking move with an HP cost and thus loses HP from using it + */ + expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); + }, TIMEOUT + ); + + it("Magic Guard prevents damage from abilities with PostTurnHurtIfSleepingAbAttr", async() => { + //Tests the ability Bad Dreams + game.override.statusEffect(StatusEffect.SLEEP); + //enemy pokemon is given Spore just in case player pokemon somehow awakens during test + game.override.enemyMoveset([Moves.SPORE, Moves.SPORE, Moves.SPORE, Moves.SPORE]); + game.override.enemyAbility(Abilities.BAD_DREAMS); + + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) should not lose HP due to this ability attribute + * - The player Pokemon is asleep + */ + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + expect(leadPokemon.status.effect).toBe(StatusEffect.SLEEP); + }, TIMEOUT + ); + + it("Magic Guard prevents damage from abilities with PostFaintContactDamageAbAttr", async() => { + //Tests the abilities Innards Out/Aftermath + game.override.moveset([Moves.TACKLE]); + game.override.enemyAbility(Abilities.AFTERMATH); + + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + const enemyPokemon = game.scene.getEnemyPokemon(); + enemyPokemon.hp = 1; + + game.doAttack(getMovePosition(game.scene, 0, Moves.TACKLE)); + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) should not lose HP due to this ability attribute + * - The enemy Pokemon has fainted + */ + expect(enemyPokemon.hp).toBe(0); + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + }, TIMEOUT + ); + + it("Magic Guard prevents damage from abilities with PostDefendContactDamageAbAttr", async() => { + //Tests the abilities Iron Barbs/Rough Skin + game.override.moveset([Moves.TACKLE]); + game.override.enemyAbility(Abilities.IRON_BARBS); + + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + const enemyPokemon = game.scene.getEnemyPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.TACKLE)); + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) should not lose HP due to this ability attribute + * - The player Pokemon's move should have connected + */ + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + }, TIMEOUT + ); + + it("Magic Guard prevents damage from abilities with ReverseDrainAbAttr", async() => { + //Tests the ability Liquid Ooze + game.override.moveset([Moves.ABSORB]); + game.override.enemyAbility(Abilities.LIQUID_OOZE); + + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + const enemyPokemon = game.scene.getEnemyPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.ABSORB)); + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) should not lose HP due to this ability attribute + * - The player Pokemon's move should have connected + */ + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + }, TIMEOUT + ); + + it("Magic Guard prevents HP loss from abilities with PostWeatherLapseDamageAbAttr", async() => { + //Tests the abilities Solar Power/Dry Skin + game.override.passiveAbility(Abilities.SOLAR_POWER); + game.override.weather(WeatherType.SUNNY); + + await game.startBattle([Species.MAGIKARP]); + const leadPokemon = game.scene.getPlayerPokemon(); + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + await game.phaseInterceptor.to(TurnEndPhase); + + /** + * Expect: + * - The player Pokemon (with Magic Guard) should not lose HP due to this ability attribute + */ + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + }, TIMEOUT + ); +}); diff --git a/src/test/abilities/moxie.test.ts b/src/test/abilities/moxie.test.ts index f7b7fe22027..f99068dea41 100644 --- a/src/test/abilities/moxie.test.ts +++ b/src/test/abilities/moxie.test.ts @@ -1,20 +1,15 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase, - EnemyCommandPhase, - VictoryPhase -} from "#app/phases"; -import {Mode} from "#app/ui/ui"; -import {Stat} from "#app/data/pokemon-stat"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; -import {Command} from "#app/ui/command-ui-handler"; -import {BattleStat} from "#app/data/battle-stat"; +import { BattleStat } from "#app/data/battle-stat"; +import { Stat } from "#app/data/pokemon-stat"; +import { CommandPhase, EnemyCommandPhase, VictoryPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; +import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Abilities - Moxie", () => { @@ -34,13 +29,13 @@ describe("Abilities - Moxie", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.AERIAL_ACE; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.MOXIE); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.MOXIE); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("single"); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.MOXIE); + game.override.ability(Abilities.MOXIE); + game.override.startingLevel(2000); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); }); it("MOXIE", async() => { diff --git a/src/test/abilities/parental_bond.test.ts b/src/test/abilities/parental_bond.test.ts index f29eafc72f6..45d65fca083 100644 --- a/src/test/abilities/parental_bond.test.ts +++ b/src/test/abilities/parental_bond.test.ts @@ -1,16 +1,16 @@ -import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; -import GameManager from "../utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { Abilities } from "#enums/abilities"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "../utils/gameManagerUtils"; -import { BerryPhase, CommandPhase, DamagePhase, MoveEffectPhase, MoveEndPhase, TurnEndPhase } from "#app/phases.js"; import { BattleStat } from "#app/data/battle-stat.js"; +import { StatusEffect } from "#app/data/status-effect.js"; import { Type } from "#app/data/type.js"; import { BattlerTagType } from "#app/enums/battler-tag-type.js"; -import { StatusEffect } from "#app/data/status-effect.js"; +import { BerryPhase, CommandPhase, DamagePhase, MoveEffectPhase, MoveEndPhase, TurnEndPhase } from "#app/phases.js"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -30,20 +30,20 @@ describe("Abilities - Parental Bond", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.PARENTAL_BOND); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); + game.override.battleType("single"); + game.override.disableCrits(); + game.override.ability(Abilities.PARENTAL_BOND); + game.override.enemySpecies(Species.SNORLAX); + game.override.enemyAbility(Abilities.INSOMNIA); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.startingLevel(100); + game.override.enemyLevel(100); }); test( "ability should add second strike to attack move", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); + game.override.moveset([Moves.TACKLE]); await game.startBattle([Species.CHARIZARD]); @@ -75,8 +75,8 @@ describe("Abilities - Parental Bond", () => { test( "ability should apply secondary effects to both strikes", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.POWER_UP_PUNCH]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.AMOONGUSS); + game.override.moveset([Moves.POWER_UP_PUNCH]); + game.override.enemySpecies(Species.AMOONGUSS); await game.startBattle([Species.CHARIZARD]); @@ -98,7 +98,7 @@ describe("Abilities - Parental Bond", () => { test( "ability should not apply to Status moves", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.BABY_DOLL_EYES]); + game.override.moveset([Moves.BABY_DOLL_EYES]); await game.startBattle([Species.CHARIZARD]); @@ -118,7 +118,7 @@ describe("Abilities - Parental Bond", () => { test( "ability should not apply to multi-hit moves", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DOUBLE_HIT]); + game.override.moveset([Moves.DOUBLE_HIT]); await game.startBattle([Species.CHARIZARD]); @@ -143,7 +143,7 @@ describe("Abilities - Parental Bond", () => { test( "ability should not apply to self-sacrifice moves", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SELF_DESTRUCT]); + game.override.moveset([Moves.SELF_DESTRUCT]); await game.startBattle([Species.CHARIZARD]); @@ -164,7 +164,7 @@ describe("Abilities - Parental Bond", () => { test( "ability should not apply to Rollout", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.ROLLOUT]); + game.override.moveset([Moves.ROLLOUT]); await game.startBattle([Species.CHARIZARD]); @@ -188,7 +188,7 @@ describe("Abilities - Parental Bond", () => { test( "ability should not apply multiplier to fixed-damage moves", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DRAGON_RAGE]); + game.override.moveset([Moves.DRAGON_RAGE]); await game.startBattle([Species.CHARIZARD]); @@ -210,8 +210,8 @@ describe("Abilities - Parental Bond", () => { test( "ability should not apply multiplier to counter moves", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.COUNTER]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.moveset([Moves.COUNTER]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); await game.startBattle([Species.CHARIZARD]); @@ -238,8 +238,8 @@ describe("Abilities - Parental Bond", () => { test( "ability should not apply to multi-target moves", async () => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.EARTHQUAKE]); + game.override.battleType("double"); + game.override.moveset([Moves.EARTHQUAKE]); await game.startBattle([Species.CHARIZARD, Species.PIDGEOT]); @@ -264,7 +264,7 @@ describe("Abilities - Parental Bond", () => { test( "ability should apply to multi-target moves when hitting only one target", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.EARTHQUAKE]); + game.override.moveset([Moves.EARTHQUAKE]); await game.startBattle([Species.CHARIZARD]); @@ -284,7 +284,7 @@ describe("Abilities - Parental Bond", () => { test( "ability should only trigger post-target move effects once", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.MIND_BLOWN]); + game.override.moveset([Moves.MIND_BLOWN]); await game.startBattle([Species.PIDGEOT]); @@ -310,7 +310,7 @@ describe("Abilities - Parental Bond", () => { test( "Burn Up only removes type after second strike with this ability", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.BURN_UP]); + game.override.moveset([Moves.BURN_UP]); await game.startBattle([Species.CHARIZARD]); @@ -337,8 +337,8 @@ describe("Abilities - Parental Bond", () => { test( "Moves boosted by this ability and Multi-Lens should strike 4 times", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "MULTI_LENS", count: 1}]); + game.override.moveset([Moves.TACKLE]); + game.override.startingHeldItems([{name: "MULTI_LENS", count: 1}]); await game.startBattle([Species.CHARIZARD]); @@ -359,8 +359,8 @@ describe("Abilities - Parental Bond", () => { test( "Super Fang boosted by this ability and Multi-Lens should strike twice", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SUPER_FANG]); - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "MULTI_LENS", count: 1}]); + game.override.moveset([Moves.SUPER_FANG]); + game.override.startingHeldItems([{name: "MULTI_LENS", count: 1}]); await game.startBattle([Species.CHARIZARD]); @@ -390,8 +390,8 @@ describe("Abilities - Parental Bond", () => { test( "Seismic Toss boosted by this ability and Multi-Lens should strike twice", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SEISMIC_TOSS]); - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "MULTI_LENS", count: 1}]); + game.override.moveset([Moves.SEISMIC_TOSS]); + game.override.startingHeldItems([{name: "MULTI_LENS", count: 1}]); await game.startBattle([Species.CHARIZARD]); @@ -421,7 +421,7 @@ describe("Abilities - Parental Bond", () => { test( "Hyper Beam boosted by this ability should strike twice, then recharge", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.HYPER_BEAM]); + game.override.moveset([Moves.HYPER_BEAM]); await game.startBattle([Species.CHARIZARD]); @@ -451,7 +451,7 @@ describe("Abilities - Parental Bond", () => { test( "Anchor Shot boosted by this ability should only trap the target after the second hit", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.ANCHOR_SHOT]); + game.override.moveset([Moves.ANCHOR_SHOT]); await game.startBattle([Species.CHARIZARD]); @@ -483,7 +483,7 @@ describe("Abilities - Parental Bond", () => { test( "Smack Down boosted by this ability should only ground the target after the second hit", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SMACK_DOWN]); + game.override.moveset([Moves.SMACK_DOWN]); await game.startBattle([Species.CHARIZARD]); @@ -512,7 +512,7 @@ describe("Abilities - Parental Bond", () => { test( "U-turn boosted by this ability should strike twice before forcing a switch", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.U_TURN]); + game.override.moveset([Moves.U_TURN]); await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); @@ -538,8 +538,7 @@ describe("Abilities - Parental Bond", () => { test( "Wake-Up Slap boosted by this ability should only wake up the target after the second hit", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.WAKE_UP_SLAP]); - vi.spyOn(Overrides, "OPP_STATUS_OVERRIDE", "get").mockReturnValue(StatusEffect.SLEEP); + game.override.moveset([Moves.WAKE_UP_SLAP]).enemyStatusEffect(StatusEffect.SLEEP); await game.startBattle([Species.CHARIZARD]); @@ -568,8 +567,8 @@ describe("Abilities - Parental Bond", () => { test( "ability should not cause user to hit into King's Shield more than once", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.KINGS_SHIELD,Moves.KINGS_SHIELD,Moves.KINGS_SHIELD,Moves.KINGS_SHIELD]); + game.override.moveset([Moves.TACKLE]); + game.override.enemyMoveset([Moves.KINGS_SHIELD,Moves.KINGS_SHIELD,Moves.KINGS_SHIELD,Moves.KINGS_SHIELD]); await game.startBattle([Species.CHARIZARD]); @@ -590,8 +589,8 @@ describe("Abilities - Parental Bond", () => { test( "ability should not cause user to hit into Storm Drain more than once", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.WATER_GUN]); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.STORM_DRAIN); + game.override.moveset([Moves.WATER_GUN]); + game.override.enemyAbility(Abilities.STORM_DRAIN); await game.startBattle([Species.CHARIZARD]); @@ -612,9 +611,9 @@ describe("Abilities - Parental Bond", () => { test( "ability should not apply to multi-target moves with Multi-Lens", async () => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.EARTHQUAKE, Moves.SPLASH]); - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "MULTI_LENS", count: 1}]); + game.override.battleType("double"); + game.override.moveset([Moves.EARTHQUAKE, Moves.SPLASH]); + game.override.startingHeldItems([{name: "MULTI_LENS", count: 1}]); await game.startBattle([Species.CHARIZARD, Species.PIDGEOT]); diff --git a/src/test/abilities/pastel_veil.test.ts b/src/test/abilities/pastel_veil.test.ts new file mode 100644 index 00000000000..8035d54a7e5 --- /dev/null +++ b/src/test/abilities/pastel_veil.test.ts @@ -0,0 +1,75 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { Species } from "#enums/species"; +import { CommandPhase, TurnEndPhase } from "#app/phases"; +import { Moves } from "#enums/moves"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { StatusEffect } from "#app/data/status-effect.js"; +import { allAbilities } from "#app/data/ability.js"; +import { Abilities } from "#app/enums/abilities.js"; +import { BattlerIndex } from "#app/battle.js"; + +describe("Abilities - Pastel Veil", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.battleType("double"); + game.override.moveset([Moves.SPLASH]); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset([Moves.TOXIC_THREAD, Moves.TOXIC_THREAD, Moves.TOXIC_THREAD, Moves.TOXIC_THREAD]); + }); + + it("prevents the user and its allies from being afflicted by poison", async () => { + await game.startBattle([Species.GALAR_PONYTA, Species.MAGIKARP]); + const ponyta = game.scene.getPlayerField()[0]; + + vi.spyOn(ponyta, "getAbility").mockReturnValue(allAbilities[Abilities.PASTEL_VEIL]); + + expect(ponyta.hasAbility(Abilities.PASTEL_VEIL)).toBe(true); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + + await game.phaseInterceptor.to(TurnEndPhase); + + expect(game.scene.getPlayerField().every(p => p.status?.effect)).toBe(false); + }); + + it("it heals the poisoned status condition of allies if user is sent out into battle", async () => { + await game.startBattle([Species.MAGIKARP, Species.MAGIKARP, Species.GALAR_PONYTA]); + const ponyta = game.scene.getParty().find(p => p.species.speciesId === Species.GALAR_PONYTA); + + vi.spyOn(ponyta, "getAbility").mockReturnValue(allAbilities[Abilities.PASTEL_VEIL]); + + expect(ponyta.hasAbility(Abilities.PASTEL_VEIL)).toBe(true); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + + await game.phaseInterceptor.to(TurnEndPhase); + expect(game.scene.getPlayerField().some(p => p.status?.effect === StatusEffect.POISON)).toBe(true); + + const poisonedMon = game.scene.getPlayerField().find(p => p.status?.effect === StatusEffect.POISON); + + await game.phaseInterceptor.to(CommandPhase); + game.doAttack(getMovePosition(game.scene, (poisonedMon.getBattlerIndex() as BattlerIndex.PLAYER | BattlerIndex.PLAYER_2), Moves.SPLASH)); + game.doSwitchPokemon(2); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(game.scene.getPlayerField().every(p => p.status?.effect)).toBe(false); + }); +}); diff --git a/src/test/abilities/power_construct.test.ts b/src/test/abilities/power_construct.test.ts index 48c92c0e2d1..769499c0e53 100644 --- a/src/test/abilities/power_construct.test.ts +++ b/src/test/abilities/power_construct.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import { Status, StatusEffect } from "#app/data/status-effect.js"; +import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { TurnEndPhase } from "#app/phases.js"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import Overrides from "#app/overrides"; -import { Moves } from "#enums/moves"; -import { Abilities } from "#enums/abilities"; -import { Species } from "#enums/species"; -import { Status, StatusEffect } from "#app/data/status-effect.js"; -import { TurnEndPhase } from "#app/phases.js"; -import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -28,10 +27,10 @@ describe("Abilities - POWER CONSTRUCT", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.POWER_CONSTRUCT); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.battleType("single"); + game.override.ability(Abilities.POWER_CONSTRUCT); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); }); test( @@ -39,8 +38,8 @@ describe("Abilities - POWER CONSTRUCT", () => { async () => { const baseForm = 2, completeForm = 4; - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(4); - vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue({ + game.override.startingWave(4); + game.override.starterForms({ [Species.ZYGARDE]: completeForm, }); diff --git a/src/test/abilities/power_spot.test.ts b/src/test/abilities/power_spot.test.ts index 1947cfc9c4f..368f8a48110 100644 --- a/src/test/abilities/power_spot.test.ts +++ b/src/test/abilities/power_spot.test.ts @@ -1,13 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; import { allMoves } from "#app/data/move.js"; -import { MoveEffectPhase, TurnEndPhase } from "#app/phases.js"; import { Abilities } from "#app/enums/abilities.js"; +import { MoveEffectPhase, TurnEndPhase } from "#app/phases.js"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Power Spot", () => { let phaserGame: Phaser.Game; @@ -27,11 +27,11 @@ describe("Abilities - Power Spot", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.BREAKING_SWIPE, Moves.SPLASH, Moves.DAZZLING_GLEAM]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); + game.override.battleType("double"); + game.override.moveset([Moves.TACKLE, Moves.BREAKING_SWIPE, Moves.SPLASH, Moves.DAZZLING_GLEAM]); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemySpecies(Species.SHUCKLE); + game.override.enemyAbility(Abilities.BALL_FETCH); }); it("raises the power of allies' special moves by 30%", async () => { @@ -40,7 +40,7 @@ describe("Abilities - Power Spot", () => { vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.startBattle([Species.PIKACHU, Species.STONJOURNER]); + await game.startBattle([Species.REGIELEKI, Species.STONJOURNER]); game.doAttack(getMovePosition(game.scene, 0, Moves.DAZZLING_GLEAM)); game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); await game.phaseInterceptor.to(MoveEffectPhase); @@ -54,7 +54,7 @@ describe("Abilities - Power Spot", () => { vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.startBattle([Species.PIKACHU, Species.STONJOURNER]); + await game.startBattle([Species.REGIELEKI, Species.STONJOURNER]); game.doAttack(getMovePosition(game.scene, 0, Moves.BREAKING_SWIPE)); game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); await game.phaseInterceptor.to(MoveEffectPhase); @@ -68,7 +68,7 @@ describe("Abilities - Power Spot", () => { vi.spyOn(moveToCheck, "calculateBattlePower"); - await game.startBattle([Species.STONJOURNER, Species.PIKACHU]); + await game.startBattle([Species.STONJOURNER, Species.REGIELEKI]); game.doAttack(getMovePosition(game.scene, 0, Moves.BREAKING_SWIPE)); game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); await game.phaseInterceptor.to(TurnEndPhase); diff --git a/src/test/abilities/protean.test.ts b/src/test/abilities/protean.test.ts index 6255a2bc2b2..7c6cca2eccd 100644 --- a/src/test/abilities/protean.test.ts +++ b/src/test/abilities/protean.test.ts @@ -1,18 +1,18 @@ +import { allMoves } from "#app/data/move.js"; +import { Type } from "#app/data/type.js"; +import { Weather, WeatherType } from "#app/data/weather.js"; +import { PlayerPokemon } from "#app/field/pokemon.js"; +import { MoveEffectPhase, TurnEndPhase } from "#app/phases.js"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Biome } from "#enums/biome"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; -import GameManager from "../utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { Abilities } from "#enums/abilities"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "../utils/gameManagerUtils"; -import { MoveEffectPhase, TurnEndPhase } from "#app/phases.js"; -import { allMoves } from "#app/data/move.js"; -import { BattlerTagType } from "#enums/battler-tag-type"; -import { Weather, WeatherType } from "#app/data/weather.js"; -import { Type } from "#app/data/type.js"; -import { Biome } from "#enums/biome"; -import { PlayerPokemon } from "#app/field/pokemon.js"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -32,17 +32,17 @@ describe("Abilities - Protean", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.PROTEAN); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.ENDURE, Moves.ENDURE, Moves.ENDURE, Moves.ENDURE]); + game.override.battleType("single"); + game.override.ability(Abilities.PROTEAN); + game.override.startingLevel(100); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyMoveset([Moves.ENDURE, Moves.ENDURE, Moves.ENDURE, Moves.ENDURE]); }); test( "ability applies and changes a pokemon's type", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); + game.override.moveset([Moves.SPLASH]); await game.startBattle([Species.MAGIKARP]); @@ -60,7 +60,7 @@ describe("Abilities - Protean", () => { test.skip( "ability applies only once per switch in", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.AGILITY]); + game.override.moveset([Moves.SPLASH, Moves.AGILITY]); await game.startBattle([Species.MAGIKARP, Species.BULBASAUR]); @@ -100,7 +100,7 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move has a variable type", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.WEATHER_BALL]); + game.override.moveset([Moves.WEATHER_BALL]); await game.startBattle([Species.MAGIKARP]); @@ -123,8 +123,8 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the type has changed by another ability", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.REFRIGERATE); + game.override.moveset([Moves.TACKLE]); + game.override.passiveAbility(Abilities.REFRIGERATE); await game.startBattle([Species.MAGIKARP]); @@ -146,7 +146,7 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move calls another move", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.NATURE_POWER]); + game.override.moveset([Moves.NATURE_POWER]); await game.startBattle([Species.MAGIKARP]); @@ -165,7 +165,7 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move is delayed / charging", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DIG]); + game.override.moveset([Moves.DIG]); await game.startBattle([Species.MAGIKARP]); @@ -183,8 +183,8 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move misses", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.moveset([Moves.TACKLE]); + game.override.enemyMoveset(SPLASH_ONLY); await game.startBattle([Species.MAGIKARP]); @@ -206,8 +206,8 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move is protected against", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); + game.override.moveset([Moves.TACKLE]); + game.override.enemyMoveset([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); await game.startBattle([Species.MAGIKARP]); @@ -225,8 +225,8 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's move fails because of type immunity", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.GASTLY); + game.override.moveset([Moves.TACKLE]); + game.override.enemySpecies(Species.GASTLY); await game.startBattle([Species.MAGIKARP]); @@ -244,7 +244,7 @@ describe("Abilities - Protean", () => { test( "ability is not applied if pokemon's type is the same as the move's type", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); + game.override.moveset([Moves.SPLASH]); await game.startBattle([Species.MAGIKARP]); @@ -263,7 +263,7 @@ describe("Abilities - Protean", () => { test( "ability is not applied if pokemon is terastallized", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); + game.override.moveset([Moves.SPLASH]); await game.startBattle([Species.MAGIKARP]); @@ -283,7 +283,7 @@ describe("Abilities - Protean", () => { test( "ability is not applied if pokemon uses struggle", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.STRUGGLE]); + game.override.moveset([Moves.STRUGGLE]); await game.startBattle([Species.MAGIKARP]); @@ -301,7 +301,7 @@ describe("Abilities - Protean", () => { test( "ability is not applied if the pokemon's move fails", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.BURN_UP]); + game.override.moveset([Moves.BURN_UP]); await game.startBattle([Species.MAGIKARP]); @@ -319,8 +319,8 @@ describe("Abilities - Protean", () => { test( "ability applies correctly even if the pokemon's Trick-or-Treat fails", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TRICK_OR_TREAT]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.GASTLY); + game.override.moveset([Moves.TRICK_OR_TREAT]); + game.override.enemySpecies(Species.GASTLY); await game.startBattle([Species.MAGIKARP]); @@ -338,7 +338,7 @@ describe("Abilities - Protean", () => { test( "ability applies correctly and the pokemon curses itself", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.CURSE]); + game.override.moveset([Moves.CURSE]); await game.startBattle([Species.MAGIKARP]); diff --git a/src/test/abilities/quick_draw.test.ts b/src/test/abilities/quick_draw.test.ts index 9e6a39b86c9..56f21cab838 100644 --- a/src/test/abilities/quick_draw.test.ts +++ b/src/test/abilities/quick_draw.test.ts @@ -1,12 +1,11 @@ -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Abilities } from "#enums/abilities"; -import { Species } from "#enums/species"; -import { FaintPhase } from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; import { allAbilities, BypassSpeedChanceAbAttr } from "#app/data/ability"; +import { FaintPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; describe("Abilities - Quick Draw", () => { @@ -25,16 +24,16 @@ describe("Abilities - Quick Draw", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.QUICK_DRAW); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TAIL_WHIP]); + game.override.starterSpecies(Species.MAGIKARP); + game.override.ability(Abilities.QUICK_DRAW); + game.override.moveset([Moves.TACKLE, Moves.TAIL_WHIP]); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(Array(4).fill(Moves.TACKLE)); + game.override.enemyLevel(100); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemyMoveset(Array(4).fill(Moves.TACKLE)); vi.spyOn(allAbilities[Abilities.QUICK_DRAW].getAttrs(BypassSpeedChanceAbAttr)[0], "chance", "get").mockReturnValue(100); }); @@ -78,7 +77,7 @@ describe("Abilities - Quick Draw", () => { ); test("does not increase priority", async () => { - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(Array(4).fill(Moves.EXTREME_SPEED)); + game.override.enemyMoveset(Array(4).fill(Moves.EXTREME_SPEED)); await game.startBattle(); diff --git a/src/test/abilities/sand_spit.test.ts b/src/test/abilities/sand_spit.test.ts new file mode 100644 index 00000000000..dacfe7ad27e --- /dev/null +++ b/src/test/abilities/sand_spit.test.ts @@ -0,0 +1,57 @@ +import GameManager from "#test/utils/gameManager"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { WeatherType } from "#app/enums/weather-type.js"; + + +describe("Ability Timing", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.battleType("single"); + game.override.disableCrits(); + + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyAbility(Abilities.BALL_FETCH); + + game.override.starterSpecies(Species.SILICOBRA); + game.override.ability(Abilities.SAND_SPIT); + game.override.moveset([Moves.SPLASH, Moves.COIL]); + }); + + it("should trigger when hit with damaging move", async() => { + game.override.enemyMoveset(Array(4).fill(Moves.TACKLE)); + await game.startBattle(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + await game.toNextTurn(); + + expect(game.scene.arena.weather.weatherType).toBe(WeatherType.SANDSTORM); + }, 20000); + + it("should not trigger when targetted with status moves", async() => { + game.override.enemyMoveset(Array(4).fill(Moves.GROWL)); + await game.startBattle(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.COIL)); + await game.toNextTurn(); + + expect(game.scene.arena.weather?.weatherType).not.toBe(WeatherType.SANDSTORM); + }, 20000); +}); diff --git a/src/test/abilities/sand_veil.test.ts b/src/test/abilities/sand_veil.test.ts index ea75027101a..6aab362634a 100644 --- a/src/test/abilities/sand_veil.test.ts +++ b/src/test/abilities/sand_veil.test.ts @@ -1,15 +1,14 @@ -import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; -import GameManager from "../utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { Abilities } from "#enums/abilities"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "../utils/gameManagerUtils"; -import { CommandPhase, MoveEffectPhase, MoveEndPhase } from "#app/phases.js"; +import { BattleStatMultiplierAbAttr, allAbilities } from "#app/data/ability.js"; import { BattleStat } from "#app/data/battle-stat.js"; import { WeatherType } from "#app/data/weather.js"; -import { BattleStatMultiplierAbAttr, allAbilities } from "#app/data/ability.js"; +import { CommandPhase, MoveEffectPhase, MoveEndPhase } from "#app/phases.js"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; const TIMEOUT = 20 * 1000; @@ -29,14 +28,15 @@ describe("Abilities - Sand Veil", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEOWSCARADA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TWISTER, Moves.TWISTER, Moves.TWISTER, Moves.TWISTER]); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "WEATHER_OVERRIDE", "get").mockReturnValue(WeatherType.SANDSTORM); + game.override.moveset([Moves.SPLASH]); + game.override.enemySpecies(Species.MEOWSCARADA); + game.override.enemyAbility(Abilities.INSOMNIA); + game.override.enemyMoveset([Moves.TWISTER, Moves.TWISTER, Moves.TWISTER, Moves.TWISTER]); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override + .weather(WeatherType.SANDSTORM) + .battleType("double"); }); test( @@ -45,10 +45,6 @@ describe("Abilities - Sand Veil", () => { await game.startBattle([Species.SNORLAX, Species.BLISSEY]); const leadPokemon = game.scene.getPlayerField(); - leadPokemon.forEach(p => expect(p).toBeDefined()); - - const enemyPokemon = game.scene.getEnemyField(); - enemyPokemon.forEach(p => expect(p).toBeDefined()); vi.spyOn(leadPokemon[0], "getAbility").mockReturnValue(allAbilities[Abilities.SAND_VEIL]); diff --git a/src/test/abilities/sap_sipper.test.ts b/src/test/abilities/sap_sipper.test.ts index 9fa2001a6ad..20a677a3244 100644 --- a/src/test/abilities/sap_sipper.test.ts +++ b/src/test/abilities/sap_sipper.test.ts @@ -1,17 +1,14 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - MoveEndPhase, TurnEndPhase, -} from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; import { BattleStat } from "#app/data/battle-stat.js"; import { TerrainType } from "#app/data/terrain.js"; +import { MoveEndPhase, TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; import { BattlerTagType } from "#enums/battler-tag-type"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; // See also: TypeImmunityAbAttr describe("Abilities - Sap Sipper", () => { @@ -30,18 +27,18 @@ describe("Abilities - Sap Sipper", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + game.override.battleType("single"); + game.override.disableCrits(); }); it("raise attack 1 level and block effects when activated against a grass attack", async() => { const moveToUse = Moves.LEAFAGE; const enemyAbility = Abilities.SAP_SIPPER; - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.DUSKULL); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(enemyAbility); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.enemySpecies(Species.DUSKULL); + game.override.enemyAbility(enemyAbility); await game.startBattle(); @@ -59,10 +56,10 @@ describe("Abilities - Sap Sipper", () => { const moveToUse = Moves.SPORE; const enemyAbility = Abilities.SAP_SIPPER; - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(enemyAbility); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(enemyAbility); await game.startBattle(); @@ -78,10 +75,10 @@ describe("Abilities - Sap Sipper", () => { const moveToUse = Moves.GRASSY_TERRAIN; const enemyAbility = Abilities.SAP_SIPPER; - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(enemyAbility); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(enemyAbility); await game.startBattle(); @@ -98,10 +95,10 @@ describe("Abilities - Sap Sipper", () => { const moveToUse = Moves.BULLET_SEED; const enemyAbility = Abilities.SAP_SIPPER; - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(enemyAbility); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(enemyAbility); await game.startBattle(); @@ -119,11 +116,11 @@ describe("Abilities - Sap Sipper", () => { const moveToUse = Moves.SPIKY_SHIELD; const ability = Abilities.SAP_SIPPER; - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(ability); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); + game.override.moveset([moveToUse]); + game.override.ability(ability); + game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.NONE); await game.startBattle(); @@ -145,10 +142,10 @@ describe("Abilities - Sap Sipper", () => { const moveToUse = Moves.METRONOME; const enemyAbility = Abilities.SAP_SIPPER; - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(enemyAbility); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(enemyAbility); await game.startBattle(); diff --git a/src/test/abilities/schooling.test.ts b/src/test/abilities/schooling.test.ts index aac8a3e793f..7671534a549 100644 --- a/src/test/abilities/schooling.test.ts +++ b/src/test/abilities/schooling.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import { Status, StatusEffect } from "#app/data/status-effect.js"; +import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { TurnEndPhase } from "#app/phases.js"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import Overrides from "#app/overrides"; -import { Moves } from "#enums/moves"; -import { Abilities } from "#enums/abilities"; -import { Species } from "#enums/species"; -import { Status, StatusEffect } from "#app/data/status-effect.js"; -import { TurnEndPhase } from "#app/phases.js"; -import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -28,10 +27,10 @@ describe("Abilities - SCHOOLING", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.SCHOOLING); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.battleType("single"); + game.override.ability(Abilities.SCHOOLING); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); }); test( @@ -39,8 +38,8 @@ describe("Abilities - SCHOOLING", () => { async () => { const soloForm = 0, schoolForm = 1; - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(4); - vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue({ + game.override.startingWave(4); + game.override.starterForms({ [Species.WISHIWASHI]: schoolForm, }); diff --git a/src/test/abilities/screen_cleaner.test.ts b/src/test/abilities/screen_cleaner.test.ts index 28253f9aaf6..a73f56dd3eb 100644 --- a/src/test/abilities/screen_cleaner.test.ts +++ b/src/test/abilities/screen_cleaner.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { PostSummonPhase, TurnEndPhase, } from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; import { ArenaTagType } from "#app/enums/arena-tag-type.js"; +import { PostSummonPhase, TurnEndPhase, } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Abilities - Screen Cleaner", () => { let phaserGame: Phaser.Game; @@ -25,14 +24,14 @@ describe("Abilities - Screen Cleaner", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.SCREEN_CLEANER); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); + game.override.battleType("single"); + game.override.ability(Abilities.SCREEN_CLEANER); + game.override.enemySpecies(Species.SHUCKLE); }); it("removes Aurora Veil", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.HAIL]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL]); + game.override.moveset([Moves.HAIL]); + game.override.enemyMoveset([Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL]); await game.startBattle([Species.MAGIKARP, Species.MAGIKARP]); @@ -49,7 +48,7 @@ describe("Abilities - Screen Cleaner", () => { }); it("removes Light Screen", async () => { - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN]); + game.override.enemyMoveset([Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN]); await game.startBattle([Species.MAGIKARP, Species.MAGIKARP]); @@ -66,7 +65,7 @@ describe("Abilities - Screen Cleaner", () => { }); it("removes Reflect", async () => { - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.REFLECT, Moves.REFLECT, Moves.REFLECT, Moves.REFLECT]); + game.override.enemyMoveset([Moves.REFLECT, Moves.REFLECT, Moves.REFLECT, Moves.REFLECT]); await game.startBattle([Species.MAGIKARP, Species.MAGIKARP]); diff --git a/src/test/abilities/serene_grace.test.ts b/src/test/abilities/serene_grace.test.ts index 6530c3ebe15..25ffc2ed2c6 100644 --- a/src/test/abilities/serene_grace.test.ts +++ b/src/test/abilities/serene_grace.test.ts @@ -1,20 +1,16 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import {Abilities} from "#enums/abilities"; -import {applyAbAttrs ,MoveEffectChanceMultiplierAbAttr} from "#app/data/ability"; -import {Species} from "#enums/species"; -import { - CommandPhase, - MoveEffectPhase, -} from "#app/phases"; -import {Mode} from "#app/ui/ui"; -import {Stat} from "#app/data/pokemon-stat"; -import {Moves} from "#enums/moves"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; -import {Command} from "#app/ui/command-ui-handler"; +import { applyAbAttrs, MoveEffectChanceMultiplierAbAttr } from "#app/data/ability"; +import { Stat } from "#app/data/pokemon-stat"; +import { CommandPhase, MoveEffectPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; +import { Mode } from "#app/ui/ui"; import * as Utils from "#app/utils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Abilities - Serene Grace", () => { @@ -34,11 +30,11 @@ describe("Abilities - Serene Grace", () => { beforeEach(() => { game = new GameManager(phaserGame); const movesToUse = [Moves.AIR_SLASH, Moves.TACKLE]; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.ONIX); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue(movesToUse); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("single"); + game.override.enemySpecies(Species.ONIX); + game.override.startingLevel(100); + game.override.moveset(movesToUse); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); }); it("Move chance without Serene Grace", async() => { @@ -76,7 +72,7 @@ describe("Abilities - Serene Grace", () => { it("Move chance with Serene Grace", async() => { const moveToUse = Moves.AIR_SLASH; - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.SERENE_GRACE); + game.override.ability(Abilities.SERENE_GRACE); await game.startBattle([ Species.TOGEKISS ]); diff --git a/src/test/abilities/sheer_force.test.ts b/src/test/abilities/sheer_force.test.ts index 46bd92f0d56..8d315e3caad 100644 --- a/src/test/abilities/sheer_force.test.ts +++ b/src/test/abilities/sheer_force.test.ts @@ -1,20 +1,16 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import {Abilities} from "#enums/abilities"; -import {applyAbAttrs ,applyPreAttackAbAttrs,applyPostDefendAbAttrs, MoveEffectChanceMultiplierAbAttr, MovePowerBoostAbAttr, PostDefendTypeChangeAbAttr} from "#app/data/ability"; -import {Species} from "#enums/species"; -import { - CommandPhase, - MoveEffectPhase, -} from "#app/phases"; -import {Mode} from "#app/ui/ui"; -import {Stat} from "#app/data/pokemon-stat"; -import {Moves} from "#enums/moves"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; -import {Command} from "#app/ui/command-ui-handler"; +import { applyAbAttrs, applyPostDefendAbAttrs, applyPreAttackAbAttrs, MoveEffectChanceMultiplierAbAttr, MovePowerBoostAbAttr, PostDefendTypeChangeAbAttr } from "#app/data/ability"; +import { Stat } from "#app/data/pokemon-stat"; +import { CommandPhase, MoveEffectPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; +import { Mode } from "#app/ui/ui"; import * as Utils from "#app/utils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Abilities - Sheer Force", () => { @@ -34,16 +30,16 @@ describe("Abilities - Sheer Force", () => { beforeEach(() => { game = new GameManager(phaserGame); const movesToUse = [Moves.AIR_SLASH, Moves.BIND, Moves.CRUSH_CLAW, Moves.TACKLE]; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.ONIX); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue(movesToUse); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("single"); + game.override.enemySpecies(Species.ONIX); + game.override.startingLevel(100); + game.override.moveset(movesToUse); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); }); it("Sheer Force", async() => { const moveToUse = Moves.AIR_SLASH; - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.SHEER_FORCE); + game.override.ability(Abilities.SHEER_FORCE); await game.startBattle([ Species.PIDGEOT ]); @@ -82,7 +78,7 @@ describe("Abilities - Sheer Force", () => { it("Sheer Force with exceptions including binding moves", async() => { const moveToUse = Moves.BIND; - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.SHEER_FORCE); + game.override.ability(Abilities.SHEER_FORCE); await game.startBattle([ Species.PIDGEOT ]); @@ -121,7 +117,7 @@ describe("Abilities - Sheer Force", () => { it("Sheer Force with moves with no secondary effect", async() => { const moveToUse = Moves.TACKLE; - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.SHEER_FORCE); + game.override.ability(Abilities.SHEER_FORCE); await game.startBattle([ Species.PIDGEOT ]); @@ -160,9 +156,9 @@ describe("Abilities - Sheer Force", () => { it("Sheer Force Disabling Specific Abilities", async() => { const moveToUse = Moves.CRUSH_CLAW; - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.COLOR_CHANGE); - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "KINGS_ROCK", count: 1}]); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.SHEER_FORCE); + game.override.enemyAbility(Abilities.COLOR_CHANGE); + game.override.startingHeldItems([{name: "KINGS_ROCK", count: 1}]); + game.override.ability(Abilities.SHEER_FORCE); await game.startBattle([ Species.PIDGEOT ]); diff --git a/src/test/abilities/shield_dust.test.ts b/src/test/abilities/shield_dust.test.ts index 472ba90caf9..6050e6d4c9a 100644 --- a/src/test/abilities/shield_dust.test.ts +++ b/src/test/abilities/shield_dust.test.ts @@ -1,20 +1,16 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Abilities } from "#enums/abilities"; -import {applyAbAttrs ,applyPreDefendAbAttrs,IgnoreMoveEffectsAbAttr,MoveEffectChanceMultiplierAbAttr} from "#app/data/ability"; -import {Species} from "#enums/species"; -import { - CommandPhase, - MoveEffectPhase, -} from "#app/phases"; -import {Mode} from "#app/ui/ui"; -import {Stat} from "#app/data/pokemon-stat"; -import {Moves} from "#enums/moves"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; -import {Command} from "#app/ui/command-ui-handler"; +import { applyAbAttrs, applyPreDefendAbAttrs, IgnoreMoveEffectsAbAttr, MoveEffectChanceMultiplierAbAttr } from "#app/data/ability"; +import { Stat } from "#app/data/pokemon-stat"; +import { CommandPhase, MoveEffectPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; +import { Mode } from "#app/ui/ui"; import * as Utils from "#app/utils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Abilities - Shield Dust", () => { @@ -34,12 +30,12 @@ describe("Abilities - Shield Dust", () => { beforeEach(() => { game = new GameManager(phaserGame); const movesToUse = [Moves.AIR_SLASH]; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.ONIX); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.SHIELD_DUST); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue(movesToUse); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("single"); + game.override.enemySpecies(Species.ONIX); + game.override.enemyAbility(Abilities.SHIELD_DUST); + game.override.startingLevel(100); + game.override.moveset(movesToUse); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); }); it("Shield Dust", async() => { diff --git a/src/test/abilities/shields_down.test.ts b/src/test/abilities/shields_down.test.ts index 881a3f4911f..64904c80032 100644 --- a/src/test/abilities/shields_down.test.ts +++ b/src/test/abilities/shields_down.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import { Status, StatusEffect } from "#app/data/status-effect.js"; +import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { TurnEndPhase } from "#app/phases.js"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import Overrides from "#app/overrides"; -import { Moves } from "#enums/moves"; -import { Abilities } from "#enums/abilities"; -import { Species } from "#enums/species"; -import { Status, StatusEffect } from "#app/data/status-effect.js"; -import { TurnEndPhase } from "#app/phases.js"; -import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -28,10 +27,10 @@ describe("Abilities - SHIELDS DOWN", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.SHIELDS_DOWN); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.battleType("single"); + game.override.ability(Abilities.SHIELDS_DOWN); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); }); test( @@ -39,8 +38,8 @@ describe("Abilities - SHIELDS DOWN", () => { async () => { const meteorForm = 0, coreForm = 7; - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(4); - vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue({ + game.override.startingWave(4); + game.override.starterForms({ [Species.MINIOR]: coreForm, }); diff --git a/src/test/abilities/steely_spirit.test.ts b/src/test/abilities/steely_spirit.test.ts index 3e9993a7465..e21067539df 100644 --- a/src/test/abilities/steely_spirit.test.ts +++ b/src/test/abilities/steely_spirit.test.ts @@ -1,14 +1,14 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { allMoves } from "#app/data/move.js"; import { allAbilities } from "#app/data/ability.js"; +import { allMoves } from "#app/data/move.js"; import { Abilities } from "#app/enums/abilities.js"; import { MoveEffectPhase, SelectTargetPhase } from "#app/phases.js"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Steely Spirit", () => { let phaserGame: Phaser.Game; @@ -29,11 +29,11 @@ describe("Abilities - Steely Spirit", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.IRON_HEAD, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.battleType("double"); + game.override.enemySpecies(Species.SHUCKLE); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.moveset([Moves.IRON_HEAD, Moves.SPLASH]); + game.override.enemyMoveset(SPLASH_ONLY); vi.spyOn(allMoves[moveToCheck], "calculateBattlePower"); }); diff --git a/src/test/abilities/sturdy.test.ts b/src/test/abilities/sturdy.test.ts index 0cfa45ef843..4caa7b0bd14 100644 --- a/src/test/abilities/sturdy.test.ts +++ b/src/test/abilities/sturdy.test.ts @@ -1,16 +1,12 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, test, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - DamagePhase, - MoveEndPhase, -} from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { EnemyPokemon } from "#app/field/pokemon.js"; +import { DamagePhase, MoveEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { EnemyPokemon } from "#app/field/pokemon.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -30,15 +26,15 @@ describe("Abilities - Sturdy", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.LUCARIO); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.CLOSE_COMBAT, Moves.FISSURE]); + game.override.starterSpecies(Species.LUCARIO); + game.override.startingLevel(100); + game.override.moveset([Moves.CLOSE_COMBAT, Moves.FISSURE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.ARON); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(5); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.STURDY); + game.override.enemySpecies(Species.ARON); + game.override.enemyLevel(5); + game.override.enemyAbility(Abilities.STURDY); }); test( @@ -85,7 +81,7 @@ describe("Abilities - Sturdy", () => { test( "Sturdy is ignored by pokemon with `Abilities.MOLD_BREAKER`", async () => { - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.MOLD_BREAKER); + game.override.ability(Abilities.MOLD_BREAKER); await game.startBattle(); game.doAttack(getMovePosition(game.scene, 0, Moves.CLOSE_COMBAT)); diff --git a/src/test/abilities/sweet_veil.test.ts b/src/test/abilities/sweet_veil.test.ts new file mode 100644 index 00000000000..19c1210b443 --- /dev/null +++ b/src/test/abilities/sweet_veil.test.ts @@ -0,0 +1,103 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { Species } from "#enums/species"; +import { CommandPhase, MoveEffectPhase, MovePhase, TurnEndPhase } from "#app/phases"; +import { Moves } from "#enums/moves"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { BattlerTagType } from "#app/enums/battler-tag-type.js"; +import { Abilities } from "#app/enums/abilities.js"; +import { BattlerIndex } from "#app/battle.js"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; + +describe("Abilities - Sweet Veil", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.battleType("double"); + game.override.moveset([Moves.SPLASH, Moves.REST]); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemyMoveset([Moves.POWDER, Moves.POWDER, Moves.POWDER, Moves.POWDER]); + }); + + it("prevents the user and its allies from falling asleep", async () => { + await game.startBattle([Species.SWIRLIX, Species.MAGIKARP]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + + await game.phaseInterceptor.to(TurnEndPhase); + + expect(game.scene.getPlayerField().every(p => p.status?.effect)).toBe(false); + }); + + it("causes Rest to fail when used by the user or its allies", async () => { + game.override.enemyMoveset(SPLASH_ONLY); + await game.startBattle([Species.SWIRLIX, Species.MAGIKARP]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + game.doAttack(getMovePosition(game.scene, 1, Moves.REST)); + + await game.phaseInterceptor.to(TurnEndPhase); + + expect(game.scene.getPlayerField().every(p => p.status?.effect)).toBe(false); + }); + + it("causes Yawn to fail if used on the user or its allies", async () => { + game.override.enemyMoveset([Moves.YAWN, Moves.YAWN, Moves.YAWN, Moves.YAWN]); + await game.startBattle([Species.SWIRLIX, Species.MAGIKARP]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + + await game.phaseInterceptor.to(TurnEndPhase); + + expect(game.scene.getPlayerField().every(p => !!p.getTag(BattlerTagType.DROWSY))).toBe(false); + }); + + it("prevents the user and its allies already drowsy due to Yawn from falling asleep.", async () => { + game.override.enemySpecies(Species.PIKACHU); + game.override.enemyLevel(5); + game.override.startingLevel(5); + game.override.enemyMoveset([Moves.YAWN, Moves.YAWN, Moves.YAWN, Moves.YAWN]); + + await game.startBattle([Species.SHUCKLE, Species.SHUCKLE, Species.SWIRLIX]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + + // First pokemon move + await game.phaseInterceptor.to(MoveEffectPhase, false); + vi.spyOn(game.scene.getCurrentPhase() as MoveEffectPhase, "hitCheck").mockReturnValueOnce(true); + + // Second pokemon move + await game.phaseInterceptor.to(MovePhase, false); + await game.phaseInterceptor.to(MoveEffectPhase, false); + vi.spyOn(game.scene.getCurrentPhase() as MoveEffectPhase, "hitCheck").mockReturnValueOnce(true); + + expect(game.scene.getPlayerField().some(p => !!p.getTag(BattlerTagType.DROWSY))).toBe(true); + + await game.phaseInterceptor.to(TurnEndPhase); + + const drowsyMon = game.scene.getPlayerField().find(p => !!p.getTag(BattlerTagType.DROWSY)); + + await game.phaseInterceptor.to(CommandPhase); + game.doAttack(getMovePosition(game.scene, (drowsyMon.getBattlerIndex() as BattlerIndex.PLAYER | BattlerIndex.PLAYER_2), Moves.SPLASH)); + game.doSwitchPokemon(2); + + expect(game.scene.getPlayerField().every(p => p.status?.effect)).toBe(false); + }); +}); diff --git a/src/test/abilities/unseen_fist.test.ts b/src/test/abilities/unseen_fist.test.ts index e6025cb0a6a..0ee4dbef513 100644 --- a/src/test/abilities/unseen_fist.test.ts +++ b/src/test/abilities/unseen_fist.test.ts @@ -1,12 +1,11 @@ -import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; -import GameManager from "../utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; +import { TurnEndPhase } from "#app/phases.js"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; -import { getMovePosition } from "../utils/gameManagerUtils"; -import { TurnEndPhase } from "#app/phases.js"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; const TIMEOUT = 20 * 1000; @@ -26,12 +25,12 @@ describe("Abilities - Unseen Fist", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.URSHIFU); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); + game.override.battleType("single"); + game.override.starterSpecies(Species.URSHIFU); + game.override.enemySpecies(Species.SNORLAX); + game.override.enemyMoveset([Moves.PROTECT, Moves.PROTECT, Moves.PROTECT, Moves.PROTECT]); + game.override.startingLevel(100); + game.override.enemyLevel(100); }); test( @@ -49,7 +48,7 @@ describe("Abilities - Unseen Fist", () => { test( "ability does not apply if the source has Long Reach", () => { - vi.spyOn(Overrides, "PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.LONG_REACH); + game.override.passiveAbility(Abilities.LONG_REACH); testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, false); }, TIMEOUT ); @@ -68,8 +67,8 @@ describe("Abilities - Unseen Fist", () => { }); async function testUnseenFistHitResult(game: GameManager, attackMove: Moves, protectMove: Moves, shouldSucceed: boolean = true): Promise { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([attackMove]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([protectMove, protectMove, protectMove, protectMove]); + game.override.moveset([attackMove]); + game.override.enemyMoveset([protectMove, protectMove, protectMove, protectMove]); await game.startBattle(); diff --git a/src/test/abilities/volt_absorb.test.ts b/src/test/abilities/volt_absorb.test.ts index e8c47e1420e..985459e133b 100644 --- a/src/test/abilities/volt_absorb.test.ts +++ b/src/test/abilities/volt_absorb.test.ts @@ -1,16 +1,13 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - TurnEndPhase, -} from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; import { BattleStat } from "#app/data/battle-stat.js"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; import { BattlerTagType } from "#enums/battler-tag-type"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; // See also: TypeImmunityAbAttr describe("Abilities - Volt Absorb", () => { @@ -29,19 +26,19 @@ describe("Abilities - Volt Absorb", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + game.override.battleType("single"); + game.override.disableCrits(); }); it("does not activate when CHARGE is used", async () => { const moveToUse = Moves.CHARGE; const ability = Abilities.VOLT_ABSORB; - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(ability); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.DUSKULL); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); + game.override.moveset([moveToUse]); + game.override.ability(ability); + game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.enemySpecies(Species.DUSKULL); + game.override.enemyAbility(Abilities.BALL_FETCH); await game.startBattle(); diff --git a/src/test/abilities/wind_power.test.ts b/src/test/abilities/wind_power.test.ts index 84869bd54a8..8a4c2969cc4 100644 --- a/src/test/abilities/wind_power.test.ts +++ b/src/test/abilities/wind_power.test.ts @@ -1,15 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - TurnEndPhase, -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; import { BattlerTagType } from "#app/enums/battler-tag-type.js"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Wind Power", () => { let phaserGame: Phaser.Game; @@ -27,11 +25,11 @@ describe("Abilities - Wind Power", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHIFTRY); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.WIND_POWER); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.battleType("single"); + game.override.enemySpecies(Species.SHIFTRY); + game.override.enemyAbility(Abilities.WIND_POWER); + game.override.moveset([Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM]); + game.override.enemyMoveset(SPLASH_ONLY); }); it("it becomes charged when hit by wind moves", async () => { @@ -47,8 +45,8 @@ describe("Abilities - Wind Power", () => { }); it("it becomes charged when Tailwind takes effect on its side", async () => { - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.WIND_POWER); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); + game.override.ability(Abilities.WIND_POWER); + game.override.enemySpecies(Species.MAGIKARP); await game.startBattle([Species.SHIFTRY]); const shiftry = game.scene.getPlayerPokemon(); @@ -62,8 +60,8 @@ describe("Abilities - Wind Power", () => { }); it("does not become charged when Tailwind takes effect on opposing side", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.WIND_POWER); + game.override.enemySpecies(Species.MAGIKARP); + game.override.ability(Abilities.WIND_POWER); await game.startBattle([Species.SHIFTRY]); const magikarp = game.scene.getEnemyPokemon(); @@ -81,7 +79,7 @@ describe("Abilities - Wind Power", () => { }); it("does not interact with Sandstorm", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); + game.override.enemySpecies(Species.MAGIKARP); await game.startBattle([Species.SHIFTRY]); const shiftry = game.scene.getPlayerPokemon(); diff --git a/src/test/abilities/wind_rider.test.ts b/src/test/abilities/wind_rider.test.ts index d578c5a22dc..855def63b6f 100644 --- a/src/test/abilities/wind_rider.test.ts +++ b/src/test/abilities/wind_rider.test.ts @@ -1,15 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - TurnEndPhase, -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; import { BattleStat } from "#app/data/battle-stat.js"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Wind Rider", () => { let phaserGame: Phaser.Game; @@ -27,11 +25,11 @@ describe("Abilities - Wind Rider", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHIFTRY); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.WIND_RIDER); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.battleType("single"); + game.override.enemySpecies(Species.SHIFTRY); + game.override.enemyAbility(Abilities.WIND_RIDER); + game.override.moveset([Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM]); + game.override.enemyMoveset(SPLASH_ONLY); }); it("takes no damage from wind moves and its Attack is increased by one stage when hit by one", async () => { @@ -49,8 +47,8 @@ describe("Abilities - Wind Rider", () => { }); it("Attack is increased by one stage when Tailwind is present on its side", async () => { - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.WIND_RIDER); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); + game.override.ability(Abilities.WIND_RIDER); + game.override.enemySpecies(Species.MAGIKARP); await game.startBattle([Species.SHIFTRY]); const shiftry = game.scene.getPlayerPokemon(); @@ -65,8 +63,8 @@ describe("Abilities - Wind Rider", () => { }); it("does not increase Attack when Tailwind is present on opposing side", async () => { - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.WIND_RIDER); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); + game.override.ability(Abilities.WIND_RIDER); + game.override.enemySpecies(Species.MAGIKARP); await game.startBattle([Species.SHIFTRY]); const magikarp = game.scene.getEnemyPokemon(); @@ -84,7 +82,7 @@ describe("Abilities - Wind Rider", () => { }); it("does not increase Attack when Tailwind is present on opposing side", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); + game.override.enemySpecies(Species.MAGIKARP); await game.startBattle([Species.SHIFTRY]); const magikarp = game.scene.getEnemyPokemon(); @@ -102,7 +100,7 @@ describe("Abilities - Wind Rider", () => { }); it("does not interact with Sandstorm", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); + game.override.enemySpecies(Species.MAGIKARP); await game.startBattle([Species.SHIFTRY]); const shiftry = game.scene.getPlayerPokemon(); diff --git a/src/test/abilities/wonder_skin.test.ts b/src/test/abilities/wonder_skin.test.ts index cd23b2c359f..a2815152df6 100644 --- a/src/test/abilities/wonder_skin.test.ts +++ b/src/test/abilities/wonder_skin.test.ts @@ -1,14 +1,14 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { MoveEffectPhase } from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; -import { allMoves } from "#app/data/move.js"; import { allAbilities } from "#app/data/ability.js"; +import { allMoves } from "#app/data/move.js"; +import { MoveEffectPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Wonder Skin", () => { let phaserGame: Phaser.Game; @@ -26,12 +26,12 @@ describe("Abilities - Wonder Skin", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.CHARM]); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.WONDER_SKIN); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.battleType("single"); + game.override.moveset([Moves.TACKLE, Moves.CHARM]); + game.override.ability(Abilities.BALL_FETCH); + game.override.enemySpecies(Species.SHUCKLE); + game.override.enemyAbility(Abilities.WONDER_SKIN); + game.override.enemyMoveset(SPLASH_ONLY); }); it("lowers accuracy of status moves to 50%", async () => { @@ -64,7 +64,7 @@ describe("Abilities - Wonder Skin", () => { it(`does not affect pokemon with ${allAbilities[ability].name}`, async () => { const moveToCheck = allMoves[Moves.CHARM]; - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(ability); + game.override.ability(ability); vi.spyOn(moveToCheck, "calculateBattleAccuracy"); await game.startBattle([Species.PIKACHU]); diff --git a/src/test/abilities/zen_mode.test.ts b/src/test/abilities/zen_mode.test.ts index dae01b7aa89..f11694b061c 100644 --- a/src/test/abilities/zen_mode.test.ts +++ b/src/test/abilities/zen_mode.test.ts @@ -1,28 +1,16 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase, - DamagePhase, - EnemyCommandPhase, - MessagePhase, - PostSummonPhase, - SwitchPhase, - SwitchSummonPhase, - TurnEndPhase, - TurnInitPhase, - TurnStartPhase, -} from "#app/phases"; -import { Mode } from "#app/ui/ui"; import { Stat } from "#app/data/pokemon-stat"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Command } from "#app/ui/command-ui-handler"; -import { QuietFormChangePhase } from "#app/form-change-phase"; import { Status, StatusEffect } from "#app/data/status-effect.js"; +import { QuietFormChangePhase } from "#app/form-change-phase"; +import { CommandPhase, DamagePhase, EnemyCommandPhase, MessagePhase, PostSummonPhase, SwitchPhase, SwitchSummonPhase, TurnEndPhase, TurnInitPhase, TurnStartPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; +import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -43,13 +31,13 @@ describe("Abilities - ZEN MODE", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZEN_MODE); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.battleType("single"); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.ability(Abilities.ZEN_MODE); + game.override.startingLevel(100); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); }); test( @@ -153,8 +141,8 @@ describe("Abilities - ZEN MODE", () => { async () => { const baseForm = 0, zenForm = 1; - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(4); - vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue({ + game.override.startingWave(4); + game.override.starterForms({ [Species.DARMANITAN]: zenForm, }); diff --git a/src/test/abilities/zero_to_hero.test.ts b/src/test/abilities/zero_to_hero.test.ts index 6e82f151f15..409fb35a78c 100644 --- a/src/test/abilities/zero_to_hero.test.ts +++ b/src/test/abilities/zero_to_hero.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import { Status, StatusEffect } from "#app/data/status-effect.js"; +import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { TurnEndPhase } from "#app/phases.js"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import Overrides from "#app/overrides"; -import { Moves } from "#enums/moves"; -import { Abilities } from "#enums/abilities"; -import { Species } from "#enums/species"; -import { Status, StatusEffect } from "#app/data/status-effect.js"; -import { TurnEndPhase } from "#app/phases.js"; -import { QuietFormChangePhase } from "#app/form-change-phase.js"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -28,10 +27,10 @@ describe("Abilities - ZERO TO HERO", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZERO_TO_HERO); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.battleType("single"); + game.override.ability(Abilities.ZERO_TO_HERO); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); }); test( @@ -39,8 +38,8 @@ describe("Abilities - ZERO TO HERO", () => { async () => { const baseForm = 0, heroForm = 1; - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(4); - vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue({ + game.override.startingWave(4); + game.override.starterForms({ [Species.PALAFIN]: heroForm, }); diff --git a/src/test/achievements/achievement.test.ts b/src/test/achievements/achievement.test.ts index f5a7416e809..14466a71086 100644 --- a/src/test/achievements/achievement.test.ts +++ b/src/test/achievements/achievement.test.ts @@ -1,11 +1,10 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import {MoneyAchv, Achv, AchvTier, RibbonAchv, DamageAchv, HealAchv, LevelAchv, ModifierAchv, achvs} from "#app/system/achv"; -import BattleScene from "../../battle-scene"; -import { IntegerHolder, NumberHolder } from "#app/utils.js"; import { TurnHeldItemTransferModifier } from "#app/modifier/modifier.js"; +import { Achv, AchvTier, DamageAchv, HealAchv, LevelAchv, ModifierAchv, MoneyAchv, RibbonAchv, achvs } from "#app/system/achv"; +import GameManager from "#test/utils/gameManager"; +import { IntegerHolder, NumberHolder } from "#app/utils.js"; import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import BattleScene from "../../battle-scene"; describe("check some Achievement related stuff", () => { it ("should check Achievement creation", () => { @@ -103,13 +102,13 @@ describe("RibbonAchv", () => { }); beforeEach(() => { - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(0); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(0); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(0); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(0); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([]); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([]); game = new GameManager(phaserGame); + game.override.moveset([]); + game.override.startingLevel(0); + game.override.starterSpecies(0); + game.override.enemyMoveset([]); + game.override.enemySpecies(0); + game.override.startingWave(0); scene = game.scene; }); diff --git a/src/test/arena/arena_gravity.test.ts b/src/test/arena/arena_gravity.test.ts index ae944758bc7..66d6994fb80 100644 --- a/src/test/arena/arena_gravity.test.ts +++ b/src/test/arena/arena_gravity.test.ts @@ -1,17 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - MoveEffectPhase, - TurnEndPhase, -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; import { allMoves } from "#app/data/move.js"; -import { ArenaTagType } from "#app/enums/arena-tag-type.js"; import { Abilities } from "#app/enums/abilities.js"; +import { ArenaTagType } from "#app/enums/arena-tag-type.js"; +import { MoveEffectPhase, TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Arena - Gravity", () => { let phaserGame: Phaser.Game; @@ -29,12 +25,12 @@ describe("Arena - Gravity", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.GRAVITY, Moves.FISSURE]); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.UNNERVE); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(new Array(4).fill(Moves.SPLASH)); + game.override.battleType("single"); + game.override.moveset([Moves.TACKLE, Moves.GRAVITY, Moves.FISSURE]); + game.override.ability(Abilities.UNNERVE); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemySpecies(Species.SHUCKLE); + game.override.enemyMoveset(new Array(4).fill(Moves.SPLASH)); }); it("non-OHKO move accuracy is multiplied by 1.67", async () => { @@ -58,8 +54,8 @@ describe("Arena - Gravity", () => { }); it("OHKO move accuracy is not affected", async () => { - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(5); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(5); + game.override.startingLevel(5); + game.override.enemyLevel(5); /** See Fissure {@link https://bulbapedia.bulbagarden.net/wiki/Fissure_(move)} */ const moveToCheck = allMoves[Moves.FISSURE]; diff --git a/src/test/arena/weather_fog.test.ts b/src/test/arena/weather_fog.test.ts index 85a9e334c45..e5718b73a3c 100644 --- a/src/test/arena/weather_fog.test.ts +++ b/src/test/arena/weather_fog.test.ts @@ -1,16 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - MoveEffectPhase, -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; import { allMoves } from "#app/data/move.js"; import { WeatherType } from "#app/data/weather.js"; import { Abilities } from "#app/enums/abilities.js"; +import { MoveEffectPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Weather - Fog", () => { let phaserGame: Phaser.Game; @@ -28,13 +25,14 @@ describe("Weather - Fog", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "WEATHER_OVERRIDE", "get").mockReturnValue(WeatherType.FOG); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(new Array(4).fill(Moves.SPLASH)); + game.override + .weather(WeatherType.FOG) + .battleType("single"); + game.override.moveset([Moves.TACKLE]); + game.override.ability(Abilities.BALL_FETCH); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset(new Array(4).fill(Moves.SPLASH)); }); it("move accuracy is multiplied by 90%", async () => { diff --git a/src/test/arena/weather_strong_winds.test.ts b/src/test/arena/weather_strong_winds.test.ts index 906d6c71b0d..0fd45173033 100644 --- a/src/test/arena/weather_strong_winds.test.ts +++ b/src/test/arena/weather_strong_winds.test.ts @@ -1,15 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - TurnStartPhase, -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; import { allMoves } from "#app/data/move.js"; +import { TurnStartPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Weather - Strong Winds", () => { let phaserGame: Phaser.Game; @@ -27,15 +24,15 @@ describe("Weather - Strong Winds", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(10); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.TAILLOW); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.DELTA_STREAM); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.THUNDERBOLT, Moves.ICE_BEAM, Moves.ROCK_SLIDE]); + game.override.battleType("single"); + game.override.startingLevel(10); + game.override.enemySpecies(Species.TAILLOW); + game.override.enemyAbility(Abilities.DELTA_STREAM); + game.override.moveset([Moves.THUNDERBOLT, Moves.ICE_BEAM, Moves.ROCK_SLIDE]); }); it("electric type move is not very effective on Rayquaza", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RAYQUAZA); + game.override.enemySpecies(Species.RAYQUAZA); await game.startBattle([Species.PIKACHU]); const pikachu = game.scene.getPlayerPokemon(); diff --git a/src/test/battle-scene.test.ts b/src/test/battle-scene.test.ts new file mode 100644 index 00000000000..21d3f689d1c --- /dev/null +++ b/src/test/battle-scene.test.ts @@ -0,0 +1,27 @@ +import { LoadingScene } from "#app/loading-scene.js"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import GameManager from "./utils/gameManager"; + +describe("BattleScene", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + it("should remove LoadingScene on create", () => { + // `BattleScene.create()` is called during the `new GameManager()` call + expect(game.scene.scene.remove).toHaveBeenCalledWith(LoadingScene.KEY); + }); +}); diff --git a/src/test/battle-stat.spec.ts b/src/test/battle-stat.spec.ts index 46f25f66bcd..775dd40ff34 100644 --- a/src/test/battle-stat.spec.ts +++ b/src/test/battle-stat.spec.ts @@ -1,8 +1,4 @@ -import { - BattleStat, - getBattleStatLevelChangeDescription, - getBattleStatName, -} from "#app/data/battle-stat.js"; +import { BattleStat, getBattleStatLevelChangeDescription, getBattleStatName } from "#app/data/battle-stat.js"; import { describe, expect, it } from "vitest"; import { arrayOfRange, mockI18next } from "./utils/testUtils"; diff --git a/src/test/battle/battle-order.test.ts b/src/test/battle/battle-order.test.ts index 0a6b9473ff1..6aa919186b4 100644 --- a/src/test/battle/battle-order.test.ts +++ b/src/test/battle/battle-order.test.ts @@ -1,20 +1,16 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase, EnemyCommandPhase, SelectTargetPhase, - TurnStartPhase -} from "#app/phases"; -import {Mode} from "#app/ui/ui"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; -import {Command} from "#app/ui/command-ui-handler"; -import {Stat} from "#app/data/pokemon-stat"; +import { Stat } from "#app/data/pokemon-stat"; +import { CommandPhase, EnemyCommandPhase, SelectTargetPhase, TurnStartPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; import TargetSelectUiHandler from "#app/ui/target-select-ui-handler"; +import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; +import { Button } from "#enums/buttons"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import {Button} from "#enums/buttons"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Battle order", () => { @@ -33,11 +29,11 @@ describe("Battle order", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); + game.override.battleType("single"); + game.override.enemySpecies(Species.MEWTWO); + game.override.enemyAbility(Abilities.INSOMNIA); + game.override.ability(Abilities.INSOMNIA); + game.override.moveset([Moves.TACKLE]); }); it("opponent faster than player 50 vs 150", async() => { @@ -83,7 +79,7 @@ describe("Battle order", () => { }, 20000); it("double - both opponents faster than player 50/50 vs 150/150", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); + game.override.battleType("double"); await game.startBattle([ Species.BULBASAUR, Species.BLASTOISE, @@ -125,7 +121,7 @@ describe("Battle order", () => { }, 20000); it("double - speed tie except 1 - 100/100 vs 100/150", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); + game.override.battleType("double"); await game.startBattle([ Species.BULBASAUR, Species.BLASTOISE, @@ -166,7 +162,7 @@ describe("Battle order", () => { }, 20000); it("double - speed tie 100/150 vs 100/150", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); + game.override.battleType("double"); await game.startBattle([ Species.BULBASAUR, Species.BLASTOISE, diff --git a/src/test/battle/battle.test.ts b/src/test/battle/battle.test.ts index 436b3227791..35eae9b96d2 100644 --- a/src/test/battle/battle.test.ts +++ b/src/test/battle/battle.test.ts @@ -1,29 +1,17 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import {generateStarter, getMovePosition,} from "#app/test/utils/gameManagerUtils"; -import {Mode} from "#app/ui/ui"; -import {GameModes} from "#app/game-mode"; -import Overrides from "#app/overrides"; -import {Command} from "#app/ui/command-ui-handler"; -import { - CommandPhase, DamagePhase, - EncounterPhase, - EnemyCommandPhase, - LoginPhase, - SelectGenderPhase, - SelectModifierPhase, - SelectStarterPhase, - SummonPhase, - TitlePhase, - TurnInitPhase, VictoryPhase, -} from "#app/phases"; -import GameManager from "#app/test/utils/gameManager"; -import Phaser from "phaser"; -import {allSpecies} from "#app/data/pokemon-species"; +import { allSpecies } from "#app/data/pokemon-species"; +import { GameModes } from "#app/game-mode"; import { getGameMode } from "#app/game-mode.js"; +import { CommandPhase, DamagePhase, EncounterPhase, EnemyCommandPhase, LoginPhase, SelectGenderPhase, SelectModifierPhase, SelectStarterPhase, SummonPhase, TitlePhase, TurnInitPhase, VictoryPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { generateStarter, getMovePosition, } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; +import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { PlayerGender } from "#enums/player-gender"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Test Battle Phase", () => { let phaserGame: Phaser.Game; @@ -90,14 +78,15 @@ describe("Test Battle Phase", () => { }, 20000); it("do attack wave 3 - single battle - regular - OHKO", async() => { - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.starterSpecies(Species.MEWTWO); + game.override.enemySpecies(Species.RATTATA); + game.override.startingLevel(2000); + game.override + .startingWave(3) + .battleType("single"); + game.override.moveset([Moves.TACKLE]); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); await game.startBattle(); game.onNextPrompt("CommandPhase", Mode.COMMAND, () => { game.scene.ui.setMode(Mode.FIGHT, (game.scene.getCurrentPhase() as CommandPhase).getFieldIndex()); @@ -110,14 +99,14 @@ describe("Test Battle Phase", () => { }, 20000); it("do attack wave 3 - single battle - regular - NO OHKO with opponent using non damage attack", async() => { - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(5); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TAIL_WHIP, Moves.TAIL_WHIP, Moves.TAIL_WHIP, Moves.TAIL_WHIP]); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.starterSpecies(Species.MEWTWO); + game.override.enemySpecies(Species.RATTATA); + game.override.startingLevel(5); + game.override.startingWave(3); + game.override.moveset([Moves.TACKLE]); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.enemyMoveset([Moves.TAIL_WHIP, Moves.TAIL_WHIP, Moves.TAIL_WHIP, Moves.TAIL_WHIP]); + game.override.battleType("single"); await game.startBattle(); game.onNextPrompt("CommandPhase", Mode.COMMAND, () => { game.scene.ui.setMode(Mode.FIGHT, (game.scene.getCurrentPhase() as CommandPhase).getFieldIndex()); @@ -204,10 +193,10 @@ describe("Test Battle Phase", () => { }, 20000); it("2vs1", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MIGHTYENA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); + game.override.battleType("single"); + game.override.enemySpecies(Species.MIGHTYENA); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.ability(Abilities.HYDRATION); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, @@ -217,10 +206,10 @@ describe("Test Battle Phase", () => { }, 20000); it("1vs1", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MIGHTYENA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); + game.override.battleType("single"); + game.override.enemySpecies(Species.MIGHTYENA); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.ability(Abilities.HYDRATION); await game.startBattle([ Species.BLASTOISE, ]); @@ -229,11 +218,11 @@ describe("Test Battle Phase", () => { }, 20000); it("2vs2", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MIGHTYENA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); + game.override.battleType("double"); + game.override.enemySpecies(Species.MIGHTYENA); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.ability(Abilities.HYDRATION); + game.override.startingWave(3); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, @@ -243,11 +232,11 @@ describe("Test Battle Phase", () => { }, 20000); it("4vs2", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MIGHTYENA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); + game.override.battleType("double"); + game.override.enemySpecies(Species.MIGHTYENA); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.ability(Abilities.HYDRATION); + game.override.startingWave(3); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, @@ -260,15 +249,15 @@ describe("Test Battle Phase", () => { it("kill opponent pokemon", async() => { const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZEN_MODE); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("single"); + game.override.starterSpecies(Species.MEWTWO); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.ability(Abilities.ZEN_MODE); + game.override.startingLevel(2000); + game.override.startingWave(3); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); await game.startBattle([ Species.DARMANITAN, Species.CHARIZARD, @@ -289,15 +278,15 @@ describe("Test Battle Phase", () => { it("to next turn", async() => { const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZEN_MODE); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("single"); + game.override.starterSpecies(Species.MEWTWO); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.ability(Abilities.ZEN_MODE); + game.override.startingLevel(2000); + game.override.startingWave(3); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); await game.startBattle(); const turn = game.scene.currentBattle.turn; game.doAttack(0); @@ -307,15 +296,15 @@ describe("Test Battle Phase", () => { it("to next wave with pokemon killed, single", async() => { const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZEN_MODE); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("single"); + game.override.starterSpecies(Species.MEWTWO); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.ability(Abilities.ZEN_MODE); + game.override.startingLevel(2000); + game.override.startingWave(3); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); await game.startBattle(); const waveIndex = game.scene.currentBattle.waveIndex; game.doAttack(0); diff --git a/src/test/battle/double_battle.test.ts b/src/test/battle/double_battle.test.ts new file mode 100644 index 00000000000..fb73fd70099 --- /dev/null +++ b/src/test/battle/double_battle.test.ts @@ -0,0 +1,59 @@ +import { BattleEndPhase, TurnInitPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition, } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; +import { Status, StatusEffect } from "#app/data/status-effect.js"; + +describe("Test Battle Phase", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + }); + + // double-battle player's pokemon both fainted in same round, then revive one, and next double battle summons two player's pokemon successfully. + // (There were bugs that either only summon one when can summon two, player stuck in switchPhase etc) + it("3v2 edge case: player summons 2 pokemon on the next battle after being fainted and revived", async() => { + game.override.battleType("double").enemyMoveset(SPLASH_ONLY).moveset(SPLASH_ONLY); + await game.startBattle([ + Species.BULBASAUR, + Species.CHARIZARD, + Species.SQUIRTLE, + ]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + + for (const pokemon of game.scene.getPlayerField()) { + pokemon.hp = 0; + pokemon.status = new Status(StatusEffect.FAINT); + expect(pokemon.isFainted()).toBe(true); + } + + await game.doKillOpponents(); + + await game.phaseInterceptor.to(BattleEndPhase); + game.doSelectModifier(); + + const charizard = game.scene.getParty().findIndex(p => p.species.speciesId === Species.CHARIZARD); + game.doRevivePokemon(charizard); + + await game.phaseInterceptor.to(TurnInitPhase); + expect(game.scene.getPlayerField().filter(p => !p.isFainted())).toHaveLength(2); + }, 20000); +}); diff --git a/src/test/battle/error-handling.test.ts b/src/test/battle/error-handling.test.ts index 063ac2b5210..f244b57ce1b 100644 --- a/src/test/battle/error-handling.test.ts +++ b/src/test/battle/error-handling.test.ts @@ -1,10 +1,9 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import GameManager from "#app/test/utils/gameManager"; -import Phaser from "phaser"; -import Overrides from "#app/overrides"; +import GameManager from "#test/utils/gameManager"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Test Battle Phase", () => { let phaserGame: Phaser.Game; @@ -23,15 +22,16 @@ describe("Test Battle Phase", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.SPLASH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MEWTWO); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ZEN_MODE); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override + .battleType("single") + .startingWave(3); + game.override.starterSpecies(Species.MEWTWO); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.ability(Abilities.ZEN_MODE); + game.override.startingLevel(2000); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); }); it.skip("to next turn", async() => { diff --git a/src/test/battle/special_battle.test.ts b/src/test/battle/special_battle.test.ts index cc1d2057b9b..b8a29e82f69 100644 --- a/src/test/battle/special_battle.test.ts +++ b/src/test/battle/special_battle.test.ts @@ -1,14 +1,11 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import {Mode} from "#app/ui/ui"; -import Overrides from "#app/overrides"; -import { - CommandPhase, -} from "#app/phases"; -import GameManager from "#app/test/utils/gameManager"; -import Phaser from "phaser"; +import { CommandPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Test Battle Phase", () => { let phaserGame: Phaser.Game; @@ -26,17 +23,18 @@ describe("Test Battle Phase", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.enemySpecies(Species.RATTATA); + game.override.startingLevel(2000); + game.override.moveset([Moves.TACKLE]); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.ability(Abilities.HYDRATION); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); }); it("startBattle 2vs1 boss", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(10); + game.override + .battleType("single") + .startingWave(10); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, @@ -46,8 +44,9 @@ describe("Test Battle Phase", () => { }, 20000); it("startBattle 2vs2 boss", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(10); + game.override + .battleType("double") + .startingWave(10); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, @@ -57,8 +56,9 @@ describe("Test Battle Phase", () => { }, 20000); it("startBattle 2vs2 trainer", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override + .battleType("double") + .startingWave(5); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, @@ -68,8 +68,9 @@ describe("Test Battle Phase", () => { }, 20000); it("startBattle 2vs1 trainer", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override + .battleType("single") + .startingWave(5); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, @@ -79,8 +80,9 @@ describe("Test Battle Phase", () => { }, 20000); it("startBattle 2vs1 rival", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(8); + game.override + .battleType("single") + .startingWave(8); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, @@ -90,8 +92,9 @@ describe("Test Battle Phase", () => { }, 20000); it("startBattle 2vs2 rival", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(8); + game.override + .battleType("double") + .startingWave(8); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, @@ -101,8 +104,9 @@ describe("Test Battle Phase", () => { }, 20000); it("startBattle 1vs1 trainer", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override + .battleType("single") + .startingWave(5); await game.startBattle([ Species.BLASTOISE, ]); @@ -111,8 +115,9 @@ describe("Test Battle Phase", () => { }, 20000); it("startBattle 2vs2 trainer", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override + .battleType("double") + .startingWave(5); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, @@ -122,8 +127,9 @@ describe("Test Battle Phase", () => { }, 20000); it("startBattle 4vs2 trainer", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override + .battleType("double") + .startingWave(5); await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD, diff --git a/src/test/eggs/egg.test.ts b/src/test/eggs/egg.test.ts index 91d1153edfc..0bc2972e2dc 100644 --- a/src/test/eggs/egg.test.ts +++ b/src/test/eggs/egg.test.ts @@ -1,4 +1,4 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import BattleScene from "../../battle-scene"; import { Egg, getLegendaryGachaSpeciesForTimestamp } from "#app/data/egg.js"; import { Species } from "#enums/species"; @@ -6,7 +6,7 @@ import Phaser from "phaser"; import { EggSourceType } from "#app/enums/egg-source-types.js"; import { EggTier } from "#app/enums/egg-type.js"; import { VariantTier } from "#app/enums/variant-tiers.js"; -import GameManager from "../utils/gameManager"; +import GameManager from "#test/utils/gameManager"; import EggData from "#app/system/egg-data.js"; import * as Utils from "#app/utils.js"; diff --git a/src/test/evolution.test.ts b/src/test/evolution.test.ts index 945e8363231..acb012741ff 100644 --- a/src/test/evolution.test.ts +++ b/src/test/evolution.test.ts @@ -1,10 +1,9 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import { Species } from "#app/enums/species.js"; -import { Abilities } from "#app/enums/abilities.js"; -import Overrides from "#app/overrides"; import { pokemonEvolutions } from "#app/data/pokemon-evolutions.js"; +import { Abilities } from "#app/enums/abilities.js"; +import { Species } from "#app/enums/species.js"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Evolution", () => { let phaserGame: Phaser.Game; @@ -24,12 +23,12 @@ describe("Evolution", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyAbility(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(60); + game.override.startingLevel(60); }); it("should keep hidden ability after evolving", async () => { diff --git a/src/test/evolutions/evolutions.test.ts b/src/test/evolutions/evolutions.test.ts new file mode 100644 index 00000000000..e6e9e0d56e2 --- /dev/null +++ b/src/test/evolutions/evolutions.test.ts @@ -0,0 +1,48 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { Species } from "#enums/species"; +import * as Utils from "#app/utils"; + +describe("Evolution tests", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + }); + + it("tandemaus evolution form test", async () => { + /* this test checks to make sure that tandemaus will + * evolve into a 3 family maushold 25% of the time + * and a 4 family maushold the other 75% of the time + * This is done by using the getEvolution method in pokemon.ts + * getEvolution will give back the form that the pokemon can evolve into + * It does this by checking the pokemon conditions in pokemon-forms.ts + * For tandemaus, the conditions are random due to a randSeedInt(4) + * If the value is 0, it's a 3 family maushold, whereas if the value is + * 1, 2 or 3, it's a 4 family maushold + */ + await game.startBattle([Species.TANDEMAUS]); // starts us off with a tandemaus + const playerPokemon = game.scene.getPlayerPokemon(); + playerPokemon.level = 25; // tandemaus evolves at level 25 + vi.spyOn(Utils, "randSeedInt").mockReturnValue(0); // setting the random generator to be 0 to force a three family maushold + const threeForm = playerPokemon.getEvolution(); + expect(threeForm.evoFormKey).toBe("three"); // as per pokemon-forms, the evoFormKey for 3 family mausholds is "three" + for (let f = 1; f < 4; f++) { + vi.spyOn(Utils, "randSeedInt").mockReturnValue(f); // setting the random generator to 1, 2 and 3 to force 4 family mausholds + const fourForm = playerPokemon.getEvolution(); + expect(fourForm.evoFormKey).toBe(null); // meanwhile, according to the pokemon-forms, the evoFormKey for a 4 family maushold is null + } + }, 5000); +}); diff --git a/src/test/final_boss.test.ts b/src/test/final_boss.test.ts new file mode 100644 index 00000000000..bc950e45767 --- /dev/null +++ b/src/test/final_boss.test.ts @@ -0,0 +1,89 @@ +import { Biome } from "#app/enums/biome.js"; +import { Species } from "#app/enums/species.js"; +import { GameModes, getGameMode } from "#app/game-mode.js"; +import { EncounterPhase, SelectStarterPhase } from "#app/phases.js"; +import { Mode } from "#app/ui/ui.js"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import GameManager from "./utils/gameManager"; +import { generateStarter } from "./utils/gameManagerUtils"; + +const FinalWave = { + Classic: 200, +}; + +describe("Final Boss", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.startingWave(FinalWave.Classic).startingBiome(Biome.END).disableCrits(); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + it("should spawn Eternatus on wave 200 in END biome", async () => { + await runToFinalBossEncounter(game, [Species.BIDOOF]); + + expect(game.scene.currentBattle.waveIndex).toBe(FinalWave.Classic); + expect(game.scene.arena.biomeType).toBe(Biome.END); + expect(game.scene.getEnemyPokemon().species.speciesId).toBe(Species.ETERNATUS); + }); + + it("should NOT spawn Eternatus before wave 200 in END biome", async () => { + game.override.startingWave(FinalWave.Classic - 1); + await runToFinalBossEncounter(game, [Species.BIDOOF]); + + expect(game.scene.currentBattle.waveIndex).not.toBe(FinalWave.Classic); + expect(game.scene.arena.biomeType).toBe(Biome.END); + expect(game.scene.getEnemyPokemon().species.speciesId).not.toBe(Species.ETERNATUS); + }); + + it("should NOT spawn Eternatus outside of END biome", async () => { + game.override.startingBiome(Biome.FOREST); + await runToFinalBossEncounter(game, [Species.BIDOOF]); + + expect(game.scene.currentBattle.waveIndex).toBe(FinalWave.Classic); + expect(game.scene.arena.biomeType).not.toBe(Biome.END); + expect(game.scene.getEnemyPokemon().species.speciesId).not.toBe(Species.ETERNATUS); + }); + + it.todo("should change form on direct hit down to last boss fragment", () => {}); +}); + +/** + * Helper function to run to the final boss encounter as it's a bit tricky due to extra dialogue + * @param game - The game manager + */ +async function runToFinalBossEncounter(game: GameManager, species: Species[]) { + console.log("===to final boss encounter==="); + await game.runToTitle(); + + game.onNextPrompt("TitlePhase", Mode.TITLE, () => { + game.scene.gameMode = getGameMode(GameModes.CLASSIC); + const starters = generateStarter(game.scene, species); + const selectStarterPhase = new SelectStarterPhase(game.scene); + game.scene.pushPhase(new EncounterPhase(game.scene, false)); + selectStarterPhase.initBattle(starters); + }); + + game.onNextPrompt("EncounterPhase", Mode.MESSAGE, async () => { + // This will skip all entry dialogue (I can't figure out a way to sequentially handle the 8 chained messages via 1 prompt handler) + game.setMode(Mode.MESSAGE); + const encounterPhase = game.scene.getCurrentPhase() as EncounterPhase; + + // No need to end phase, this will do it for you + encounterPhase.doEncounterCommon(false); + }); + + await game.phaseInterceptor.to(EncounterPhase, true); + console.log("===finished run to final boss encounter==="); +} diff --git a/src/test/game-mode.test.ts b/src/test/game-mode.test.ts index 04376c20361..4a1960a05ff 100644 --- a/src/test/game-mode.test.ts +++ b/src/test/game-mode.test.ts @@ -1,13 +1,5 @@ import { GameMode, GameModes, getGameMode } from "#app/game-mode.js"; -import { - afterEach, - beforeAll, - beforeEach, - describe, - expect, - it, - vi, -} from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import GameManager from "./utils/gameManager"; import * as Utils from "../utils"; describe("game-mode", () => { diff --git a/src/test/imports.test.ts b/src/test/imports.test.ts index 5c0272e191d..69c145236bc 100644 --- a/src/test/imports.test.ts +++ b/src/test/imports.test.ts @@ -1,5 +1,5 @@ -import { describe, expect, it} from "vitest"; -import {initStatsKeys} from "#app/ui/game-stats-ui-handler"; +import { describe, expect, it } from "vitest"; +import { initStatsKeys } from "#app/ui/game-stats-ui-handler"; async function importModule() { try { diff --git a/src/test/inputs/inputs.test.ts b/src/test/inputs/inputs.test.ts index 5acee145011..7182ac2c02c 100644 --- a/src/test/inputs/inputs.test.ts +++ b/src/test/inputs/inputs.test.ts @@ -1,9 +1,9 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it} from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; +import GameManager from "#test/utils/gameManager"; import pad_xbox360 from "#app/configs/inputs/pad_xbox360"; import cfg_keyboard_qwerty from "#app/configs/inputs/cfg_keyboard_qwerty"; -import InputsHandler from "#app/test/utils/inputsHandler"; +import InputsHandler from "#test/utils/inputsHandler"; describe("Inputs", () => { diff --git a/src/test/internals.test.ts b/src/test/internals.test.ts index a54b8b01544..2ada42d0c8c 100644 --- a/src/test/internals.test.ts +++ b/src/test/internals.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; +import GameManager from "#test/utils/gameManager"; import { Species } from "#app/enums/species.js"; import { Abilities } from "#app/enums/abilities.js"; diff --git a/src/test/items/eviolite.test.ts b/src/test/items/eviolite.test.ts index 5cdcf2256c3..0fe90866de8 100644 --- a/src/test/items/eviolite.test.ts +++ b/src/test/items/eviolite.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phase from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; import { Stat } from "#app/data/pokemon-stat"; import { EvolutionStatBoosterModifier } from "#app/modifier/modifier"; import { modifierTypes } from "#app/modifier/modifier-type"; -import * as Utils from "#app/utils"; import i18next from "#app/plugins/i18n"; +import GameManager from "#test/utils/gameManager"; +import * as Utils from "#app/utils"; import { Species } from "#enums/species"; +import Phase from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Items - Eviolite", () => { let phaserGame: Phaser.Game; @@ -26,11 +25,11 @@ describe("Items - Eviolite", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); }); it("EVIOLITE activates in battle correctly", async() => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{ name: "EVIOLITE" }]); + game.override.startingHeldItems([{ name: "EVIOLITE" }]); const consoleSpy = vi.spyOn(console, "log"); await game.startBattle([ Species.PICHU diff --git a/src/test/items/exp_booster.test.ts b/src/test/items/exp_booster.test.ts index 866bd6f08b6..7ea457eda1f 100644 --- a/src/test/items/exp_booster.test.ts +++ b/src/test/items/exp_booster.test.ts @@ -1,10 +1,9 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phase from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; import { Abilities } from "#app/enums/abilities.js"; import { PokemonExpBoosterModifier } from "#app/modifier/modifier.js"; +import GameManager from "#test/utils/gameManager"; import * as Utils from "#app/utils"; +import Phase from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("EXP Modifier Items", () => { let phaserGame: Phaser.Game; @@ -23,13 +22,13 @@ describe("EXP Modifier Items", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.ability(Abilities.BALL_FETCH); + game.override.battleType("single"); }); it("EXP booster items stack additively", async() => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "LUCKY_EGG"}, {name: "GOLDEN_EGG"}]); + game.override.startingHeldItems([{name: "LUCKY_EGG"}, {name: "GOLDEN_EGG"}]); await game.startBattle(); const partyMember = game.scene.getPlayerPokemon(); diff --git a/src/test/items/grip_claw.test.ts b/src/test/items/grip_claw.test.ts index 2aeb98253ab..40ef81fed73 100644 --- a/src/test/items/grip_claw.test.ts +++ b/src/test/items/grip_claw.test.ts @@ -1,15 +1,14 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phase from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Moves } from "#app/enums/moves.js"; -import { Species } from "#app/enums/species.js"; -import { BerryType } from "#app/enums/berry-type.js"; -import { Abilities } from "#app/enums/abilities.js"; -import { getMovePosition } from "../utils/gameManagerUtils"; -import { CommandPhase, MoveEndPhase, SelectTargetPhase } from "#app/phases.js"; import { BattlerIndex } from "#app/battle.js"; import { allMoves } from "#app/data/move.js"; +import { Abilities } from "#app/enums/abilities.js"; +import { BerryType } from "#app/enums/berry-type.js"; +import { Moves } from "#app/enums/moves.js"; +import { Species } from "#app/enums/species.js"; +import { CommandPhase, MoveEndPhase, SelectTargetPhase } from "#app/phases.js"; +import GameManager from "#test/utils/gameManager"; +import Phase from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; const TIMEOUT = 20 * 1000; // 20 seconds @@ -30,18 +29,22 @@ describe("Items - Grip Claw", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.POPULATION_BOMB, Moves.SPLASH ]); - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "GRIP_CLAW", count: 5}, {name: "MULTI_LENS", count: 3}]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.KLUTZ); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); - vi.spyOn(Overrides, "OPP_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([ - {name: "BERRY", type: BerryType.SITRUS, count: 2}, - {name: "BERRY", type: BerryType.LUM, count: 2} - ]); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); + game.override + .battleType("double") + .moveset([Moves.POPULATION_BOMB, Moves.SPLASH]) + .startingHeldItems([ + { name: "GRIP_CLAW", count: 5 }, + { name: "MULTI_LENS", count: 3 }, + ]) + .enemySpecies(Species.SNORLAX) + .ability(Abilities.KLUTZ) + .enemyMoveset([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]) + .enemyHeldItems([ + { name: "BERRY", type: BerryType.SITRUS, count: 2 }, + { name: "BERRY", type: BerryType.LUM, count: 2 }, + ]) + .startingLevel(100) + .enemyLevel(100); vi.spyOn(allMoves[Moves.POPULATION_BOMB], "accuracy", "get").mockReturnValue(100); }); @@ -51,11 +54,7 @@ describe("Items - Grip Claw", () => { async () => { await game.startBattle([Species.PANSEAR, Species.ROWLET, Species.PANPOUR, Species.PANSAGE, Species.CHARMANDER, Species.SQUIRTLE]); - const playerPokemon = game.scene.getPlayerField(); - playerPokemon.forEach(p => expect(p).toBeDefined()); - const enemyPokemon = game.scene.getEnemyField(); - enemyPokemon.forEach(p => expect(p).toBeDefined()); const enemyHeldItemCt = enemyPokemon.map(p => p.getHeldItems.length); diff --git a/src/test/items/leek.test.ts b/src/test/items/leek.test.ts index 2781de45c08..7a2dd369e4e 100644 --- a/src/test/items/leek.test.ts +++ b/src/test/items/leek.test.ts @@ -1,14 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phase from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { Moves } from "#enums/moves"; +import { BattlerIndex } from "#app/battle"; import { CritBoosterModifier } from "#app/modifier/modifier"; import { modifierTypes } from "#app/modifier/modifier-type"; -import * as Utils from "#app/utils"; import { MoveEffectPhase, TurnStartPhase } from "#app/phases"; -import { BattlerIndex } from "#app/battle"; +import GameManager from "#test/utils/gameManager"; +import * as Utils from "#app/utils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phase from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Items - Leek", () => { let phaserGame: Phaser.Game; @@ -27,16 +26,16 @@ describe("Items - Leek", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); + game.override.disableCrits(); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); }); it("LEEK activates in battle correctly", async() => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{ name: "LEEK" }]); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.POUND ]); + game.override.startingHeldItems([{ name: "LEEK" }]); + game.override.moveset([ Moves.POUND ]); const consoleSpy = vi.spyOn(console, "log"); await game.startBattle([ Species.FARFETCHD diff --git a/src/test/items/leftovers.test.ts b/src/test/items/leftovers.test.ts index 1d564ae534c..6850528a664 100644 --- a/src/test/items/leftovers.test.ts +++ b/src/test/items/leftovers.test.ts @@ -1,12 +1,11 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import overrides from "#app/overrides"; import { DamagePhase, TurnEndPhase } from "#app/phases"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Items - Leftovers", () => { @@ -25,14 +24,14 @@ describe("Items - Leftovers", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.UNNERVE); - vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); - vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); - vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.UNNERVE); - vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); - vi.spyOn(overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "LEFTOVERS", count: 1}]); + game.override.battleType("single"); + game.override.startingLevel(2000); + game.override.ability(Abilities.UNNERVE); + game.override.moveset([Moves.SPLASH]); + game.override.enemySpecies(Species.SHUCKLE); + game.override.enemyAbility(Abilities.UNNERVE); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.startingHeldItems([{name: "LEFTOVERS", count: 1}]); }); it("leftovers works", async() => { @@ -42,10 +41,6 @@ describe("Items - Leftovers", () => { expect(game.scene.modifiers[0].type.id).toBe("LEFTOVERS"); const leadPokemon = game.scene.getPlayerPokemon(); - expect(leadPokemon).toBeDefined(); - - const enemyPokemon = game.scene.getEnemyPokemon(); - expect(enemyPokemon).toBeDefined(); // We should have full hp expect(leadPokemon.isFullHp()).toBe(true); diff --git a/src/test/items/light_ball.test.ts b/src/test/items/light_ball.test.ts index e693307e229..fef5793d26c 100644 --- a/src/test/items/light_ball.test.ts +++ b/src/test/items/light_ball.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phase from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; import { Stat } from "#app/data/pokemon-stat"; import { SpeciesStatBoosterModifier } from "#app/modifier/modifier"; import { modifierTypes } from "#app/modifier/modifier-type"; -import * as Utils from "#app/utils"; import i18next from "#app/plugins/i18n"; +import GameManager from "#test/utils/gameManager"; +import * as Utils from "#app/utils"; +import { Species } from "#enums/species"; +import Phase from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Items - Light Ball", () => { let phaserGame: Phaser.Game; @@ -26,11 +25,11 @@ describe("Items - Light Ball", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); }); it("LIGHT_BALL activates in battle correctly", async() => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{ name: "SPECIES_STAT_BOOSTER", type: "LIGHT_BALL" }]); + game.override.startingHeldItems([{ name: "SPECIES_STAT_BOOSTER", type: "LIGHT_BALL" }]); const consoleSpy = vi.spyOn(console, "log"); await game.startBattle([ Species.PIKACHU diff --git a/src/test/items/metal_powder.test.ts b/src/test/items/metal_powder.test.ts index 111bc6dfad1..da5d9109c9a 100644 --- a/src/test/items/metal_powder.test.ts +++ b/src/test/items/metal_powder.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phase from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; import { Stat } from "#app/data/pokemon-stat"; import { SpeciesStatBoosterModifier } from "#app/modifier/modifier"; import { modifierTypes } from "#app/modifier/modifier-type"; -import * as Utils from "#app/utils"; import i18next from "#app/plugins/i18n"; +import GameManager from "#test/utils/gameManager"; +import * as Utils from "#app/utils"; +import { Species } from "#enums/species"; +import Phase from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Items - Metal Powder", () => { let phaserGame: Phaser.Game; @@ -26,11 +25,11 @@ describe("Items - Metal Powder", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); }); it("METAL_POWDER activates in battle correctly", async() => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{ name: "SPECIES_STAT_BOOSTER", type: "METAL_POWDER" }]); + game.override.startingHeldItems([{ name: "SPECIES_STAT_BOOSTER", type: "METAL_POWDER" }]); const consoleSpy = vi.spyOn(console, "log"); await game.startBattle([ Species.DITTO diff --git a/src/test/items/quick_powder.test.ts b/src/test/items/quick_powder.test.ts index cddddb0eeea..939d25070bc 100644 --- a/src/test/items/quick_powder.test.ts +++ b/src/test/items/quick_powder.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phase from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; import { Stat } from "#app/data/pokemon-stat"; import { SpeciesStatBoosterModifier } from "#app/modifier/modifier"; import { modifierTypes } from "#app/modifier/modifier-type"; -import * as Utils from "#app/utils"; import i18next from "#app/plugins/i18n"; +import GameManager from "#test/utils/gameManager"; +import * as Utils from "#app/utils"; +import { Species } from "#enums/species"; +import Phase from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Items - Quick Powder", () => { let phaserGame: Phaser.Game; @@ -26,11 +25,11 @@ describe("Items - Quick Powder", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); }); it("QUICK_POWDER activates in battle correctly", async() => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{ name: "SPECIES_STAT_BOOSTER", type: "QUICK_POWDER" }]); + game.override.startingHeldItems([{ name: "SPECIES_STAT_BOOSTER", type: "QUICK_POWDER" }]); const consoleSpy = vi.spyOn(console, "log"); await game.startBattle([ Species.DITTO diff --git a/src/test/items/scope_lens.test.ts b/src/test/items/scope_lens.test.ts index 8f54a880c41..59702ee51ac 100644 --- a/src/test/items/scope_lens.test.ts +++ b/src/test/items/scope_lens.test.ts @@ -1,14 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phase from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { Moves } from "#enums/moves"; +import { BattlerIndex } from "#app/battle"; import { CritBoosterModifier } from "#app/modifier/modifier"; import { modifierTypes } from "#app/modifier/modifier-type"; -import * as Utils from "#app/utils"; import { MoveEffectPhase, TurnStartPhase } from "#app/phases"; -import { BattlerIndex } from "#app/battle"; +import GameManager from "#test/utils/gameManager"; +import * as Utils from "#app/utils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phase from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Items - Scope Lens", () => { let phaserGame: Phaser.Game; @@ -27,16 +26,16 @@ describe("Items - Scope Lens", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); + game.override.disableCrits(); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); }, 20000); it("SCOPE_LENS activates in battle correctly", async() => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{ name: "SCOPE_LENS" }]); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.POUND ]); + game.override.startingHeldItems([{ name: "SCOPE_LENS" }]); + game.override.moveset([ Moves.POUND ]); const consoleSpy = vi.spyOn(console, "log"); await game.startBattle([ Species.GASTLY diff --git a/src/test/items/thick_club.test.ts b/src/test/items/thick_club.test.ts index a0a229a5d13..6b56cf98099 100644 --- a/src/test/items/thick_club.test.ts +++ b/src/test/items/thick_club.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phase from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; import { Stat } from "#app/data/pokemon-stat"; import { SpeciesStatBoosterModifier } from "#app/modifier/modifier"; import { modifierTypes } from "#app/modifier/modifier-type"; -import * as Utils from "#app/utils"; import i18next from "#app/plugins/i18n"; +import GameManager from "#test/utils/gameManager"; +import * as Utils from "#app/utils"; +import { Species } from "#enums/species"; +import Phase from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Items - Thick Club", () => { let phaserGame: Phaser.Game; @@ -26,11 +25,11 @@ describe("Items - Thick Club", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); }); it("THICK_CLUB activates in battle correctly", async() => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{ name: "SPECIES_STAT_BOOSTER", type: "THICK_CLUB" }]); + game.override.startingHeldItems([{ name: "SPECIES_STAT_BOOSTER", type: "THICK_CLUB" }]); const consoleSpy = vi.spyOn(console, "log"); await game.startBattle([ Species.CUBONE diff --git a/src/test/items/toxic_orb.test.ts b/src/test/items/toxic_orb.test.ts index 45662ac29cf..b5e9b6c4d65 100644 --- a/src/test/items/toxic_orb.test.ts +++ b/src/test/items/toxic_orb.test.ts @@ -1,21 +1,15 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase, - EnemyCommandPhase, - MessagePhase, - TurnEndPhase, -} from "#app/phases"; -import {Mode} from "#app/ui/ui"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; -import {Command} from "#app/ui/command-ui-handler"; -import {StatusEffect} from "#app/data/status-effect"; +import { StatusEffect } from "#app/data/status-effect"; +import { CommandPhase, EnemyCommandPhase, MessagePhase, TurnEndPhase } from "#app/phases"; +import i18next, { initI18n } from "#app/plugins/i18n"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; +import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import i18next, { initI18n } from "#app/plugins/i18n"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Items - Toxic orb", () => { @@ -36,14 +30,14 @@ describe("Items - Toxic orb", () => { game = new GameManager(phaserGame); const moveToUse = Moves.GROWTH; const oppMoveToUse = Moves.TACKLE; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([oppMoveToUse, oppMoveToUse, oppMoveToUse, oppMoveToUse]); - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{ + game.override.battleType("single"); + game.override.enemySpecies(Species.RATTATA); + game.override.ability(Abilities.INSOMNIA); + game.override.enemyAbility(Abilities.INSOMNIA); + game.override.startingLevel(2000); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([oppMoveToUse, oppMoveToUse, oppMoveToUse, oppMoveToUse]); + game.override.startingHeldItems([{ name: "TOXIC_ORB", }]); }); @@ -73,7 +67,7 @@ describe("Items - Toxic orb", () => { // Toxic orb should trigger here await game.phaseInterceptor.run(MessagePhase); const message = game.textInterceptor.getLatestMessage(); - expect(message).toContain("was badly poisoned by Toxic Orb"); + expect(message).toContain("was badly poisoned by the Toxic Orb"); await game.phaseInterceptor.run(MessagePhase); const message2 = game.textInterceptor.getLatestMessage(); expect(message2).toContain("is hurt"); diff --git a/src/test/localization/battle-stat.test.ts b/src/test/localization/battle-stat.test.ts index ea2714b3852..b99ed2b7064 100644 --- a/src/test/localization/battle-stat.test.ts +++ b/src/test/localization/battle-stat.test.ts @@ -1,27 +1,26 @@ -import {beforeAll, describe, expect, it} from "vitest"; -import {getBattleStatName, getBattleStatLevelChangeDescription} from "#app/data/battle-stat.js"; -import {BattleStat} from "#app/data/battle-stat.js"; -import {pokemonInfo as enPokemonInfo} from "#app/locales/en/pokemon-info.js"; -import {battle as enBattleStat} from "#app/locales/en/battle.js"; -import {pokemonInfo as dePokemonInfo} from "#app/locales/de/pokemon-info.js"; -import {battle as deBattleStat} from "#app/locales/de/battle.js"; -import {pokemonInfo as esPokemonInfo} from "#app/locales/es/pokemon-info.js"; -import {battle as esBattleStat} from "#app/locales/es/battle.js"; -import {pokemonInfo as frPokemonInfo} from "#app/locales/fr/pokemon-info.js"; -import {battle as frBattleStat} from "#app/locales/fr/battle.js"; -import {pokemonInfo as itPokemonInfo} from "#app/locales/it/pokemon-info.js"; -import {battle as itBattleStat} from "#app/locales/it/battle.js"; -import {pokemonInfo as koPokemonInfo} from "#app/locales/ko/pokemon-info.js"; -import {battle as koBattleStat} from "#app/locales/ko/battle.js"; -import {pokemonInfo as ptBrPokemonInfo} from "#app/locales/pt_BR/pokemon-info.js"; -import {battle as ptBrBattleStat} from "#app/locales/pt_BR/battle.js"; -import {pokemonInfo as zhCnPokemonInfo} from "#app/locales/zh_CN/pokemon-info.js"; -import {battle as zhCnBattleStat} from "#app/locales/zh_CN/battle.js"; -import {pokemonInfo as zhTwPokemonInfo} from "#app/locales/zh_TW/pokemon-info.js"; -import {battle as zhTwBattleStat} from "#app/locales/zh_TW/battle.js"; - -import i18next, {initI18n} from "#app/plugins/i18n"; -import {KoreanPostpositionProcessor} from "i18next-korean-postposition-processor"; +import { beforeAll, describe, expect, it } from "vitest"; +import { getBattleStatName, getBattleStatLevelChangeDescription } from "#app/data/battle-stat.js"; +import { BattleStat} from "#app/data/battle-stat.js"; +import { pokemonInfo as enPokemonInfo } from "#app/locales/en/pokemon-info.js"; +import { battle as enBattleStat } from "#app/locales/en/battle.js"; +import { pokemonInfo as dePokemonInfo } from "#app/locales/de/pokemon-info.js"; +import { battle as deBattleStat } from "#app/locales/de/battle.js"; +import { pokemonInfo as esPokemonInfo } from "#app/locales/es/pokemon-info.js"; +import { battle as esBattleStat } from "#app/locales/es/battle.js"; +import { pokemonInfo as frPokemonInfo } from "#app/locales/fr/pokemon-info.js"; +import { battle as frBattleStat } from "#app/locales/fr/battle.js"; +import { pokemonInfo as itPokemonInfo } from "#app/locales/it/pokemon-info.js"; +import { battle as itBattleStat } from "#app/locales/it/battle.js"; +import { pokemonInfo as koPokemonInfo } from "#app/locales/ko/pokemon-info.js"; +import { battle as koBattleStat } from "#app/locales/ko/battle.js"; +import { pokemonInfo as ptBrPokemonInfo } from "#app/locales/pt_BR/pokemon-info.js"; +import { battle as ptBrBattleStat } from "#app/locales/pt_BR/battle.js"; +import { pokemonInfo as zhCnPokemonInfo } from "#app/locales/zh_CN/pokemon-info.js"; +import { battle as zhCnBattleStat } from "#app/locales/zh_CN/battle.js"; +import { pokemonInfo as zhTwPokemonInfo } from "#app/locales/zh_TW/pokemon-info.js"; +import { battle as zhTwBattleStat } from "#app/locales/zh_TW/battle.js"; +import i18next, { initI18n } from "#app/plugins/i18n"; +import { KoreanPostpositionProcessor } from "i18next-korean-postposition-processor"; interface BattleStatTestUnit { stat: BattleStat, diff --git a/src/test/localization/french.test.ts b/src/test/localization/french.test.ts index 45429b1b157..b03a8ee64e8 100644 --- a/src/test/localization/french.test.ts +++ b/src/test/localization/french.test.ts @@ -1,9 +1,9 @@ -import {afterEach, beforeAll, describe, expect, it} from "vitest"; +import { afterEach, beforeAll, describe, expect, it } from "vitest"; import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import {Species} from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import { Species } from "#enums/species"; import i18next from "i18next"; -import {initI18n} from "#app/plugins/i18n"; +import { initI18n } from "#app/plugins/i18n"; describe("Lokalization - french", () => { let phaserGame: Phaser.Game; diff --git a/src/test/localization/status-effect.test.ts b/src/test/localization/status-effect.test.ts index ad33a59a675..8a9effe1672 100644 --- a/src/test/localization/status-effect.test.ts +++ b/src/test/localization/status-effect.test.ts @@ -1,14 +1,7 @@ import { beforeAll, describe, afterEach, expect, it, vi } from "vitest"; -import { - StatusEffect, - getStatusEffectActivationText, - getStatusEffectDescriptor, - getStatusEffectHealText, - getStatusEffectObtainText, - getStatusEffectOverlapText, -} from "#app/data/status-effect"; +import { StatusEffect, getStatusEffectActivationText, getStatusEffectDescriptor, getStatusEffectHealText, getStatusEffectObtainText, getStatusEffectOverlapText } from "#app/data/status-effect"; import i18next from "i18next"; -import { mockI18next } from "../utils/testUtils"; +import { mockI18next } from "#test/utils/testUtils"; const pokemonName = "PKM"; const sourceText = "SOURCE"; diff --git a/src/test/localization/terrain.test.ts b/src/test/localization/terrain.test.ts index 08292bcdda7..f97b7813948 100644 --- a/src/test/localization/terrain.test.ts +++ b/src/test/localization/terrain.test.ts @@ -1,12 +1,11 @@ -import { beforeAll, describe, beforeEach, afterEach, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; import { TerrainType, getTerrainName } from "#app/data/terrain"; -import { getTerrainStartMessage, getTerrainClearMessage, getTerrainBlockMessage } from "#app/data/weather"; +import { getTerrainBlockMessage, getTerrainClearMessage, getTerrainStartMessage } from "#app/data/weather"; +import GameManager from "#test/utils/gameManager"; +import { Species } from "#enums/species"; import i18next from "i18next"; -import { mockI18next } from "../utils/testUtils"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { mockI18next } from "#test/utils/testUtils"; describe("terrain", () => { let phaserGame: Phaser.Game; @@ -21,7 +20,7 @@ describe("terrain", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); }); describe("NONE", () => { diff --git a/src/test/moves/astonish.test.ts b/src/test/moves/astonish.test.ts index 4ce2f16715b..c5d59f82102 100644 --- a/src/test/moves/astonish.test.ts +++ b/src/test/moves/astonish.test.ts @@ -1,14 +1,13 @@ -import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; -import GameManager from "../utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; +import { allMoves } from "#app/data/move.js"; +import { BattlerTagType } from "#app/enums/battler-tag-type.js"; +import { BerryPhase, CommandPhase, MoveEndPhase, TurnEndPhase } from "#app/phases.js"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; -import { getMovePosition } from "../utils/gameManagerUtils"; -import { BerryPhase, CommandPhase, MoveEndPhase, TurnEndPhase } from "#app/phases.js"; -import { BattlerTagType } from "#app/enums/battler-tag-type.js"; -import { allMoves } from "#app/data/move.js"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; const TIMEOUT = 20 * 1000; @@ -28,13 +27,13 @@ describe("Moves - Astonish", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.ASTONISH, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.BLASTOISE); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); + game.override.battleType("single"); + game.override.moveset([Moves.ASTONISH, Moves.SPLASH]); + game.override.enemySpecies(Species.BLASTOISE); + game.override.enemyAbility(Abilities.INSOMNIA); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.startingLevel(100); + game.override.enemyLevel(100); vi.spyOn(allMoves[Moves.ASTONISH], "chance", "get").mockReturnValue(100); }); @@ -45,10 +44,8 @@ describe("Moves - Astonish", () => { await game.startBattle([Species.MEOWSCARADA]); const leadPokemon = game.scene.getPlayerPokemon(); - expect(leadPokemon).toBeDefined(); const enemyPokemon = game.scene.getEnemyPokemon(); - expect(enemyPokemon).toBeDefined(); game.doAttack(getMovePosition(game.scene, 0, Moves.ASTONISH)); diff --git a/src/test/moves/aurora_veil.test.ts b/src/test/moves/aurora_veil.test.ts index dad8d277b7f..f98e9e9cc0c 100644 --- a/src/test/moves/aurora_veil.test.ts +++ b/src/test/moves/aurora_veil.test.ts @@ -1,20 +1,17 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - TurnEndPhase, -} from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { ArenaTagSide } from "#app/data/arena-tag.js"; +import Move, { allMoves } from "#app/data/move.js"; +import { WeatherType } from "#app/data/weather.js"; +import { Abilities } from "#app/enums/abilities.js"; +import { ArenaTagType } from "#app/enums/arena-tag-type.js"; +import Pokemon from "#app/field/pokemon.js"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { NumberHolder } from "#app/utils.js"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { Abilities } from "#app/enums/abilities.js"; -import Pokemon from "#app/field/pokemon.js"; -import Move, { allMoves } from "#app/data/move.js"; -import { NumberHolder } from "#app/utils.js"; -import { ArenaTagSide } from "#app/data/arena-tag.js"; -import { WeatherType } from "#app/data/weather.js"; -import { ArenaTagType } from "#app/enums/arena-tag-type.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Aurora Veil", () => { @@ -35,14 +32,14 @@ describe("Moves - Aurora Veil", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.ABSORB, Moves.ROCK_SLIDE, Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL]); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); - vi.spyOn(Overrides, "WEATHER_OVERRIDE", "get").mockReturnValue(WeatherType.HAIL); + game.override.battleType("single"); + game.override.ability(Abilities.NONE); + game.override.moveset([Moves.ABSORB, Moves.ROCK_SLIDE, Moves.TACKLE]); + game.override.enemyLevel(100); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset([Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL, Moves.AURORA_VEIL]); + game.override.disableCrits(); + game.override.weather(WeatherType.HAIL); }); it("reduces damage of physical attacks by half in a single battle", async() => { @@ -58,7 +55,7 @@ describe("Moves - Aurora Veil", () => { }); it("reduces damage of physical attacks by a third in a double battle", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); + game.override.battleType("double"); const moveToUse = Moves.ROCK_SLIDE; await game.startBattle([Species.SHUCKLE, Species.SHUCKLE]); @@ -86,7 +83,7 @@ describe("Moves - Aurora Veil", () => { }); it("reduces damage of special attacks by a third in a double battle", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); + game.override.battleType("double"); const moveToUse = Moves.DAZZLING_GLEAM; await game.startBattle([Species.SHUCKLE, Species.SHUCKLE]); diff --git a/src/test/moves/beat_up.test.ts b/src/test/moves/beat_up.test.ts new file mode 100644 index 00000000000..e720c625956 --- /dev/null +++ b/src/test/moves/beat_up.test.ts @@ -0,0 +1,105 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { Species } from "#app/enums/species.js"; +import { Moves } from "#app/enums/moves.js"; +import { Abilities } from "#app/enums/abilities.js"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { MoveEffectPhase } from "#app/phases.js"; +import { StatusEffect } from "#app/enums/status-effect.js"; + +const TIMEOUT = 20 * 1000; // 20 sec timeout + +describe("Moves - Beat Up", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.battleType("single"); + + game.override.enemySpecies(Species.SNORLAX); + game.override.enemyLevel(100); + game.override.enemyMoveset(Array(4).fill(Moves.SPLASH)); + game.override.enemyAbility(Abilities.INSOMNIA); + + game.override.startingLevel(100); + game.override.moveset([Moves.BEAT_UP]); + }); + + it( + "should hit once for each healthy player Pokemon", + async () => { + await game.startBattle([Species.MAGIKARP, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.PIKACHU, Species.EEVEE]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + let enemyStartingHp = enemyPokemon.hp; + + game.doAttack(getMovePosition(game.scene, 0, Moves.BEAT_UP)); + + await game.phaseInterceptor.to(MoveEffectPhase); + + expect(playerPokemon.turnData.hitCount).toBe(6); + expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); + + while (playerPokemon.turnData.hitsLeft > 0) { + enemyStartingHp = enemyPokemon.hp; + await game.phaseInterceptor.to(MoveEffectPhase); + expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); + } + }, TIMEOUT + ); + + it( + "should not count player Pokemon with status effects towards hit count", + async () => { + await game.startBattle([Species.MAGIKARP, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.PIKACHU, Species.EEVEE]); + + const playerPokemon = game.scene.getPlayerPokemon(); + + game.scene.getParty()[1].trySetStatus(StatusEffect.BURN); + + game.doAttack(getMovePosition(game.scene, 0, Moves.BEAT_UP)); + + await game.phaseInterceptor.to(MoveEffectPhase); + + expect(playerPokemon.turnData.hitCount).toBe(5); + }, TIMEOUT + ); + + it( + "should hit twice for each player Pokemon if the user has Multi-Lens", + async () => { + game.override.startingHeldItems([{name: "MULTI_LENS", count: 1}]); + await game.startBattle([Species.MAGIKARP, Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.PIKACHU, Species.EEVEE]); + + const playerPokemon = game.scene.getPlayerPokemon(); + const enemyPokemon = game.scene.getEnemyPokemon(); + let enemyStartingHp = enemyPokemon.hp; + + game.doAttack(getMovePosition(game.scene, 0, Moves.BEAT_UP)); + + await game.phaseInterceptor.to(MoveEffectPhase); + + expect(playerPokemon.turnData.hitCount).toBe(12); + expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); + + while (playerPokemon.turnData.hitsLeft > 0) { + enemyStartingHp = enemyPokemon.hp; + await game.phaseInterceptor.to(MoveEffectPhase); + expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); + } + }, TIMEOUT + ); +}); diff --git a/src/test/moves/belly_drum.test.ts b/src/test/moves/belly_drum.test.ts new file mode 100644 index 00000000000..5bb27394805 --- /dev/null +++ b/src/test/moves/belly_drum.test.ts @@ -0,0 +1,108 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { TurnEndPhase } from "#app/phases"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { BattleStat } from "#app/data/battle-stat"; + +const TIMEOUT = 20 * 1000; +// RATIO : HP Cost of Move +const RATIO = 2; +// PREDAMAGE : Amount of extra HP lost +const PREDAMAGE = 15; + +describe("Moves - BELLY DRUM", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.starterSpecies(Species.MAGIKARP); + game.override.enemySpecies(Species.SNORLAX); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override.moveset([Moves.BELLY_DRUM]); + game.override.enemyMoveset([Moves.SPLASH]); + }); + + // Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/Belly_Drum_(move) + + test("Belly Drum raises the user's Attack to its max, at the cost of 1/2 of its maximum HP", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); + + game.doAttack(getMovePosition(game.scene, 0, Moves.BELLY_DRUM)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp() - hpLost); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(6); + }, TIMEOUT + ); + + test("Belly Drum will still take effect if an uninvolved stat is at max", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); + + // Here - BattleStat.ATK -> -3 and BattleStat.SPATK -> 6 + leadPokemon.summonData.battleStats[BattleStat.ATK] = -3; + leadPokemon.summonData.battleStats[BattleStat.SPATK] = 6; + + game.doAttack(getMovePosition(game.scene, 0, Moves.BELLY_DRUM)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp() - hpLost); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.SPATK]).toBe(6); + }, TIMEOUT + ); + + test("Belly Drum fails if the pokemon's attack stat is at its maximum", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + leadPokemon.summonData.battleStats[BattleStat.ATK] = 6; + + game.doAttack(getMovePosition(game.scene, 0, Moves.BELLY_DRUM)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(6); + }, TIMEOUT + ); + + test("Belly Drum fails if the user's health is less than 1/2", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); + leadPokemon.hp = hpLost - PREDAMAGE; + + game.doAttack(getMovePosition(game.scene, 0, Moves.BELLY_DRUM)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(hpLost - PREDAMAGE); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(0); + }, TIMEOUT + ); +}); diff --git a/src/test/moves/ceaseless_edge.test.ts b/src/test/moves/ceaseless_edge.test.ts index a59d6e8f535..288ea6ac277 100644 --- a/src/test/moves/ceaseless_edge.test.ts +++ b/src/test/moves/ceaseless_edge.test.ts @@ -1,18 +1,14 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, test, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - MoveEffectPhase, - TurnEndPhase -} from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag"; +import { allMoves } from "#app/data/move"; +import { Abilities } from "#app/enums/abilities"; +import { ArenaTagType } from "#app/enums/arena-tag-type"; +import { MoveEffectPhase, TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { ArenaTagType } from "#app/enums/arena-tag-type"; -import { allMoves } from "#app/data/move"; -import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag"; -import { Abilities } from "#app/enums/abilities"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; const TIMEOUT = 20 * 1000; @@ -32,14 +28,14 @@ describe("Moves - Ceaseless Edge", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.RUN_AWAY); - vi.spyOn(Overrides, "OPP_PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.RUN_AWAY); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.CEASELESS_EDGE, Moves.SPLASH, Moves.ROAR ]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH,Moves.SPLASH,Moves.SPLASH,Moves.SPLASH]); + game.override.battleType("single"); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.RUN_AWAY); + game.override.enemyPassiveAbility(Abilities.RUN_AWAY); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override.moveset([ Moves.CEASELESS_EDGE, Moves.SPLASH, Moves.ROAR ]); + game.override.enemyMoveset([Moves.SPLASH,Moves.SPLASH,Moves.SPLASH,Moves.SPLASH]); vi.spyOn(allMoves[Moves.CEASELESS_EDGE], "accuracy", "get").mockReturnValue(100); }); @@ -49,11 +45,7 @@ describe("Moves - Ceaseless Edge", () => { async () => { await game.startBattle([ Species.ILLUMISE ]); - const leadPokemon = game.scene.getPlayerPokemon(); - expect(leadPokemon).toBeDefined(); - const enemyPokemon = game.scene.getEnemyPokemon(); - expect(enemyPokemon).toBeDefined(); const enemyStartingHp = enemyPokemon.hp; @@ -75,14 +67,10 @@ describe("Moves - Ceaseless Edge", () => { test( "move should hit twice with multi lens and apply two layers of spikes", async () => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "MULTI_LENS"}]); + game.override.startingHeldItems([{name: "MULTI_LENS"}]); await game.startBattle([ Species.ILLUMISE ]); - const leadPokemon = game.scene.getPlayerPokemon(); - expect(leadPokemon).toBeDefined(); - const enemyPokemon = game.scene.getEnemyPokemon(); - expect(enemyPokemon).toBeDefined(); const enemyStartingHp = enemyPokemon.hp; @@ -104,17 +92,11 @@ describe("Moves - Ceaseless Edge", () => { test( "trainer - move should hit twice, apply two layers of spikes, force switch opponent - opponent takes damage", async () => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "MULTI_LENS"}]); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override.startingHeldItems([{name: "MULTI_LENS"}]); + game.override.startingWave(5); await game.startBattle([ Species.ILLUMISE ]); - const leadPokemon = game.scene.getPlayerPokemon(); - expect(leadPokemon).toBeDefined(); - - const enemyPokemon = game.scene.getEnemyPokemon(); - expect(enemyPokemon).toBeDefined(); - game.doAttack(getMovePosition(game.scene, 0, Moves.CEASELESS_EDGE)); await game.phaseInterceptor.to(MoveEffectPhase, false); // Spikes should not have any layers before move effect is applied diff --git a/src/test/moves/clangorous_soul.test.ts b/src/test/moves/clangorous_soul.test.ts new file mode 100644 index 00000000000..251225e7068 --- /dev/null +++ b/src/test/moves/clangorous_soul.test.ts @@ -0,0 +1,130 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { TurnEndPhase } from "#app/phases"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { BattleStat } from "#app/data/battle-stat"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; + +const TIMEOUT = 20 * 1000; +/** HP Cost of Move */ +const RATIO = 3; +/** Amount of extra HP lost */ +const PREDAMAGE = 15; + +describe("Moves - CLANGOROUS_SOUL", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.starterSpecies(Species.MAGIKARP); + game.override.enemySpecies(Species.SNORLAX); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override.moveset([Moves.CLANGOROUS_SOUL]); + game.override.enemyMoveset(SPLASH_ONLY); + }); + + //Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/Clangorous_Soul_(move) + + test("Clangorous Soul raises the user's Attack, Defense, Special Attack, Special Defense and Speed by one stage each, at the cost of 1/3 of its maximum HP", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); + + game.doAttack(getMovePosition(game.scene, 0, Moves.CLANGOROUS_SOUL)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp() - hpLost); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(1); + expect(leadPokemon.summonData.battleStats[BattleStat.DEF]).toBe(1); + expect(leadPokemon.summonData.battleStats[BattleStat.SPATK]).toBe(1); + expect(leadPokemon.summonData.battleStats[BattleStat.SPDEF]).toBe(1); + expect(leadPokemon.summonData.battleStats[BattleStat.SPD]).toBe(1); + }, TIMEOUT + ); + + test("Clangorous Soul will still take effect if one or more of the involved stats are not at max", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); + + //Here - BattleStat.SPD -> 0 and BattleStat.SPDEF -> 4 + leadPokemon.summonData.battleStats[BattleStat.ATK] = 6; + leadPokemon.summonData.battleStats[BattleStat.DEF] = 6; + leadPokemon.summonData.battleStats[BattleStat.SPATK] = 6; + leadPokemon.summonData.battleStats[BattleStat.SPDEF] = 4; + + game.doAttack(getMovePosition(game.scene, 0, Moves.CLANGOROUS_SOUL)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp() - hpLost); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.DEF]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.SPATK]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.SPDEF]).toBe(5); + expect(leadPokemon.summonData.battleStats[BattleStat.SPD]).toBe(1); + }, TIMEOUT + ); + + test("Clangorous Soul fails if all stats involved are at max", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + leadPokemon.summonData.battleStats[BattleStat.ATK] = 6; + leadPokemon.summonData.battleStats[BattleStat.DEF] = 6; + leadPokemon.summonData.battleStats[BattleStat.SPATK] = 6; + leadPokemon.summonData.battleStats[BattleStat.SPDEF] = 6; + leadPokemon.summonData.battleStats[BattleStat.SPD] = 6; + + game.doAttack(getMovePosition(game.scene, 0, Moves.CLANGOROUS_SOUL)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.DEF]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.SPATK]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.SPDEF]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.SPD]).toBe(6); + }, TIMEOUT + ); + + test("Clangorous Soul fails if the user's health is less than 1/3", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); + leadPokemon.hp = hpLost - PREDAMAGE; + + game.doAttack(getMovePosition(game.scene, 0, Moves.CLANGOROUS_SOUL)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(hpLost - PREDAMAGE); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(0); + expect(leadPokemon.summonData.battleStats[BattleStat.DEF]).toBe(0); + expect(leadPokemon.summonData.battleStats[BattleStat.SPATK]).toBe(0); + expect(leadPokemon.summonData.battleStats[BattleStat.SPDEF]).toBe(0); + expect(leadPokemon.summonData.battleStats[BattleStat.SPD]).toBe(0); + }, TIMEOUT + ); +}); diff --git a/src/test/moves/double_team.test.ts b/src/test/moves/double_team.test.ts index de9bd01fd5b..48b322f5f11 100644 --- a/src/test/moves/double_team.test.ts +++ b/src/test/moves/double_team.test.ts @@ -1,15 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - TurnEndPhase, -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; import { BattleStat } from "#app/data/battle-stat.js"; import { Abilities } from "#app/enums/abilities.js"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Moves - Double Team", () => { let phaserGame: Phaser.Game; @@ -27,13 +24,13 @@ describe("Moves - Double Team", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DOUBLE_TEAM]); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SHUCKLE); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override.battleType("single"); + game.override.moveset([Moves.DOUBLE_TEAM]); + game.override.disableCrits(); + game.override.ability(Abilities.BALL_FETCH); + game.override.enemySpecies(Species.SHUCKLE); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); }); it("increases the user's evasion by one stage.", async () => { diff --git a/src/test/moves/dragon_rage.test.ts b/src/test/moves/dragon_rage.test.ts index a6044044aa4..2facff3428f 100644 --- a/src/test/moves/dragon_rage.test.ts +++ b/src/test/moves/dragon_rage.test.ts @@ -1,17 +1,17 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { TurnEndPhase } from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; -import { Species } from "#app/enums/species.js"; -import { Type } from "#app/data/type"; import { BattleStat } from "#app/data/battle-stat"; -import { BattlerTagType } from "#enums/battler-tag-type"; +import { Type } from "#app/data/type"; +import { Species } from "#app/enums/species.js"; import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon"; import { modifierTypes } from "#app/modifier/modifier-type"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Moves } from "#enums/moves"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Moves - Dragon Rage", () => { let phaserGame: Phaser.Game; @@ -34,20 +34,20 @@ describe("Moves - Dragon Rage", () => { beforeEach(async () => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + game.override.battleType("single"); + game.override.disableCrits(); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DRAGON_RAGE]); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); + game.override.starterSpecies(Species.SNORLAX); + game.override.moveset([Moves.DRAGON_RAGE]); + game.override.ability(Abilities.BALL_FETCH); + game.override.passiveAbility(Abilities.BALL_FETCH); + game.override.startingLevel(100); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); + game.override.enemySpecies(Species.SNORLAX); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemyPassiveAbility(Abilities.BALL_FETCH); + game.override.enemyLevel(100); await game.startBattle(); @@ -111,7 +111,7 @@ describe("Moves - Dragon Rage", () => { }); it("ignores damage modification from abilities such as ice scales", async () => { - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.ICE_SCALES); + game.override.enemyAbility(Abilities.ICE_SCALES); game.doAttack(getMovePosition(game.scene, 0, Moves.DRAGON_RAGE)); await game.phaseInterceptor.to(TurnEndPhase); diff --git a/src/test/moves/dynamax_cannon.test.ts b/src/test/moves/dynamax_cannon.test.ts index aab1b210f68..8af6a624797 100644 --- a/src/test/moves/dynamax_cannon.test.ts +++ b/src/test/moves/dynamax_cannon.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { MoveEffectPhase, DamagePhase, TurnStartPhase } from "#app/phases"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; +import { BattlerIndex } from "#app/battle"; import { allMoves } from "#app/data/move"; +import { DamagePhase, MoveEffectPhase, TurnStartPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { BattlerIndex } from "#app/battle"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Moves - Dynamax Cannon", () => { let phaserGame: Phaser.Game; @@ -28,22 +27,22 @@ describe("Moves - Dynamax Cannon", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ dynamaxCannon.id ]); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(200); + game.override.moveset([ dynamaxCannon.id ]); + game.override.startingLevel(200); // Note that, for Waves 1-10, the level cap is 10 - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(1); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + game.override.startingWave(1); + game.override.battleType("single"); + game.override.disableCrits(); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); vi.spyOn(dynamaxCannon, "calculateBattlePower"); }); it("should return 100 power against an enemy below level cap", async() => { - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(1); + game.override.enemyLevel(1); await game.startBattle([ Species.ETERNATUS, ]); @@ -57,7 +56,7 @@ describe("Moves - Dynamax Cannon", () => { }, 20000); it("should return 100 power against an enemy at level cap", async() => { - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(10); + game.override.enemyLevel(10); await game.startBattle([ Species.ETERNATUS, ]); @@ -71,7 +70,7 @@ describe("Moves - Dynamax Cannon", () => { }, 20000); it("should return 120 power against an enemy 1% above level cap", async() => { - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(101); + game.override.enemyLevel(101); await game.startBattle([ Species.ETERNATUS, ]); @@ -88,7 +87,7 @@ describe("Moves - Dynamax Cannon", () => { }, 20000); it("should return 140 power against an enemy 2% above level capp", async() => { - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(102); + game.override.enemyLevel(102); await game.startBattle([ Species.ETERNATUS, ]); @@ -105,7 +104,7 @@ describe("Moves - Dynamax Cannon", () => { }, 20000); it("should return 160 power against an enemy 3% above level cap", async() => { - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(103); + game.override.enemyLevel(103); await game.startBattle([ Species.ETERNATUS, ]); @@ -122,7 +121,7 @@ describe("Moves - Dynamax Cannon", () => { }, 20000); it("should return 180 power against an enemy 4% above level cap", async() => { - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(104); + game.override.enemyLevel(104); await game.startBattle([ Species.ETERNATUS, ]); @@ -139,7 +138,7 @@ describe("Moves - Dynamax Cannon", () => { }, 20000); it("should return 200 power against an enemy 5% above level cap", async() => { - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(105); + game.override.enemyLevel(105); await game.startBattle([ Species.ETERNATUS, ]); @@ -156,7 +155,7 @@ describe("Moves - Dynamax Cannon", () => { }, 20000); it("should return 200 power against an enemy way above level cap", async() => { - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(999); + game.override.enemyLevel(999); await game.startBattle([ Species.ETERNATUS, ]); diff --git a/src/test/moves/fillet_away.test.ts b/src/test/moves/fillet_away.test.ts new file mode 100644 index 00000000000..a3922b18468 --- /dev/null +++ b/src/test/moves/fillet_away.test.ts @@ -0,0 +1,118 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { TurnEndPhase } from "#app/phases"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { BattleStat } from "#app/data/battle-stat"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; + +const TIMEOUT = 20 * 1000; +/** HP Cost of Move */ +const RATIO = 2; +/** Amount of extra HP lost */ +const PREDAMAGE = 15; + +describe("Moves - FILLET AWAY", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.starterSpecies(Species.MAGIKARP); + game.override.enemySpecies(Species.SNORLAX); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override.moveset([Moves.FILLET_AWAY]); + game.override.enemyMoveset(SPLASH_ONLY); + }); + + //Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/fillet_away_(move) + + test("Fillet Away raises the user's Attack, Special Attack, and Speed by two stages each, at the cost of 1/2 of its maximum HP", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); + + game.doAttack(getMovePosition(game.scene, 0, Moves.FILLET_AWAY)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp() - hpLost); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(2); + expect(leadPokemon.summonData.battleStats[BattleStat.SPATK]).toBe(2); + expect(leadPokemon.summonData.battleStats[BattleStat.SPD]).toBe(2); + }, TIMEOUT + ); + + test("Fillet Away will still take effect if one or more of the involved stats are not at max", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); + + //Here - BattleStat.SPD -> 0 and BattleStat.SPATK -> 3 + leadPokemon.summonData.battleStats[BattleStat.ATK] = 6; + leadPokemon.summonData.battleStats[BattleStat.SPATK] = 3; + + game.doAttack(getMovePosition(game.scene, 0, Moves.FILLET_AWAY)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp() - hpLost); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.SPATK]).toBe(5); + expect(leadPokemon.summonData.battleStats[BattleStat.SPD]).toBe(2); + }, TIMEOUT + ); + + test("Fillet Away fails if all stats involved are at max", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + + leadPokemon.summonData.battleStats[BattleStat.ATK] = 6; + leadPokemon.summonData.battleStats[BattleStat.SPATK] = 6; + leadPokemon.summonData.battleStats[BattleStat.SPD] = 6; + + game.doAttack(getMovePosition(game.scene, 0, Moves.FILLET_AWAY)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.SPATK]).toBe(6); + expect(leadPokemon.summonData.battleStats[BattleStat.SPD]).toBe(6); + }, TIMEOUT + ); + + test("Fillet Away fails if the user's health is less than 1/2", + async() => { + await game.startBattle([Species.MAGIKARP]); + + const leadPokemon = game.scene.getPlayerPokemon(); + const hpLost = Math.floor(leadPokemon.getMaxHp() / RATIO); + leadPokemon.hp = hpLost - PREDAMAGE; + + game.doAttack(getMovePosition(game.scene, 0, Moves.FILLET_AWAY)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leadPokemon.hp).toBe(hpLost - PREDAMAGE); + expect(leadPokemon.summonData.battleStats[BattleStat.ATK]).toBe(0); + expect(leadPokemon.summonData.battleStats[BattleStat.SPATK]).toBe(0); + expect(leadPokemon.summonData.battleStats[BattleStat.SPD]).toBe(0); + }, TIMEOUT + ); +}); diff --git a/src/test/moves/fissure.test.ts b/src/test/moves/fissure.test.ts index f91c01ebbe2..f2f58212209 100644 --- a/src/test/moves/fissure.test.ts +++ b/src/test/moves/fissure.test.ts @@ -1,14 +1,14 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { DamagePhase, TurnEndPhase } from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; +import { BattleStat } from "#app/data/battle-stat"; import { Species } from "#app/enums/species.js"; import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon"; -import { BattleStat } from "#app/data/battle-stat"; +import { DamagePhase, TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Moves - Fissure", () => { let phaserGame: Phaser.Game; @@ -29,18 +29,18 @@ describe("Moves - Fissure", () => { beforeEach(async () => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + game.override.battleType("single"); + game.override.disableCrits(); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.FISSURE]); - vi.spyOn(Overrides, "PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); + game.override.starterSpecies(Species.SNORLAX); + game.override.moveset([Moves.FISSURE]); + game.override.passiveAbility(Abilities.BALL_FETCH); + game.override.startingLevel(100); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); + game.override.enemySpecies(Species.SNORLAX); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyPassiveAbility(Abilities.BALL_FETCH); + game.override.enemyLevel(100); await game.startBattle(); @@ -53,8 +53,8 @@ describe("Moves - Fissure", () => { }); it("ignores damage modification from abilities such as fur coat", async () => { - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NO_GUARD); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.FUR_COAT); + game.override.ability(Abilities.NO_GUARD); + game.override.enemyAbility(Abilities.FUR_COAT); game.doAttack(getMovePosition(game.scene, 0, Moves.FISSURE)); await game.phaseInterceptor.to(DamagePhase, true); diff --git a/src/test/moves/flame_burst.test.ts b/src/test/moves/flame_burst.test.ts new file mode 100644 index 00000000000..0f9e311ca86 --- /dev/null +++ b/src/test/moves/flame_burst.test.ts @@ -0,0 +1,114 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { Species } from "#enums/species"; +import { SelectTargetPhase, TurnEndPhase } from "#app/phases"; +import { Moves } from "#enums/moves"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#app/enums/abilities.js"; +import { allAbilities } from "#app/data/ability.js"; +import Pokemon from "#app/field/pokemon.js"; + +describe("Moves - Flame Burst", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + /** + * Calculates the effect damage of Flame Burst which is 1/16 of the target ally's max HP + * See Flame Burst {@link https://bulbapedia.bulbagarden.net/wiki/Flame_Burst_(move)} + * See Flame Burst's move attribute {@linkcode FlameBurstAttr} + * @param pokemon {@linkcode Pokemon} - The ally of the move's target + * @returns Effect damage of Flame Burst + */ + const getEffectDamage = (pokemon: Pokemon): number => { + return Math.max(1, Math.floor(pokemon.getMaxHp() * 1/16)); + }; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.battleType("double"); + game.override.moveset([Moves.FLAME_BURST, Moves.SPLASH]); + game.override.disableCrits(); + game.override.ability(Abilities.UNNERVE); + game.override.startingWave(4); + game.override.enemySpecies(Species.SHUCKLE); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemyMoveset(new Array(4).fill(Moves.SPLASH)); + }); + + it("inflicts damage to the target's ally equal to 1/16 of its max HP", async () => { + await game.startBattle([Species.PIKACHU, Species.PIKACHU]); + const [ leftEnemy, rightEnemy ] = game.scene.getEnemyField(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.FLAME_BURST)); + await game.phaseInterceptor.to(SelectTargetPhase, false); + game.doSelectTarget(leftEnemy.getBattlerIndex()); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leftEnemy.hp).toBeLessThan(leftEnemy.getMaxHp()); + expect(rightEnemy.hp).toBe(rightEnemy.getMaxHp() - getEffectDamage(rightEnemy)); + }); + + it("does not inflict damage to the target's ally if the target was not affected by Flame Burst", async () => { + game.override.enemyAbility(Abilities.FLASH_FIRE); + + await game.startBattle([Species.PIKACHU, Species.PIKACHU]); + const [ leftEnemy, rightEnemy ] = game.scene.getEnemyField(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.FLAME_BURST)); + await game.phaseInterceptor.to(SelectTargetPhase, false); + game.doSelectTarget(leftEnemy.getBattlerIndex()); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leftEnemy.hp).toBe(leftEnemy.getMaxHp()); + expect(rightEnemy.hp).toBe(rightEnemy.getMaxHp()); + }); + + it("does not interact with the target ally's abilities", async () => { + await game.startBattle([Species.PIKACHU, Species.PIKACHU]); + const [ leftEnemy, rightEnemy ] = game.scene.getEnemyField(); + + vi.spyOn(rightEnemy, "getAbility").mockReturnValue(allAbilities[Abilities.FLASH_FIRE]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.FLAME_BURST)); + await game.phaseInterceptor.to(SelectTargetPhase, false); + game.doSelectTarget(leftEnemy.getBattlerIndex()); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leftEnemy.hp).toBeLessThan(leftEnemy.getMaxHp()); + expect(rightEnemy.hp).toBe(rightEnemy.getMaxHp() - getEffectDamage(rightEnemy)); + }); + + it("effect damage is prevented by Magic Guard", async () => { + await game.startBattle([Species.PIKACHU, Species.PIKACHU]); + const [ leftEnemy, rightEnemy ] = game.scene.getEnemyField(); + + vi.spyOn(rightEnemy, "getAbility").mockReturnValue(allAbilities[Abilities.MAGIC_GUARD]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.FLAME_BURST)); + await game.phaseInterceptor.to(SelectTargetPhase, false); + game.doSelectTarget(leftEnemy.getBattlerIndex()); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + await game.phaseInterceptor.to(TurnEndPhase); + + expect(leftEnemy.hp).toBeLessThan(leftEnemy.getMaxHp()); + expect(rightEnemy.hp).toBe(rightEnemy.getMaxHp()); + }); + + it("is not affected by protection moves and Endure", async () => { + // TODO: update this test when it's possible to select move for each enemy + }, { skip: true }); +}); diff --git a/src/test/moves/flower_shield.test.ts b/src/test/moves/flower_shield.test.ts index c36a45790c7..a00c84f8714 100644 --- a/src/test/moves/flower_shield.test.ts +++ b/src/test/moves/flower_shield.test.ts @@ -1,18 +1,16 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - TurnEndPhase, -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; import { BattleStat } from "#app/data/battle-stat.js"; -import { Biome } from "#app/enums/biome.js"; -import { Type } from "#app/data/type.js"; import { SemiInvulnerableTag } from "#app/data/battler-tags.js"; +import { Type } from "#app/data/type.js"; +import { Biome } from "#app/enums/biome.js"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Moves - Flower Shield", () => { let phaserGame: Phaser.Game; @@ -30,15 +28,15 @@ describe("Moves - Flower Shield", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.FLOWER_SHIELD, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.ability(Abilities.NONE); + game.override.enemyAbility(Abilities.NONE); + game.override.battleType("single"); + game.override.moveset([Moves.FLOWER_SHIELD, Moves.SPLASH]); + game.override.enemyMoveset(SPLASH_ONLY); }); it("increases defense of all Grass-type Pokemon on the field by one stage - single battle", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.CHERRIM); + game.override.enemySpecies(Species.CHERRIM); await game.startBattle([Species.MAGIKARP]); const cherrim = game.scene.getEnemyPokemon(); @@ -55,9 +53,7 @@ describe("Moves - Flower Shield", () => { }); it("increases defense of all Grass-type Pokemon on the field by one stage - double battle", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "STARTING_BIOME_OVERRIDE", "get").mockReturnValue(Biome.GRASS); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); + game.override.enemySpecies(Species.MAGIKARP).startingBiome(Biome.GRASS).battleType("double"); await game.startBattle([Species.CHERRIM, Species.MAGIKARP]); const field = game.scene.getField(true); @@ -80,9 +76,9 @@ describe("Moves - Flower Shield", () => { * See semi-vulnerable state tags. {@linkcode SemiInvulnerableTag} */ it("does not increase defense of a pokemon in semi-vulnerable state", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.PARAS); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DIG, Moves.DIG, Moves.DIG, Moves.DIG]); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(50); + game.override.enemySpecies(Species.PARAS); + game.override.enemyMoveset([Moves.DIG, Moves.DIG, Moves.DIG, Moves.DIG]); + game.override.enemyLevel(50); await game.startBattle([Species.CHERRIM]); const paras = game.scene.getEnemyPokemon(); @@ -101,7 +97,7 @@ describe("Moves - Flower Shield", () => { }); it("does nothing if there are no Grass-type pokemon on the field", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); + game.override.enemySpecies(Species.MAGIKARP); await game.startBattle([Species.MAGIKARP]); const enemy = game.scene.getEnemyPokemon(); diff --git a/src/test/moves/follow_me.test.ts b/src/test/moves/follow_me.test.ts index 738c9b6e837..420dd7e0762 100644 --- a/src/test/moves/follow_me.test.ts +++ b/src/test/moves/follow_me.test.ts @@ -1,18 +1,13 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, test, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase, - SelectTargetPhase, - TurnEndPhase, -} from "#app/phases"; -import {Stat} from "#app/data/pokemon-stat"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { BattlerIndex } from "#app/battle.js"; +import { Stat } from "#app/data/pokemon-stat"; +import { Abilities } from "#app/enums/abilities.js"; +import { CommandPhase, SelectTargetPhase, TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { BattlerIndex } from "#app/battle.js"; -import { Abilities } from "#app/enums/abilities.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -32,13 +27,13 @@ describe("Moves - Follow Me", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.AMOONGUSS); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK ]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("double"); + game.override.starterSpecies(Species.AMOONGUSS); + game.override.enemySpecies(Species.SNORLAX); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override.moveset([ Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK ]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); }); test( @@ -101,9 +96,9 @@ describe("Moves - Follow Me", () => { test( "move effect should be bypassed by Stalwart", async () => { - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.STALWART); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.QUICK_ATTACK ]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME ]); + game.override.ability(Abilities.STALWART); + game.override.moveset([ Moves.QUICK_ATTACK ]); + game.override.enemyMoveset([ Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME ]); await game.startBattle([ Species.AMOONGUSS, Species.CHARIZARD ]); @@ -136,8 +131,8 @@ describe("Moves - Follow Me", () => { test( "move effect should be bypassed by Snipe Shot", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.SNIPE_SHOT ]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME ]); + game.override.moveset([ Moves.SNIPE_SHOT ]); + game.override.enemyMoveset([ Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME ]); await game.startBattle([ Species.AMOONGUSS, Species.CHARIZARD ]); diff --git a/src/test/moves/fusion_bolt.test.ts b/src/test/moves/fusion_bolt.test.ts new file mode 100644 index 00000000000..3ba4148db9f --- /dev/null +++ b/src/test/moves/fusion_bolt.test.ts @@ -0,0 +1,53 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Species } from "#enums/species"; +import { Moves } from "#enums/moves"; +import { Abilities } from "#enums/abilities"; + +describe("Moves - Fusion Bolt", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + const fusionBolt = Moves.FUSION_BOLT; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.moveset([ fusionBolt ]); + game.override.startingLevel(1); + + game.override.enemySpecies(Species.RESHIRAM); + game.override.enemyAbility(Abilities.ROUGH_SKIN); + game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); + + game.override.battleType("single"); + game.override.startingWave(97); + game.override.disableCrits(); + }); + + it("should not make contact", async() => { + await game.startBattle([ + Species.ZEKROM, + ]); + + const partyMember = game.scene.getPlayerPokemon(); + const initialHp = partyMember.hp; + + game.doAttack(getMovePosition(game.scene, 0, fusionBolt)); + + await game.toNextTurn(); + + expect(initialHp - partyMember.hp).toBe(0); + }, 20000); +}); diff --git a/src/test/moves/fusion_flare.test.ts b/src/test/moves/fusion_flare.test.ts new file mode 100644 index 00000000000..9862995be32 --- /dev/null +++ b/src/test/moves/fusion_flare.test.ts @@ -0,0 +1,59 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { TurnStartPhase } from "#app/phases"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { StatusEffect } from "#app/data/status-effect"; +import { Species } from "#enums/species"; +import { Moves } from "#enums/moves"; + +describe("Moves - Fusion Flare", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + const fusionFlare = Moves.FUSION_FLARE; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.moveset([ fusionFlare ]); + game.override.startingLevel(1); + + game.override.enemySpecies(Species.RESHIRAM); + game.override.enemyMoveset([ Moves.REST, Moves.REST, Moves.REST, Moves.REST ]); + + game.override.battleType("single"); + game.override.startingWave(97); + game.override.disableCrits(); + }); + + it("should thaw freeze status condition", async() => { + await game.startBattle([ + Species.RESHIRAM, + ]); + + const partyMember = game.scene.getPlayerPokemon(); + + game.doAttack(getMovePosition(game.scene, 0, fusionFlare)); + + await game.phaseInterceptor.to(TurnStartPhase, false); + + // Inflict freeze quietly and check if it was properly inflicted + partyMember.trySetStatus(StatusEffect.FREEZE, false); + expect(partyMember.status.effect).toBe(StatusEffect.FREEZE); + + await game.toNextTurn(); + + // Check if FUSION_FLARE thawed freeze + expect(partyMember.status?.effect).toBeUndefined(); + }); +}); diff --git a/src/test/moves/fusion_flare_bolt.test.ts b/src/test/moves/fusion_flare_bolt.test.ts new file mode 100644 index 00000000000..e04d766f848 --- /dev/null +++ b/src/test/moves/fusion_flare_bolt.test.ts @@ -0,0 +1,322 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#test/utils/gameManager"; +import { MoveEffectPhase, MovePhase, MoveEndPhase, TurnStartPhase, DamagePhase } from "#app/phases"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Stat } from "#app/data/pokemon-stat"; +import { allMoves } from "#app/data/move"; +import { BattlerIndex } from "#app/battle"; +import { Species } from "#enums/species"; +import { Moves } from "#enums/moves"; + +describe("Moves - Fusion Flare and Fusion Bolt", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + const fusionFlare = allMoves[Moves.FUSION_FLARE]; + const fusionBolt = allMoves[Moves.FUSION_BOLT]; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override.moveset([ fusionFlare.id, fusionBolt.id ]); + game.override.startingLevel(1); + + game.override.enemySpecies(Species.RESHIRAM); + game.override.enemyMoveset([ Moves.REST, Moves.REST, Moves.REST, Moves.REST ]); + + game.override.battleType("double"); + game.override.startingWave(97); + game.override.disableCrits(); + + vi.spyOn(fusionFlare, "calculateBattlePower"); + vi.spyOn(fusionBolt, "calculateBattlePower"); + }); + + it("FUSION_FLARE should double power of subsequent FUSION_BOLT", async() => { + await game.startBattle([ + Species.ZEKROM, + Species.ZEKROM + ]); + + game.doAttack(getMovePosition(game.scene, 0, fusionFlare.id)); + game.doSelectTarget(BattlerIndex.ENEMY); + + game.doAttack(getMovePosition(game.scene, 0, fusionBolt.id)); + game.doSelectTarget(BattlerIndex.ENEMY); + + await game.phaseInterceptor.to(TurnStartPhase, false); + + // Force user party to act before enemy party + vi.spyOn(game.scene.getCurrentPhase() as TurnStartPhase, "getOrder").mockReturnValue([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(100); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); + }, 20000); + + it("FUSION_BOLT should double power of subsequent FUSION_FLARE", async() => { + await game.startBattle([ + Species.ZEKROM, + Species.ZEKROM + ]); + + game.doAttack(getMovePosition(game.scene, 0, fusionBolt.id)); + game.doSelectTarget(BattlerIndex.ENEMY); + + game.doAttack(getMovePosition(game.scene, 0, fusionFlare.id)); + game.doSelectTarget(BattlerIndex.ENEMY); + + await game.phaseInterceptor.to(TurnStartPhase, false); + + // Force user party to act before enemy party + vi.spyOn(game.scene.getCurrentPhase() as TurnStartPhase, "getOrder").mockReturnValue([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); + }, 20000); + + it("FUSION_FLARE should double power of subsequent FUSION_BOLT if a move failed in between", async() => { + await game.startBattle([ + Species.ZEKROM, + Species.ZEKROM + ]); + + game.doAttack(getMovePosition(game.scene, 0, fusionFlare.id)); + game.doSelectTarget(0); + + game.doAttack(getMovePosition(game.scene, 0, fusionBolt.id)); + game.doSelectTarget(0); + + await game.phaseInterceptor.to(TurnStartPhase, false); + + // Force first enemy to act (and fail) in between party + vi.spyOn(game.scene.getCurrentPhase() as TurnStartPhase, "getOrder").mockReturnValue([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(100); + + await game.phaseInterceptor.to(MoveEndPhase); + + // Skip enemy move; because the enemy is at full HP, Rest should fail + await game.phaseInterceptor.runFrom(MovePhase).to(MoveEndPhase); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); + }, 20000); + + it("FUSION_FLARE should not double power of subsequent FUSION_BOLT if a move succeeded in between", async() => { + game.override.enemyMoveset([ Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH ]); + await game.startBattle([ + Species.ZEKROM, + Species.ZEKROM + ]); + + game.doAttack(getMovePosition(game.scene, 0, fusionFlare.id)); + game.doSelectTarget(BattlerIndex.ENEMY); + + game.doAttack(getMovePosition(game.scene, 0, fusionBolt.id)); + game.doSelectTarget(BattlerIndex.ENEMY); + + await game.phaseInterceptor.to(TurnStartPhase, false); + + // Force first enemy to act in between party + vi.spyOn(game.scene.getCurrentPhase() as TurnStartPhase, "getOrder").mockReturnValue([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(100); + + await game.phaseInterceptor.to(MoveEndPhase); + // Skip enemy move + await game.phaseInterceptor.runFrom(MovePhase).to(MoveEndPhase); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); + }, 20000); + + it("FUSION_FLARE should double power of subsequent FUSION_BOLT if moves are aimed at allies", async() => { + await game.startBattle([ + Species.ZEKROM, + Species.RESHIRAM + ]); + + game.doAttack(getMovePosition(game.scene, 0, fusionBolt.id)); + game.doSelectTarget(BattlerIndex.PLAYER_2); + + game.doAttack(getMovePosition(game.scene, 0, fusionFlare.id)); + game.doSelectTarget(BattlerIndex.PLAYER); + + await game.phaseInterceptor.to(TurnStartPhase, false); + + // Force user party to act before enemy party + vi.spyOn(game.scene.getCurrentPhase() as TurnStartPhase, "getOrder").mockReturnValue([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); + }, 20000); + + it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves", async() => { + game.override.enemyMoveset([ fusionFlare.id, fusionFlare.id, fusionFlare.id, fusionFlare.id ]); + await game.startBattle([ + Species.ZEKROM, + Species.ZEKROM + ]); + + const party = game.scene.getParty(); + const enemyParty = game.scene.getEnemyParty(); + + // Get rid of any modifiers that may alter power + game.scene.clearEnemyHeldItemModifiers(); + game.scene.clearEnemyModifiers(); + + // Mock stats by replacing entries in copy with desired values for specific stats + const stats = { + enemy: [ + [...enemyParty[0].stats], + [...enemyParty[1].stats], + ], + player: [ + [...party[0].stats], + [...party[1].stats], + ] + }; + + // Ensure survival by reducing enemy Sp. Atk and boosting party Sp. Def + vi.spyOn(enemyParty[0], "stats", "get").mockReturnValue(stats.enemy[0].map((val, i) => (i === Stat.SPATK ? 1 : val))); + vi.spyOn(enemyParty[1], "stats", "get").mockReturnValue(stats.enemy[1].map((val, i) => (i === Stat.SPATK ? 1 : val))); + vi.spyOn(party[1], "stats", "get").mockReturnValue(stats.player[0].map((val, i) => (i === Stat.SPDEF ? 250 : val))); + vi.spyOn(party[1], "stats", "get").mockReturnValue(stats.player[1].map((val, i) => (i === Stat.SPDEF ? 250 : val))); + + game.doAttack(getMovePosition(game.scene, 0, fusionBolt.id)); + game.doSelectTarget(BattlerIndex.ENEMY); + + game.doAttack(getMovePosition(game.scene, 0, fusionBolt.id)); + game.doSelectTarget(BattlerIndex.ENEMY); + + await game.phaseInterceptor.to(TurnStartPhase, false); + + // Force first enemy to act in between party + vi.spyOn(game.scene.getCurrentPhase() as TurnStartPhase, "getOrder").mockReturnValue([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); + }, 20000); + + it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves if moves are aimed at allies", async() => { + game.override.enemyMoveset([ fusionFlare.id, fusionFlare.id, fusionFlare.id, fusionFlare.id ]); + await game.startBattle([ + Species.ZEKROM, + Species.ZEKROM + ]); + + const party = game.scene.getParty(); + const enemyParty = game.scene.getEnemyParty(); + + // Get rid of any modifiers that may alter power + game.scene.clearEnemyHeldItemModifiers(); + game.scene.clearEnemyModifiers(); + + // Mock stats by replacing entries in copy with desired values for specific stats + const stats = { + enemy: [ + [...enemyParty[0].stats], + [...enemyParty[1].stats], + ], + player: [ + [...party[0].stats], + [...party[1].stats], + ] + }; + + // Ensure survival by reducing enemy Sp. Atk and boosting party Sp. Def + vi.spyOn(enemyParty[0], "stats", "get").mockReturnValue(stats.enemy[0].map((val, i) => (i === Stat.SPATK ? 1 : val))); + vi.spyOn(enemyParty[1], "stats", "get").mockReturnValue(stats.enemy[1].map((val, i) => (i === Stat.SPATK ? 1 : val))); + vi.spyOn(party[1], "stats", "get").mockReturnValue(stats.player[0].map((val, i) => (i === Stat.SPDEF ? 250 : val))); + vi.spyOn(party[1], "stats", "get").mockReturnValue(stats.player[1].map((val, i) => (i === Stat.SPDEF ? 250 : val))); + + game.doAttack(getMovePosition(game.scene, 0, fusionBolt.id)); + game.doSelectTarget(BattlerIndex.PLAYER_2); + + game.doAttack(getMovePosition(game.scene, 0, fusionBolt.id)); + game.doSelectTarget(BattlerIndex.PLAYER); + + await game.phaseInterceptor.to(TurnStartPhase, false); + + // Force first enemy to act in between party + vi.spyOn(game.scene.getCurrentPhase() as TurnStartPhase, "getOrder").mockReturnValue([ BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY ]); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionBolt.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + expect((game.scene.getCurrentPhase() as MoveEffectPhase).move.moveId).toBe(fusionFlare.id); + await game.phaseInterceptor.to(DamagePhase, false); + expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); + }, 20000); +}); diff --git a/src/test/moves/gastro_acid.test.ts b/src/test/moves/gastro_acid.test.ts index c8f6ab6cc6a..cd1f0e4ab12 100644 --- a/src/test/moves/gastro_acid.test.ts +++ b/src/test/moves/gastro_acid.test.ts @@ -1,15 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import GameManager from "../utils/gameManager"; -import { - Moves -} from "#app/enums/moves.js"; -import Overrides from "#app/overrides"; -import { Abilities } from "#app/enums/abilities.js"; import { BattlerIndex } from "#app/battle.js"; -import { getMovePosition } from "../utils/gameManagerUtils"; -import { MoveResult } from "#app/field/pokemon.js"; import { Stat } from "#app/data/pokemon-stat.js"; +import { Abilities } from "#app/enums/abilities.js"; +import { Moves } from "#app/enums/moves.js"; import { Species } from "#app/enums/species.js"; +import { MoveResult } from "#app/field/pokemon.js"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -29,14 +27,14 @@ describe("Moves - Gastro Acid", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(1); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.GASTRO_ACID, Moves.WATER_GUN, Moves.SPLASH, Moves.CORE_ENFORCER]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.BIDOOF); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.WATER_ABSORB); + game.override.battleType("double"); + game.override.startingLevel(1); + game.override.enemyLevel(100); + game.override.ability(Abilities.NONE); + game.override.moveset([Moves.GASTRO_ACID, Moves.WATER_GUN, Moves.SPLASH, Moves.CORE_ENFORCER]); + game.override.enemySpecies(Species.BIDOOF); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.WATER_ABSORB); }); it("suppresses effect of ability", async () => { @@ -72,7 +70,7 @@ describe("Moves - Gastro Acid", () => { }, TIMEOUT); it("fails if used on an enemy with an already-suppressed ability", async () => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue(null); + game.override.battleType(null); await game.startBattle(); diff --git a/src/test/moves/glaive_rush.test.ts b/src/test/moves/glaive_rush.test.ts index 8cc2dc73b72..fc9f6ee1c7f 100644 --- a/src/test/moves/glaive_rush.test.ts +++ b/src/test/moves/glaive_rush.test.ts @@ -1,13 +1,12 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; +import { allMoves } from "#app/data/move.js"; +import { Abilities } from "#app/enums/abilities.js"; import { DamagePhase, TurnEndPhase } from "#app/phases"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { Abilities } from "#app/enums/abilities.js"; -import { allMoves } from "#app/data/move.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Moves - Glaive Rush", () => { @@ -26,15 +25,15 @@ describe("Moves - Glaive Rush", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(Array(4).fill(Moves.GLAIVE_RUSH)); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.KLINK); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.UNNERVE); - vi.spyOn(Overrides, "PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.FUR_COAT); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SHADOW_SNEAK, Moves.AVALANCHE, Moves.SPLASH, Moves.GLAIVE_RUSH]); + game.override.battleType("single"); + game.override.disableCrits(); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemyMoveset(Array(4).fill(Moves.GLAIVE_RUSH)); + game.override.starterSpecies(Species.KLINK); + game.override.ability(Abilities.UNNERVE); + game.override.passiveAbility(Abilities.FUR_COAT); + game.override.moveset([Moves.SHADOW_SNEAK, Moves.AVALANCHE, Moves.SPLASH, Moves.GLAIVE_RUSH]); }); it("takes double damage from attacks", async() => { @@ -66,8 +65,8 @@ describe("Moves - Glaive Rush", () => { }, 20000); it("interacts properly with multi-lens", async() => { - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([{name: "MULTI_LENS", count: 2}]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(Array(4).fill(Moves.AVALANCHE)); + game.override.startingHeldItems([{name: "MULTI_LENS", count: 2}]); + game.override.enemyMoveset(Array(4).fill(Moves.AVALANCHE)); await game.startBattle(); const player = game.scene.getPlayerPokemon(); const enemy = game.scene.getEnemyPokemon(); @@ -86,7 +85,7 @@ describe("Moves - Glaive Rush", () => { }, 20000); it("secondary effects only last until next move", async() => { - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(Array(4).fill(Moves.SHADOW_SNEAK)); + game.override.enemyMoveset(Array(4).fill(Moves.SHADOW_SNEAK)); await game.startBattle(); const player = game.scene.getPlayerPokemon(); const enemy = game.scene.getEnemyPokemon(); @@ -110,8 +109,8 @@ describe("Moves - Glaive Rush", () => { }, 20000); it("secondary effects are removed upon switching", async() => { - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(Array(4).fill(Moves.SHADOW_SNEAK)); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(0); + game.override.enemyMoveset(Array(4).fill(Moves.SHADOW_SNEAK)); + game.override.starterSpecies(0); await game.startBattle([Species.KLINK, Species.FEEBAS]); const player = game.scene.getPlayerPokemon(); const enemy = game.scene.getEnemyPokemon(); diff --git a/src/test/moves/growth.test.ts b/src/test/moves/growth.test.ts index 6068c114fc3..bfa3cc54896 100644 --- a/src/test/moves/growth.test.ts +++ b/src/test/moves/growth.test.ts @@ -1,20 +1,15 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase, - EnemyCommandPhase, - TurnInitPhase, -} from "#app/phases"; -import {Mode} from "#app/ui/ui"; -import {Stat} from "#app/data/pokemon-stat"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; -import {Command} from "#app/ui/command-ui-handler"; -import {BattleStat} from "#app/data/battle-stat"; +import { BattleStat } from "#app/data/battle-stat"; +import { Stat } from "#app/data/pokemon-stat"; +import { CommandPhase, EnemyCommandPhase, TurnInitPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; +import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Growth", () => { @@ -34,13 +29,13 @@ describe("Moves - Growth", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.GROWTH; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.MOXIE); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("single"); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.MOXIE); + game.override.ability(Abilities.INSOMNIA); + game.override.startingLevel(2000); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); }); it("GROWTH", async() => { diff --git a/src/test/moves/hard_press.test.ts b/src/test/moves/hard_press.test.ts index 8800d66bd9a..6a45e49137b 100644 --- a/src/test/moves/hard_press.test.ts +++ b/src/test/moves/hard_press.test.ts @@ -1,15 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - MoveEffectPhase -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; import { allMoves } from "#app/data/move.js"; +import { MoveEffectPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Moves - Hard Press", () => { let phaserGame: Phaser.Game; @@ -29,12 +27,12 @@ describe("Moves - Hard Press", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MUNCHLAX); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.HARD_PRESS]); + game.override.battleType("single"); + game.override.ability(Abilities.BALL_FETCH); + game.override.enemySpecies(Species.MUNCHLAX); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.moveset([Moves.HARD_PRESS]); vi.spyOn(moveToCheck, "calculateBattlePower"); }); diff --git a/src/test/moves/hyper_beam.test.ts b/src/test/moves/hyper_beam.test.ts index 2a6486c0de5..e7d3454ba32 100644 --- a/src/test/moves/hyper_beam.test.ts +++ b/src/test/moves/hyper_beam.test.ts @@ -1,14 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import overrides from "#app/overrides"; -import { Abilities } from "#app/enums/abilities.js"; -import { Species } from "#app/enums/species.js"; -import { Moves } from "#app/enums/moves.js"; import { allMoves } from "#app/data/move.js"; -import { getMovePosition } from "../utils/gameManagerUtils"; -import { BerryPhase, TurnEndPhase } from "#app/phases.js"; +import { Abilities } from "#app/enums/abilities.js"; import { BattlerTagType } from "#app/enums/battler-tag-type.js"; +import { Moves } from "#app/enums/moves.js"; +import { Species } from "#app/enums/species.js"; +import { BerryPhase, TurnEndPhase } from "#app/phases.js"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; const TIMEOUT = 20 * 1000; // 20 sec timeout for all tests @@ -29,13 +28,13 @@ describe("Moves - Hyper Beam", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(Array(4).fill(Moves.SPLASH)); + game.override.battleType("single"); + game.override.ability(Abilities.BALL_FETCH); + game.override.enemySpecies(Species.SNORLAX); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemyMoveset(Array(4).fill(Moves.SPLASH)); - vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.HYPER_BEAM, Moves.TACKLE]); + game.override.moveset([Moves.HYPER_BEAM, Moves.TACKLE]); vi.spyOn(allMoves[Moves.HYPER_BEAM], "accuracy", "get").mockReturnValue(100); }); diff --git a/src/test/moves/light_screen.test.ts b/src/test/moves/light_screen.test.ts index 5269ec6d8ee..e47b6fe93ea 100644 --- a/src/test/moves/light_screen.test.ts +++ b/src/test/moves/light_screen.test.ts @@ -1,19 +1,16 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - TurnEndPhase, -} from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { ArenaTagSide } from "#app/data/arena-tag.js"; +import Move, { allMoves } from "#app/data/move.js"; +import { Abilities } from "#app/enums/abilities.js"; +import { ArenaTagType } from "#app/enums/arena-tag-type.js"; +import Pokemon from "#app/field/pokemon.js"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { NumberHolder } from "#app/utils.js"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { Abilities } from "#app/enums/abilities.js"; -import Pokemon from "#app/field/pokemon.js"; -import Move, { allMoves } from "#app/data/move.js"; -import { NumberHolder } from "#app/utils.js"; -import { ArenaTagSide } from "#app/data/arena-tag.js"; -import { ArenaTagType } from "#app/enums/arena-tag-type.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Light Screen", () => { @@ -34,13 +31,13 @@ describe("Moves - Light Screen", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.ABSORB, Moves.DAZZLING_GLEAM, Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN]); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + game.override.battleType("single"); + game.override.ability(Abilities.NONE); + game.override.moveset([Moves.ABSORB, Moves.DAZZLING_GLEAM, Moves.TACKLE]); + game.override.enemyLevel(100); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset([Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN, Moves.LIGHT_SCREEN]); + game.override.disableCrits(); }); it("reduces damage of special attacks by half in a single battle", async() => { @@ -57,7 +54,7 @@ describe("Moves - Light Screen", () => { }); it("reduces damage of special attacks by a third in a double battle", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); + game.override.battleType("double"); const moveToUse = Moves.DAZZLING_GLEAM; await game.startBattle([Species.SHUCKLE, Species.SHUCKLE]); diff --git a/src/test/moves/magnet_rise.test.ts b/src/test/moves/magnet_rise.test.ts index 2b06867f0a7..9b3c6c457e2 100644 --- a/src/test/moves/magnet_rise.test.ts +++ b/src/test/moves/magnet_rise.test.ts @@ -1,10 +1,9 @@ -import {beforeAll, afterEach, beforeEach, describe, vi, it, expect} from "vitest"; +import { CommandPhase, TurnEndPhase } from "#app/phases.js"; +import GameManager from "#test/utils/gameManager"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import {Moves} from "#enums/moves"; -import {Species} from "#enums/species"; -import {CommandPhase, TurnEndPhase} from "#app/phases.js"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Magnet Rise", () => { let phaserGame: Phaser.Game; @@ -23,13 +22,13 @@ describe("Moves - Magnet Rise", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.MAGNET_RISE; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGNEZONE); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DRILL_RUN, Moves.DRILL_RUN, Moves.DRILL_RUN, Moves.DRILL_RUN]); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(1); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse, Moves.SPLASH, Moves.GRAVITY, Moves.BATON_PASS]); + game.override.battleType("single"); + game.override.starterSpecies(Species.MAGNEZONE); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyMoveset([Moves.DRILL_RUN, Moves.DRILL_RUN, Moves.DRILL_RUN, Moves.DRILL_RUN]); + game.override.disableCrits(); + game.override.enemyLevel(1); + game.override.moveset([moveToUse, Moves.SPLASH, Moves.GRAVITY, Moves.BATON_PASS]); }); it("MAGNET RISE", async () => { diff --git a/src/test/moves/make_it_rain.test.ts b/src/test/moves/make_it_rain.test.ts index c578a70bb9c..850f8f644b8 100644 --- a/src/test/moves/make_it_rain.test.ts +++ b/src/test/moves/make_it_rain.test.ts @@ -1,17 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - CommandPhase, - MoveEndPhase, - StatChangePhase, -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { Abilities } from "#enums/abilities"; import { BattleStat } from "#app/data/battle-stat.js"; +import { MoveEffectPhase, MoveEndPhase, StatChangePhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -31,29 +27,21 @@ describe("Moves - Make It Rain", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.MAKE_IT_RAIN, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); + game.override.battleType("double"); + game.override.moveset([Moves.MAKE_IT_RAIN, Moves.SPLASH]); + game.override.enemySpecies(Species.SNORLAX); + game.override.enemyAbility(Abilities.INSOMNIA); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.startingLevel(100); + game.override.enemyLevel(100); }); it("should only reduce Sp. Atk. once in a double battle", async () => { await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); const playerPokemon = game.scene.getPlayerField(); - expect(playerPokemon.length).toBe(2); - playerPokemon.forEach(p => expect(p).toBeDefined()); - - const enemyPokemon = game.scene.getEnemyField(); - expect(enemyPokemon.length).toBe(2); - enemyPokemon.forEach(p => expect(p).toBeDefined()); game.doAttack(getMovePosition(game.scene, 0, Moves.MAKE_IT_RAIN)); - - await game.phaseInterceptor.to(CommandPhase); game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); await game.phaseInterceptor.to(MoveEndPhase); @@ -62,16 +50,13 @@ describe("Moves - Make It Rain", () => { }, TIMEOUT); it("should apply effects even if the target faints", async () => { - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(1); // ensures the enemy will faint - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.enemyLevel(1); // ensures the enemy will faint + game.override.battleType("single"); await game.startBattle([Species.CHARIZARD]); const playerPokemon = game.scene.getPlayerPokemon(); - expect(playerPokemon).toBeDefined(); - const enemyPokemon = game.scene.getEnemyPokemon(); - expect(enemyPokemon).toBeDefined(); game.doAttack(getMovePosition(game.scene, 0, Moves.MAKE_IT_RAIN)); @@ -82,19 +67,14 @@ describe("Moves - Make It Rain", () => { }, TIMEOUT); it("should reduce Sp. Atk. once after KOing two enemies", async () => { - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(1); // ensures the enemy will faint + game.override.enemyLevel(1); // ensures the enemy will faint await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); const playerPokemon = game.scene.getPlayerField(); - playerPokemon.forEach(p => expect(p).toBeDefined()); - const enemyPokemon = game.scene.getEnemyField(); - enemyPokemon.forEach(p => expect(p).toBeDefined()); game.doAttack(getMovePosition(game.scene, 0, Moves.MAKE_IT_RAIN)); - - await game.phaseInterceptor.to(CommandPhase); game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); await game.phaseInterceptor.to(StatChangePhase); @@ -102,4 +82,23 @@ describe("Moves - Make It Rain", () => { enemyPokemon.forEach(p => expect(p.isFainted()).toBe(true)); expect(playerPokemon[0].summonData.battleStats[BattleStat.SPATK]).toBe(-1); }, TIMEOUT); + + it("should reduce Sp. Atk if it only hits the second target", async () => { + await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + + const playerPokemon = game.scene.getPlayerField(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.MAKE_IT_RAIN)); + game.doAttack(getMovePosition(game.scene, 1, Moves.SPLASH)); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + + // Make Make It Rain miss the first target + const moveEffectPhase = game.scene.getCurrentPhase() as MoveEffectPhase; + vi.spyOn(moveEffectPhase, "hitCheck").mockReturnValueOnce(false); + + await game.phaseInterceptor.to(MoveEndPhase); + + expect(playerPokemon[0].summonData.battleStats[BattleStat.SPATK]).toBe(-1); + }, TIMEOUT); }); diff --git a/src/test/moves/multi_target.test.ts b/src/test/moves/multi_target.test.ts index 7548e9529d1..a4ed936c5ee 100644 --- a/src/test/moves/multi_target.test.ts +++ b/src/test/moves/multi_target.test.ts @@ -1,13 +1,13 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Moves } from "#enums/moves"; import { getMoveTargets } from "#app/data/move.js"; import { Abilities } from "#app/enums/abilities.js"; import { Species } from "#app/enums/species.js"; -import { getMovePosition } from "../utils/gameManagerUtils"; import { TurnEndPhase } from "#app/phases.js"; +import GameManager from "#test/utils/gameManager"; +import { Moves } from "#enums/moves"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; const TIMEOUT = 20 * 1000; @@ -69,11 +69,10 @@ describe("Moves - Multi target", () => { async function checkTargetMultiplier(game: GameManager, attackMove: Moves, killAlly: boolean, killSecondEnemy: boolean, shouldMultiplied: boolean, oppAbility?: Abilities) { // play an attack and check target count - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(oppAbility ? oppAbility : Abilities.BALL_FETCH); + game.override.enemyAbility(oppAbility ? oppAbility : Abilities.BALL_FETCH); await game.startBattle(); const playerPokemonRepr = game.scene.getPlayerField(); - expect(playerPokemonRepr).not.toBeUndefined(); killAllyAndEnemy(game, killAlly, killSecondEnemy); @@ -164,14 +163,16 @@ function leaveOneEnemyPokemon(game: GameManager) { function beforeTrial(phaserGame: Phaser.Game, single: boolean = false) { const game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.EARTHQUAKE, Moves.HYPER_VOICE, Moves.SURF, Moves.SPLASH]); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(50); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(40); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.EEVEE); + game.override + .battleType("double") + .moveset([Moves.EARTHQUAKE, Moves.HYPER_VOICE, Moves.SURF, Moves.SPLASH]) + .ability(Abilities.BALL_FETCH) + .passiveAbility(Abilities.UNNERVE) + .enemyMoveset(SPLASH_ONLY) + .disableCrits() + .startingLevel(50) + .enemyLevel(40) + .enemySpecies(Species.EEVEE); return game; } diff --git a/src/test/moves/octolock.test.ts b/src/test/moves/octolock.test.ts index af96c2dc872..8988109f431 100644 --- a/src/test/moves/octolock.test.ts +++ b/src/test/moves/octolock.test.ts @@ -1,14 +1,14 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; +import { BattleStat } from "#app/data/battle-stat"; +import { TrappedTag } from "#app/data/battler-tags.js"; import { CommandPhase, MoveEndPhase, TurnInitPhase } from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; -import {BattleStat} from "#app/data/battle-stat"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { TrappedTag } from "#app/data/battler-tags.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Moves - Octolock", () => { describe("integration tests", () => { @@ -28,15 +28,15 @@ describe("Moves - Octolock", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.OCTOLOCK, Moves.SPLASH]); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); + game.override.startingLevel(2000); + game.override.moveset([Moves.OCTOLOCK, Moves.SPLASH]); + game.override.ability(Abilities.BALL_FETCH); }); it("Reduces DEf and SPDEF by 1 each turn", { timeout: 10000 }, async () => { diff --git a/src/test/moves/purify.test.ts b/src/test/moves/purify.test.ts index 282d33f85f9..4d108c43d4b 100644 --- a/src/test/moves/purify.test.ts +++ b/src/test/moves/purify.test.ts @@ -1,15 +1,12 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, test, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - MoveEndPhase, -} from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { Status, StatusEffect } from "#app/data/status-effect.js"; +import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon.js"; +import { MoveEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon.js"; -import { Status, StatusEffect } from "#app/data/status-effect.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -29,15 +26,15 @@ describe("Moves - Purify", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.PYUKUMUKU); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(10); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.PURIFY, Moves.SIZZLY_SLIDE]); + game.override.starterSpecies(Species.PYUKUMUKU); + game.override.startingLevel(10); + game.override.moveset([Moves.PURIFY, Moves.SIZZLY_SLIDE]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(10); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyLevel(10); + game.override.enemyMoveset([Moves.SPLASH, Moves.NONE, Moves.NONE, Moves.NONE]); }); test( diff --git a/src/test/moves/rage_powder.test.ts b/src/test/moves/rage_powder.test.ts index 3c315447b23..92cdcc9b4f7 100644 --- a/src/test/moves/rage_powder.test.ts +++ b/src/test/moves/rage_powder.test.ts @@ -1,17 +1,12 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, test, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase, - SelectTargetPhase, - TurnEndPhase, -} from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { BattlerIndex } from "#app/battle.js"; +import { CommandPhase, SelectTargetPhase, TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { BattlerIndex } from "#app/battle.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -31,19 +26,19 @@ describe("Moves - Rage Powder", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.AMOONGUSS); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK ]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("double"); + game.override.starterSpecies(Species.AMOONGUSS); + game.override.enemySpecies(Species.SNORLAX); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override.moveset([ Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK ]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); }); test( "move effect should be bypassed by Grass type", async () => { - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.RAGE_POWDER, Moves.RAGE_POWDER, Moves.RAGE_POWDER, Moves.RAGE_POWDER ]); + game.override.enemyMoveset([ Moves.RAGE_POWDER, Moves.RAGE_POWDER, Moves.RAGE_POWDER, Moves.RAGE_POWDER ]); await game.startBattle([ Species.AMOONGUSS, Species.VENUSAUR ]); @@ -76,8 +71,8 @@ describe("Moves - Rage Powder", () => { test( "move effect should be bypassed by Overcoat", async () => { - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.OVERCOAT); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.RAGE_POWDER, Moves.RAGE_POWDER, Moves.RAGE_POWDER, Moves.RAGE_POWDER ]); + game.override.ability(Abilities.OVERCOAT); + game.override.enemyMoveset([ Moves.RAGE_POWDER, Moves.RAGE_POWDER, Moves.RAGE_POWDER, Moves.RAGE_POWDER ]); // Test with two non-Grass type player Pokemon await game.startBattle([ Species.BLASTOISE, Species.CHARIZARD ]); diff --git a/src/test/moves/reflect.test.ts b/src/test/moves/reflect.test.ts index 9b57b3cdee3..821d9df437a 100644 --- a/src/test/moves/reflect.test.ts +++ b/src/test/moves/reflect.test.ts @@ -1,19 +1,16 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - TurnEndPhase, -} from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { ArenaTagSide } from "#app/data/arena-tag.js"; +import Move, { allMoves } from "#app/data/move.js"; +import { Abilities } from "#app/enums/abilities.js"; +import { ArenaTagType } from "#app/enums/arena-tag-type.js"; +import Pokemon from "#app/field/pokemon.js"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { NumberHolder } from "#app/utils.js"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { Abilities } from "#app/enums/abilities.js"; -import Pokemon from "#app/field/pokemon.js"; -import Move, { allMoves } from "#app/data/move.js"; -import { NumberHolder } from "#app/utils.js"; -import { ArenaTagSide } from "#app/data/arena-tag.js"; -import { ArenaTagType } from "#app/enums/arena-tag-type.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Reflect", () => { @@ -34,13 +31,13 @@ describe("Moves - Reflect", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.ABSORB, Moves.ROCK_SLIDE, Moves.TACKLE]); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.REFLECT, Moves.REFLECT, Moves.REFLECT, Moves.REFLECT]); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + game.override.battleType("single"); + game.override.ability(Abilities.NONE); + game.override.moveset([Moves.ABSORB, Moves.ROCK_SLIDE, Moves.TACKLE]); + game.override.enemyLevel(100); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset([Moves.REFLECT, Moves.REFLECT, Moves.REFLECT, Moves.REFLECT]); + game.override.disableCrits(); }); it("reduces damage of physical attacks by half in a single battle", async() => { @@ -56,7 +53,7 @@ describe("Moves - Reflect", () => { }); it("reduces damage of physical attacks by a third in a double battle", async() => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); + game.override.battleType("double"); const moveToUse = Moves.ROCK_SLIDE; await game.startBattle([Species.SHUCKLE, Species.SHUCKLE]); diff --git a/src/test/moves/rollout.test.ts b/src/test/moves/rollout.test.ts index 6d8828455e4..ad323c447f5 100644 --- a/src/test/moves/rollout.test.ts +++ b/src/test/moves/rollout.test.ts @@ -1,14 +1,13 @@ import { allMoves } from "#app/data/move.js"; -import Overrides from "#app/overrides"; import { CommandPhase } from "#app/phases"; -import GameManager from "#app/test/utils/gameManager"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { SPLASH_ONLY } from "../utils/testUtils"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Moves - Rollout", () => { let phaserGame: Phaser.Game; @@ -26,19 +25,19 @@ describe("Moves - Rollout", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.BIDOOF); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(SPLASH_ONLY); + game.override.disableCrits(); + game.override.battleType("single"); + game.override.starterSpecies(Species.RATTATA); + game.override.ability(Abilities.NONE); + game.override.enemySpecies(Species.BIDOOF); + game.override.enemyAbility(Abilities.NONE); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override.enemyMoveset(SPLASH_ONLY); }); it("should double it's dmg on sequential uses but reset after 5", async () => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.ROLLOUT]); + game.override.moveset([Moves.ROLLOUT]); vi.spyOn(allMoves[Moves.ROLLOUT], "accuracy", "get").mockReturnValue(100); //always hit const variance = 5; diff --git a/src/test/moves/roost.test.ts b/src/test/moves/roost.test.ts index 7f8495e1632..9ebd52e457d 100644 --- a/src/test/moves/roost.test.ts +++ b/src/test/moves/roost.test.ts @@ -1,13 +1,12 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, test, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#app/enums/species.js"; -import { Moves } from "#app/enums/moves.js"; -import { getMovePosition } from "../utils/gameManagerUtils"; -import { MoveEffectPhase, TurnEndPhase } from "#app/phases.js"; -import { BattlerTagType } from "#app/enums/battler-tag-type.js"; import { Abilities } from "#app/enums/abilities.js"; +import { BattlerTagType } from "#app/enums/battler-tag-type.js"; +import { Moves } from "#app/enums/moves.js"; +import { Species } from "#app/enums/species.js"; +import { MoveEffectPhase, TurnEndPhase } from "#app/phases.js"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; const TIMEOUT = 20 * 1000; @@ -27,13 +26,13 @@ describe("Moves - Roost", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.STARAPTOR); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.STOMPING_TANTRUM ]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.ROOST,Moves.ROOST,Moves.ROOST,Moves.ROOST]); + game.override.battleType("single"); + game.override.enemySpecies(Species.STARAPTOR); + game.override.enemyAbility(Abilities.INSOMNIA); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override.moveset([ Moves.STOMPING_TANTRUM ]); + game.override.enemyMoveset([Moves.ROOST,Moves.ROOST,Moves.ROOST,Moves.ROOST]); }); test( @@ -41,11 +40,7 @@ describe("Moves - Roost", () => { async () => { await game.startBattle([Species.MAGIKARP]); - const leadPokemon = game.scene.getPlayerPokemon(); - expect(leadPokemon).toBeDefined(); - const enemyPokemon = game.scene.getEnemyPokemon(); - expect(enemyPokemon).toBeDefined(); const enemyStartingHp = enemyPokemon.hp; diff --git a/src/test/moves/spikes.test.ts b/src/test/moves/spikes.test.ts index 44f365ea689..1f5bb757ee4 100644 --- a/src/test/moves/spikes.test.ts +++ b/src/test/moves/spikes.test.ts @@ -1,13 +1,10 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase -} from "#app/phases"; +import { CommandPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Spikes", () => { @@ -27,15 +24,15 @@ describe("Moves - Spikes", () => { beforeEach(() => { game = new GameManager(phaserGame); game.scene.battleStyle = 1; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "OPP_PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.HYDRATION); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(3); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH,Moves.SPLASH,Moves.SPLASH,Moves.SPLASH]); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPIKES,Moves.SPLASH, Moves.ROAR]); + game.override.battleType("single"); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.HYDRATION); + game.override.enemyPassiveAbility(Abilities.HYDRATION); + game.override.ability(Abilities.HYDRATION); + game.override.passiveAbility(Abilities.HYDRATION); + game.override.startingWave(3); + game.override.enemyMoveset([Moves.SPLASH,Moves.SPLASH,Moves.SPLASH,Moves.SPLASH]); + game.override.moveset([Moves.SPIKES,Moves.SPLASH, Moves.ROAR]); }); it("single - wild - stay on field - no damage", async() => { @@ -86,7 +83,7 @@ describe("Moves - Spikes", () => { }, 20000); it("trainer - wild - force switch opponent - should take damage", async() => { - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); + game.override.startingWave(5); // player set spikes on the field and do splash for 3 turns // opponent do splash for 4 turns // nobody should take damage @@ -104,9 +101,9 @@ describe("Moves - Spikes", () => { }, 20000); it("trainer - wild - force switch by himself opponent - should take damage", async() => { - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(5); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(5000); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(0); + game.override.startingWave(5); + game.override.startingLevel(5000); + game.override.enemySpecies(0); // turn 1: player set spikes, opponent do splash // turn 2: player do splash, opponent switch pokemon // opponent pokemon should trigger spikes and lose HP diff --git a/src/test/moves/spit_up.test.ts b/src/test/moves/spit_up.test.ts index f136d8f1e2b..298c96d6d66 100644 --- a/src/test/moves/spit_up.test.ts +++ b/src/test/moves/spit_up.test.ts @@ -1,16 +1,16 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import overrides from "#app/overrides"; -import { MovePhase, TurnInitPhase } from "#app/phases"; import { BattleStat } from "#app/data/battle-stat"; +import { StockpilingTag } from "#app/data/battler-tags.js"; +import { allMoves } from "#app/data/move.js"; +import { BattlerTagType } from "#app/enums/battler-tag-type.js"; +import { MoveResult, TurnMove } from "#app/field/pokemon.js"; +import { MovePhase, TurnInitPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { StockpilingTag } from "#app/data/battler-tags.js"; -import { MoveResult, TurnMove } from "#app/field/pokemon.js"; -import { BattlerTagType } from "#app/enums/battler-tag-type.js"; -import { allMoves } from "#app/data/move.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Moves - Spit Up", () => { let phaserGame: Phaser.Game; @@ -27,15 +27,15 @@ describe("Moves - Spit Up", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); - vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); - vi.spyOn(overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(2000); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.NONE); + game.override.enemyLevel(2000); - vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPIT_UP, Moves.SPIT_UP, Moves.SPIT_UP, Moves.SPIT_UP]); - vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); + game.override.moveset([Moves.SPIT_UP, Moves.SPIT_UP, Moves.SPIT_UP, Moves.SPIT_UP]); + game.override.ability(Abilities.NONE); }); describe("consumes all stockpile stacks to deal damage (scaling with stacks)", () => { diff --git a/src/test/moves/spotlight.test.ts b/src/test/moves/spotlight.test.ts index 88d276d3d61..0893ba975d7 100644 --- a/src/test/moves/spotlight.test.ts +++ b/src/test/moves/spotlight.test.ts @@ -1,17 +1,12 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, test, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase, - SelectTargetPhase, - TurnEndPhase, -} from "#app/phases"; -import {Stat} from "#app/data/pokemon-stat"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { BattlerIndex } from "#app/battle.js"; +import { Stat } from "#app/data/pokemon-stat"; +import { CommandPhase, SelectTargetPhase, TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { BattlerIndex } from "#app/battle.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; const TIMEOUT = 20 * 1000; @@ -31,13 +26,13 @@ describe("Moves - Spotlight", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.AMOONGUSS); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK ]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("double"); + game.override.starterSpecies(Species.AMOONGUSS); + game.override.enemySpecies(Species.SNORLAX); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override.moveset([ Moves.FOLLOW_ME, Moves.RAGE_POWDER, Moves.SPOTLIGHT, Moves.QUICK_ATTACK ]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); }); test( @@ -73,7 +68,7 @@ describe("Moves - Spotlight", () => { test( "move should cause other redirection moves to fail", async () => { - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME ]); + game.override.enemyMoveset([ Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME, Moves.FOLLOW_ME ]); await game.startBattle([ Species.AMOONGUSS, Species.CHARIZARD ]); diff --git a/src/test/moves/stockpile.test.ts b/src/test/moves/stockpile.test.ts index 1a23017c6b3..604b08745eb 100644 --- a/src/test/moves/stockpile.test.ts +++ b/src/test/moves/stockpile.test.ts @@ -1,15 +1,15 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import overrides from "#app/overrides"; -import { CommandPhase, TurnInitPhase } from "#app/phases"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; import { BattleStat } from "#app/data/battle-stat"; +import { StockpilingTag } from "#app/data/battler-tags.js"; +import { MoveResult, TurnMove } from "#app/field/pokemon.js"; +import { CommandPhase, TurnInitPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { StockpilingTag } from "#app/data/battler-tags.js"; -import { MoveResult, TurnMove } from "#app/field/pokemon.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Moves - Stockpile", () => { describe("integration tests", () => { @@ -27,15 +27,15 @@ describe("Moves - Stockpile", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); - vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.NONE); - vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.STOCKPILE, Moves.SPLASH]); - vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); + game.override.startingLevel(2000); + game.override.moveset([Moves.STOCKPILE, Moves.SPLASH]); + game.override.ability(Abilities.NONE); }); it("Gains a stockpile stack and increases DEF and SPDEF by 1 on each use, fails at max stacks (3)", { timeout: 10000 }, async () => { diff --git a/src/test/moves/swallow.test.ts b/src/test/moves/swallow.test.ts index 0dd4237c232..9a0a19dce2b 100644 --- a/src/test/moves/swallow.test.ts +++ b/src/test/moves/swallow.test.ts @@ -1,15 +1,15 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import overrides from "#app/overrides"; -import { MovePhase, TurnInitPhase } from "#app/phases"; import { BattleStat } from "#app/data/battle-stat"; +import { StockpilingTag } from "#app/data/battler-tags.js"; +import { BattlerTagType } from "#app/enums/battler-tag-type.js"; +import { MoveResult, TurnMove } from "#app/field/pokemon.js"; +import { MovePhase, TurnInitPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { StockpilingTag } from "#app/data/battler-tags.js"; -import { MoveResult, TurnMove } from "#app/field/pokemon.js"; -import { BattlerTagType } from "#app/enums/battler-tag-type.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Moves - Swallow", () => { let phaserGame: Phaser.Game; @@ -26,15 +26,15 @@ describe("Moves - Swallow", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); - vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); - vi.spyOn(overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(2000); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.enemyAbility(Abilities.NONE); + game.override.enemyLevel(2000); - vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SWALLOW, Moves.SWALLOW, Moves.SWALLOW, Moves.SWALLOW]); - vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE); + game.override.moveset([Moves.SWALLOW, Moves.SWALLOW, Moves.SWALLOW, Moves.SWALLOW]); + game.override.ability(Abilities.NONE); }); describe("consumes all stockpile stacks to heal (scaling with stacks)", () => { diff --git a/src/test/moves/tackle.test.ts b/src/test/moves/tackle.test.ts index f4b335d9576..512b23ae363 100644 --- a/src/test/moves/tackle.test.ts +++ b/src/test/moves/tackle.test.ts @@ -1,17 +1,13 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase, - EnemyCommandPhase, TurnEndPhase, -} from "#app/phases"; -import {Mode} from "#app/ui/ui"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; -import {Command} from "#app/ui/command-ui-handler"; -import {Stat} from "#app/data/pokemon-stat"; +import { Stat } from "#app/data/pokemon-stat"; +import { CommandPhase, EnemyCommandPhase, TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; +import { Mode } from "#app/ui/ui"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Tackle", () => { @@ -31,18 +27,18 @@ describe("Moves - Tackle", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.TACKLE; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(1); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(97); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.GROWTH,Moves.GROWTH,Moves.GROWTH,Moves.GROWTH]); - vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + game.override.battleType("single"); + game.override.enemySpecies(Species.MAGIKARP); + game.override.startingLevel(1); + game.override.startingWave(97); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.GROWTH,Moves.GROWTH,Moves.GROWTH,Moves.GROWTH]); + game.override.disableCrits(); }); it("TACKLE against ghost", async() => { const moveToUse = Moves.TACKLE; - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.GENGAR); + game.override.enemySpecies(Species.GENGAR); await game.startBattle([ Species.MIGHTYENA, ]); diff --git a/src/test/moves/tail_whip.test.ts b/src/test/moves/tail_whip.test.ts index 662746db4eb..7630b31f7de 100644 --- a/src/test/moves/tail_whip.test.ts +++ b/src/test/moves/tail_whip.test.ts @@ -1,19 +1,14 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - CommandPhase, - EnemyCommandPhase, - TurnInitPhase, -} from "#app/phases"; -import {Mode} from "#app/ui/ui"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; -import {Command} from "#app/ui/command-ui-handler"; -import {BattleStat} from "#app/data/battle-stat"; +import { BattleStat } from "#app/data/battle-stat"; +import { CommandPhase, EnemyCommandPhase, TurnInitPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Command } from "#app/ui/command-ui-handler"; +import { Mode } from "#app/ui/ui"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Tail whip", () => { @@ -33,13 +28,13 @@ describe("Moves - Tail whip", () => { beforeEach(() => { game = new GameManager(phaserGame); const moveToUse = Moves.TAIL_WHIP; - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RATTATA); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.INSOMNIA); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(2000); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([moveToUse]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); + game.override.battleType("single"); + game.override.enemySpecies(Species.RATTATA); + game.override.enemyAbility(Abilities.INSOMNIA); + game.override.ability(Abilities.INSOMNIA); + game.override.startingLevel(2000); + game.override.moveset([moveToUse]); + game.override.enemyMoveset([Moves.TACKLE,Moves.TACKLE,Moves.TACKLE,Moves.TACKLE]); }); it("TAIL_WHIP", async() => { diff --git a/src/test/moves/tailwind.test.ts b/src/test/moves/tailwind.test.ts index 535d0a1e525..d88de680d8a 100644 --- a/src/test/moves/tailwind.test.ts +++ b/src/test/moves/tailwind.test.ts @@ -1,16 +1,14 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { Species } from "#enums/species"; -import { - TurnEndPhase, -} from "#app/phases"; -import { Moves } from "#enums/moves"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; +import { ArenaTagSide } from "#app/data/arena-tag.js"; import { Stat } from "#app/data/pokemon-stat.js"; import { ArenaTagType } from "#app/enums/arena-tag-type.js"; -import { ArenaTagSide } from "#app/data/arena-tag.js"; +import { TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Abilities - Wind Rider", () => { let phaserGame: Phaser.Game; @@ -28,9 +26,9 @@ describe("Abilities - Wind Rider", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("double"); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); + game.override.battleType("double"); + game.override.moveset([Moves.TAILWIND, Moves.SPLASH, Moves.PETAL_BLIZZARD, Moves.SANDSTORM]); + game.override.enemyMoveset(SPLASH_ONLY); }); it("doubles the Speed stat of the Pokemons on its side", async () => { @@ -55,7 +53,7 @@ describe("Abilities - Wind Rider", () => { }); it("lasts for 4 turns", async () => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); await game.startBattle([Species.MAGIKARP]); @@ -78,7 +76,7 @@ describe("Abilities - Wind Rider", () => { }); it("does not affect the opposing side", async () => { - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); + game.override.battleType("single"); await game.startBattle([Species.MAGIKARP]); diff --git a/src/test/moves/thousand_arrows.test.ts b/src/test/moves/thousand_arrows.test.ts index 950e5228928..3b15610f896 100644 --- a/src/test/moves/thousand_arrows.test.ts +++ b/src/test/moves/thousand_arrows.test.ts @@ -1,16 +1,12 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; -import { - BerryPhase, - MoveEffectPhase -} from "#app/phases"; -import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { Abilities } from "#app/enums/abilities.js"; +import { BattlerTagType } from "#app/enums/battler-tag-type.js"; +import { BerryPhase, MoveEffectPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { BattlerTagType } from "#app/enums/battler-tag-type.js"; -import { Abilities } from "#app/enums/abilities.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; const TIMEOUT = 20 * 1000; @@ -30,12 +26,12 @@ describe("Moves - Thousand Arrows", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.TOGETIC); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.THOUSAND_ARROWS ]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH,Moves.SPLASH,Moves.SPLASH,Moves.SPLASH]); + game.override.battleType("single"); + game.override.enemySpecies(Species.TOGETIC); + game.override.startingLevel(100); + game.override.enemyLevel(100); + game.override.moveset([ Moves.THOUSAND_ARROWS ]); + game.override.enemyMoveset([Moves.SPLASH,Moves.SPLASH,Moves.SPLASH,Moves.SPLASH]); }); it( @@ -61,8 +57,8 @@ describe("Moves - Thousand Arrows", () => { it( "move should hit and ground targets with Levitate", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.LEVITATE); + game.override.enemySpecies(Species.SNORLAX); + game.override.enemyAbility(Abilities.LEVITATE); await game.startBattle([ Species.ILLUMISE ]); @@ -84,7 +80,7 @@ describe("Moves - Thousand Arrows", () => { it( "move should hit and ground targets under the effects of Magnet Rise", async () => { - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX); + game.override.enemySpecies(Species.SNORLAX); await game.startBattle([ Species.ILLUMISE ]); diff --git a/src/test/moves/tidy_up.test.ts b/src/test/moves/tidy_up.test.ts index 16312ce431a..83e1dda07cb 100644 --- a/src/test/moves/tidy_up.test.ts +++ b/src/test/moves/tidy_up.test.ts @@ -1,14 +1,14 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; -import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import Overrides from "#app/overrides"; +import { BattleStat } from "#app/data/battle-stat.js"; +import { ArenaTagType } from "#app/enums/arena-tag-type.js"; import { MoveEndPhase, TurnEndPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { getMovePosition } from "#app/test/utils/gameManagerUtils"; -import { ArenaTagType } from "#app/enums/arena-tag-type.js"; -import { BattleStat } from "#app/data/battle-stat.js"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "#test/utils/testUtils"; describe("Moves - Tidy Up", () => { @@ -27,19 +27,19 @@ describe("Moves - Tidy Up", () => { beforeEach(() => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]); - vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(Species.FEEBAS); - vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TIDY_UP]); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(50); + game.override.battleType("single"); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyAbility(Abilities.BALL_FETCH); + game.override.enemyMoveset(SPLASH_ONLY); + game.override.starterSpecies(Species.FEEBAS); + game.override.ability(Abilities.BALL_FETCH); + game.override.moveset([Moves.TIDY_UP]); + game.override.startingLevel(50); }); it("spikes are cleared", async() => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPIKES, Moves.TIDY_UP]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPIKES, Moves.SPIKES, Moves.SPIKES, Moves.SPIKES]); + game.override.moveset([Moves.SPIKES, Moves.TIDY_UP]); + game.override.enemyMoveset([Moves.SPIKES, Moves.SPIKES, Moves.SPIKES, Moves.SPIKES]); await game.startBattle(); game.doAttack(getMovePosition(game.scene, 0, Moves.SPIKES)); @@ -51,8 +51,8 @@ describe("Moves - Tidy Up", () => { }, 20000); it("stealth rocks are cleared", async() => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.STEALTH_ROCK, Moves.TIDY_UP]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.STEALTH_ROCK, Moves.STEALTH_ROCK, Moves.STEALTH_ROCK, Moves.STEALTH_ROCK]); + game.override.moveset([Moves.STEALTH_ROCK, Moves.TIDY_UP]); + game.override.enemyMoveset([Moves.STEALTH_ROCK, Moves.STEALTH_ROCK, Moves.STEALTH_ROCK, Moves.STEALTH_ROCK]); await game.startBattle(); game.doAttack(getMovePosition(game.scene, 0, Moves.STEALTH_ROCK)); @@ -64,8 +64,8 @@ describe("Moves - Tidy Up", () => { }, 20000); it("toxic spikes are cleared", async() => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TOXIC_SPIKES, Moves.TIDY_UP]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES]); + game.override.moveset([Moves.TOXIC_SPIKES, Moves.TIDY_UP]); + game.override.enemyMoveset([Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES, Moves.TOXIC_SPIKES]); await game.startBattle(); game.doAttack(getMovePosition(game.scene, 0, Moves.TOXIC_SPIKES)); @@ -77,8 +77,8 @@ describe("Moves - Tidy Up", () => { }, 20000); it("sticky webs are cleared", async() => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.STICKY_WEB, Moves.TIDY_UP]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.STICKY_WEB, Moves.STICKY_WEB, Moves.STICKY_WEB, Moves.STICKY_WEB]); + game.override.moveset([Moves.STICKY_WEB, Moves.TIDY_UP]); + game.override.enemyMoveset([Moves.STICKY_WEB, Moves.STICKY_WEB, Moves.STICKY_WEB, Moves.STICKY_WEB]); await game.startBattle(); @@ -91,8 +91,8 @@ describe("Moves - Tidy Up", () => { }, 20000); it.skip("substitutes are cleared", async() => { - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SUBSTITUTE, Moves.TIDY_UP]); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SUBSTITUTE, Moves.SUBSTITUTE, Moves.SUBSTITUTE, Moves.SUBSTITUTE]); + game.override.moveset([Moves.SUBSTITUTE, Moves.TIDY_UP]); + game.override.enemyMoveset([Moves.SUBSTITUTE, Moves.SUBSTITUTE, Moves.SUBSTITUTE, Moves.SUBSTITUTE]); await game.startBattle(); diff --git a/src/test/phases/phases.test.ts b/src/test/phases/phases.test.ts index 3d6da362004..c61eb1d41b8 100644 --- a/src/test/phases/phases.test.ts +++ b/src/test/phases/phases.test.ts @@ -1,9 +1,9 @@ import BattleScene from "#app/battle-scene.js"; import { LoginPhase, TitlePhase, UnavailablePhase } from "#app/phases.js"; import { Mode } from "#app/ui/ui.js"; -import {afterEach, beforeAll, beforeEach, describe, expect, it} from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; +import GameManager from "#test/utils/gameManager"; describe("Phases", () => { let phaserGame: Phaser.Game; diff --git a/src/test/settingMenu/helpers/inGameManip.ts b/src/test/settingMenu/helpers/inGameManip.ts index 1edab75fd27..e18a82ca571 100644 --- a/src/test/settingMenu/helpers/inGameManip.ts +++ b/src/test/settingMenu/helpers/inGameManip.ts @@ -1,9 +1,6 @@ -import { - getIconForLatestInput, - getSettingNameWithKeycode -} from "#app/configs/inputs/configHandler"; -import {expect} from "vitest"; -import {SettingKeyboard} from "#app/system/settings/settings-keyboard"; +import { getIconForLatestInput, getSettingNameWithKeycode } from "#app/configs/inputs/configHandler"; +import { expect } from "vitest"; +import { SettingKeyboard } from "#app/system/settings/settings-keyboard"; export class InGameManip { private config; diff --git a/src/test/settingMenu/helpers/menuManip.ts b/src/test/settingMenu/helpers/menuManip.ts index 7b4080c3d75..f33867476cf 100644 --- a/src/test/settingMenu/helpers/menuManip.ts +++ b/src/test/settingMenu/helpers/menuManip.ts @@ -1,14 +1,6 @@ -import {expect} from "vitest"; -import { - deleteBind, - getIconWithKeycode, - getIconWithSettingName, - getKeyWithKeycode, - getKeyWithSettingName, - assign, - getSettingNameWithKeycode, canIAssignThisKey, canIDeleteThisKey, canIOverrideThisSetting -} from "#app/configs/inputs/configHandler"; -import {SettingKeyboard} from "#app/system/settings/settings-keyboard"; +import { expect } from "vitest"; +import { deleteBind, getIconWithKeycode, getIconWithSettingName, getKeyWithKeycode, getKeyWithSettingName, assign, getSettingNameWithKeycode, canIAssignThisKey, canIDeleteThisKey, canIOverrideThisSetting } from "#app/configs/inputs/configHandler"; +import { SettingKeyboard } from "#app/system/settings/settings-keyboard"; export class MenuManip { private config; diff --git a/src/test/settingMenu/rebinding_setting.test.ts b/src/test/settingMenu/rebinding_setting.test.ts index 010ad427d6e..3bc17109c95 100644 --- a/src/test/settingMenu/rebinding_setting.test.ts +++ b/src/test/settingMenu/rebinding_setting.test.ts @@ -1,14 +1,11 @@ -import {beforeEach, describe, expect, it} from "vitest"; -import {deepCopy} from "#app/utils"; -import { - getKeyWithKeycode, - getKeyWithSettingName, -} from "#app/configs/inputs/configHandler"; -import {MenuManip} from "#app/test/settingMenu/helpers/menuManip"; -import {InGameManip} from "#app/test/settingMenu/helpers/inGameManip"; -import {InterfaceConfig} from "#app/inputs-controller"; +import { beforeEach, describe, expect, it } from "vitest"; +import { deepCopy } from "#app/utils"; +import { getKeyWithKeycode, getKeyWithSettingName } from "#app/configs/inputs/configHandler"; +import { MenuManip } from "#test/settingMenu/helpers/menuManip"; +import { InGameManip } from "#test/settingMenu/helpers/inGameManip"; +import { InterfaceConfig } from "#app/inputs-controller"; import cfg_keyboard_qwerty from "#app/configs/inputs/cfg_keyboard_qwerty"; -import {SettingKeyboard} from "#app/system/settings/settings-keyboard"; +import { SettingKeyboard } from "#app/system/settings/settings-keyboard"; import { Device } from "#enums/devices"; import { Button } from "#enums/buttons"; diff --git a/src/test/sprites/pokemonSprite.test.ts b/src/test/sprites/pokemonSprite.test.ts index 5c1db85fa6f..ce847751b6b 100644 --- a/src/test/sprites/pokemonSprite.test.ts +++ b/src/test/sprites/pokemonSprite.test.ts @@ -1,20 +1,21 @@ -import {beforeAll, describe, expect, it} from "vitest"; +import { beforeAll, describe, expect, it } from "vitest"; import _masterlist from "../../../public/images/pokemon/variant/_masterlist.json"; import fs from "fs"; import path from "path"; -import {getAppRootDir} from "#app/test/sprites/spritesUtils"; +import { getAppRootDir } from "#test/sprites/spritesUtils"; -const deepCopy = (data) => { +type PokemonVariantMasterlist = typeof _masterlist; + +const deepCopy = (data: any) => { return JSON.parse(JSON.stringify(data)); }; - describe("check if every variant's sprite are correctly set", () => { - let masterlist; - let expVariant; - let femaleVariant; - let backVariant; - let rootDir; + let masterlist: PokemonVariantMasterlist; + let expVariant: PokemonVariantMasterlist["exp"]; + let femaleVariant: PokemonVariantMasterlist["female"]; + let backVariant: PokemonVariantMasterlist["back"]; + let rootDir: string; beforeAll(() => { rootDir = `${getAppRootDir()}${path.sep}public${path.sep}images${path.sep}pokemon${path.sep}variant${path.sep}`; @@ -28,17 +29,17 @@ describe("check if every variant's sprite are correctly set", () => { }); it("data should not be undefined", () => { - expect(masterlist).not.toBeUndefined(); - expect(expVariant).not.toBeUndefined(); - expect(femaleVariant).not.toBeUndefined(); - expect(backVariant).not.toBeUndefined(); + expect(masterlist).toBeDefined(); + expect(expVariant).toBeDefined(); + expect(femaleVariant).toBeDefined(); + expect(backVariant).toBeDefined(); }); - function getMissingMasterlist(mlist, dirpath, excludes = []) { - const errors = []; + function getMissingMasterlist(mlist: any, dirpath: string, excludes: string[] = []): string[] { + const errors: string[] = []; const trimmedDirpath = `variant${path.sep}${dirpath.split(rootDir)[1]}`; if (fs.existsSync(dirpath)) { - const files = fs.readdirSync(dirpath); + const files = fs.readdirSync(dirpath).filter((filename) => !/^\..*/.test(filename)); for (const filename of files) { const filePath = `${dirpath}${filename}`; const trimmedFilePath = `${trimmedDirpath}${filename}`; @@ -101,12 +102,12 @@ describe("check if every variant's sprite are correctly set", () => { return errors; } - function getMissingFiles(keys, dirPath) { + function getMissingFiles(keys: Record, dirPath: string): string[] { const errors = []; for (const key of Object.keys(keys)) { const row = keys[key]; for (const [index, elm] of row.entries()) { - let url; + let url: string; if (elm === 0) { continue; } else if (elm === 1) { diff --git a/src/test/ui/starter-select.test.ts b/src/test/ui/starter-select.test.ts index 95a4605fd68..eae5b3fe3a5 100644 --- a/src/test/ui/starter-select.test.ts +++ b/src/test/ui/starter-select.test.ts @@ -1,20 +1,16 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it} from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import { - EncounterPhase, - SelectStarterPhase, - TitlePhase, -} from "#app/phases"; -import {Mode} from "#app/ui/ui"; -import {GameModes} from "#app/game-mode"; +import GameManager from "#test/utils/gameManager"; +import { EncounterPhase, SelectStarterPhase, TitlePhase } from "#app/phases"; +import { Mode } from "#app/ui/ui"; +import { GameModes } from "#app/game-mode"; import StarterSelectUiHandler from "#app/ui/starter-select-ui-handler"; import OptionSelectUiHandler from "#app/ui/settings/option-select-ui-handler"; import SaveSlotSelectUiHandler from "#app/ui/save-slot-select-ui-handler"; -import {OptionSelectItem} from "#app/ui/abstact-option-select-ui-handler"; -import {Gender} from "#app/data/gender"; -import {allSpecies} from "#app/data/pokemon-species"; -import {Nature} from "#app/data/nature"; +import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"; +import { Gender } from "#app/data/gender"; +import { allSpecies } from "#app/data/pokemon-species"; +import { Nature} from "#app/data/nature"; import { Button } from "#enums/buttons"; import { Abilities } from "#enums/abilities"; import { Species } from "#enums/species"; diff --git a/src/test/ui/transfer-item.test.ts b/src/test/ui/transfer-item.test.ts index c20fa51aff9..bbb9a823ad9 100644 --- a/src/test/ui/transfer-item.test.ts +++ b/src/test/ui/transfer-item.test.ts @@ -1,20 +1,16 @@ import { BerryType } from "#app/enums/berry-type"; +import { Button } from "#app/enums/buttons"; import { Moves } from "#app/enums/moves"; import { Species } from "#app/enums/species"; -import { Button } from "#app/enums/buttons"; -import Overrides from "#app/overrides"; -import { - BattleEndPhase, - SelectModifierPhase -} from "#app/phases"; -import GameManager from "#app/test/utils/gameManager"; +import { BattleEndPhase, SelectModifierPhase } from "#app/phases"; +import GameManager from "#test/utils/gameManager"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; import PartyUiHandler, { PartyUiMode } from "#app/ui/party-ui-handler"; import { Mode } from "#app/ui/ui"; import Phaser from "phaser"; import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { getMovePosition } from "../utils/gameManagerUtils"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { getMovePosition } from "#test/utils/gameManagerUtils"; describe("UI - Transfer Items", () => { @@ -33,17 +29,17 @@ describe("UI - Transfer Items", () => { beforeEach(async () => { game = new GameManager(phaserGame); - vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single"); - vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); - vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(1); - vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([ + game.override.battleType("single"); + game.override.startingLevel(100); + game.override.startingWave(1); + game.override.startingHeldItems([ { name: "BERRY", count: 1, type: BerryType.SITRUS }, { name: "BERRY", count: 2, type: BerryType.APICOT }, { name: "BERRY", count: 2, type: BerryType.LUM }, ]); - vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DRAGON_CLAW]); - vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP); - vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]); + game.override.moveset([Moves.DRAGON_CLAW]); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyMoveset([Moves.SPLASH]); await game.startBattle([Species.RAYQUAZA, Species.RAYQUAZA, Species.RAYQUAZA]); diff --git a/src/test/utils/TextInterceptor.ts b/src/test/utils/TextInterceptor.ts index 34b55aa30ac..a49f41f6be0 100644 --- a/src/test/utils/TextInterceptor.ts +++ b/src/test/utils/TextInterceptor.ts @@ -11,6 +11,11 @@ export default class TextInterceptor { this.logs.push(text); } + showDialogue(text: string, name: string, delay?: integer, callback?: Function, callbackDelay?: integer, promptDelay?: integer): void { + console.log(name, text); + this.logs.push(name, text); + } + getLatestMessage(): string { return this.logs.pop(); } diff --git a/src/test/utils/gameManager.ts b/src/test/utils/gameManager.ts index ac18daaaada..ac7f7aea4d2 100644 --- a/src/test/utils/gameManager.ts +++ b/src/test/utils/gameManager.ts @@ -1,31 +1,21 @@ -import GameWrapper from "#app/test/utils/gameWrapper"; -import {Mode} from "#app/ui/ui"; -import {generateStarter, waitUntil} from "#app/test/utils/gameManagerUtils"; -import { - CommandPhase, - EncounterPhase, - FaintPhase, - LoginPhase, - NewBattlePhase, - SelectStarterPhase, - SelectTargetPhase, - TitlePhase, TurnEndPhase, TurnInitPhase, - TurnStartPhase, -} from "#app/phases"; +import GameWrapper from "#test/utils/gameWrapper"; +import { Mode } from "#app/ui/ui"; +import { generateStarter, waitUntil } from "#test/utils/gameManagerUtils"; +import { CommandPhase, EncounterPhase, FaintPhase, LoginPhase, NewBattlePhase, SelectStarterPhase, SelectTargetPhase, TitlePhase, TurnEndPhase, TurnInitPhase, TurnStartPhase } from "#app/phases"; import BattleScene from "#app/battle-scene.js"; -import PhaseInterceptor from "#app/test/utils/phaseInterceptor"; -import TextInterceptor from "#app/test/utils/TextInterceptor"; -import {GameModes, getGameMode} from "#app/game-mode"; +import PhaseInterceptor from "#test/utils/phaseInterceptor"; +import TextInterceptor from "#test/utils/TextInterceptor"; +import { GameModes, getGameMode } from "#app/game-mode"; import fs from "fs"; -import {AES, enc} from "crypto-js"; -import {updateUserInfo} from "#app/account"; -import InputsHandler from "#app/test/utils/inputsHandler"; -import ErrorInterceptor from "#app/test/utils/errorInterceptor"; -import {EnemyPokemon, PlayerPokemon} from "#app/field/pokemon"; -import {MockClock} from "#app/test/utils/mocks/mockClock"; -import {Command} from "#app/ui/command-ui-handler"; +import { AES, enc } from "crypto-js"; +import { updateUserInfo } from "#app/account"; +import InputsHandler from "#test/utils/inputsHandler"; +import ErrorInterceptor from "#test/utils/errorInterceptor"; +import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon"; +import { MockClock } from "#test/utils/mocks/mockClock"; +import { Command } from "#app/ui/command-ui-handler"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; -import PartyUiHandler, {PartyUiMode} from "#app/ui/party-ui-handler"; +import PartyUiHandler, { PartyUiMode } from "#app/ui/party-ui-handler"; import Trainer from "#app/field/trainer"; import { ExpNotification } from "#enums/exp-notification"; import { GameDataType } from "#enums/game-data-type"; @@ -34,6 +24,10 @@ import { Species } from "#enums/species"; import { Button } from "#enums/buttons"; import { BattlerIndex } from "#app/battle.js"; import TargetSelectUiHandler from "#app/ui/target-select-ui-handler.js"; +import { OverridesHelper } from "./overridesHelper"; +import { ModifierTypeOption, modifierTypes } from "#app/modifier/modifier-type.js"; +import overrides from "#app/overrides.js"; +import { removeEnemyHeldItems } from "./testUtils"; /** * Class to manage the game state and transitions between phases. @@ -44,6 +38,7 @@ export default class GameManager { public phaseInterceptor: PhaseInterceptor; public textInterceptor: TextInterceptor; public inputsHandler: InputsHandler; + public readonly override: OverridesHelper; /** * Creates an instance of GameManager. @@ -59,6 +54,7 @@ export default class GameManager { this.phaseInterceptor = new PhaseInterceptor(this.scene); this.textInterceptor = new TextInterceptor(this.scene); this.gameWrapper.setScene(this.scene); + this.override = new OverridesHelper(this); } /** @@ -136,6 +132,9 @@ export default class GameManager { }); await this.phaseInterceptor.run(EncounterPhase); + if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0) { + removeEnemyHeldItems(this.scene); + } } /** @@ -325,4 +324,15 @@ export default class GameManager { (this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.POKEMON, pokemonIndex, false); }); } + + /** + * Revive pokemon, currently player's only. + * @param pokemonIndex the index of the pokemon in your party to revive + */ + doRevivePokemon(pokemonIndex: number) { + const party = this.scene.getParty(); + const candidate = new ModifierTypeOption(modifierTypes.MAX_REVIVE(), 0); + const modifier = candidate.type.newModifier(party[pokemonIndex]); + this.scene.addModifier(modifier, false); + } } diff --git a/src/test/utils/gameManagerUtils.ts b/src/test/utils/gameManagerUtils.ts index d83805e59e8..74a73bb7875 100644 --- a/src/test/utils/gameManagerUtils.ts +++ b/src/test/utils/gameManagerUtils.ts @@ -1,14 +1,14 @@ -// Function to convert Blob to string -import {getDailyRunStarters} from "#app/data/daily-run"; -import {Gender} from "#app/data/gender"; -import {Species} from "#enums/species"; -import {Starter} from "#app/ui/starter-select-ui-handler"; -import {GameModes, getGameMode} from "#app/game-mode"; -import {getPokemonSpecies, getPokemonSpeciesForm} from "#app/data/pokemon-species"; -import {PlayerPokemon} from "#app/field/pokemon"; +import { getDailyRunStarters } from "#app/data/daily-run"; +import { Gender } from "#app/data/gender"; +import { Species } from "#enums/species"; +import { Starter } from "#app/ui/starter-select-ui-handler"; +import { GameModes, getGameMode } from "#app/game-mode"; +import { getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species"; +import { PlayerPokemon } from "#app/field/pokemon"; import { Moves } from "#app/enums/moves"; import BattleScene from "#app/battle-scene"; +/** Function to convert Blob to string */ export function blobToString(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); diff --git a/src/test/utils/gameWrapper.ts b/src/test/utils/gameWrapper.ts index b1b00c8e15d..7edb69aef8a 100644 --- a/src/test/utils/gameWrapper.ts +++ b/src/test/utils/gameWrapper.ts @@ -8,23 +8,24 @@ import KeyboardPlugin = Phaser.Input.Keyboard.KeyboardPlugin; import GamepadPlugin = Phaser.Input.Gamepad.GamepadPlugin; import EventEmitter = Phaser.Events.EventEmitter; import UpdateList = Phaser.GameObjects.UpdateList; -import MockGraphics from "#app/test/utils/mocks/mocksContainer/mockGraphics"; -import MockTextureManager from "#app/test/utils/mocks/mockTextureManager"; +import MockGraphics from "#test/utils/mocks/mocksContainer/mockGraphics"; +import MockTextureManager from "#test/utils/mocks/mockTextureManager"; import Phaser from "phaser"; -import {blobToString} from "#app/test/utils/gameManagerUtils"; -import {vi} from "vitest"; -import mockLocalStorage from "#app/test/utils/mocks/mockLocalStorage"; -import mockConsoleLog from "#app/test/utils/mocks/mockConsoleLog"; -import MockLoader from "#app/test/utils/mocks/mockLoader"; -import {MockFetch} from "#app/test/utils/mocks/mockFetch"; +import { blobToString } from "#test/utils/gameManagerUtils"; +import { vi } from "vitest"; +import mockLocalStorage from "#test/utils/mocks/mockLocalStorage"; +import mockConsoleLog from "#test/utils/mocks/mockConsoleLog"; +import MockLoader from "#test/utils/mocks/mockLoader"; +import { MockFetch } from "#test/utils/mocks/mockFetch"; import * as Utils from "#app/utils"; import InputText from "phaser3-rex-plugins/plugins/inputtext"; -import {MockClock} from "#app/test/utils/mocks/mockClock"; +import { MockClock } from "#test/utils/mocks/mockClock"; import BattleScene from "#app/battle-scene.js"; -import {MoveAnim} from "#app/data/battle-anims"; +import { MoveAnim } from "#app/data/battle-anims"; import Pokemon from "#app/field/pokemon"; import * as battleScene from "#app/battle-scene"; -import MockImage from "#app/test/utils/mocks/mocksContainer/mockImage.js"; +import MockImage from "#test/utils/mocks/mocksContainer/mockImage.js"; +import { MockGameObjectCreator } from "./mocks/mockGameObjectCreator"; Object.defineProperty(window, "localStorage", { value: mockLocalStorage(), @@ -40,7 +41,7 @@ Phaser.GameObjects.Image = MockImage; window.URL.createObjectURL = (blob: Blob) => { blobToString(blob).then((data: string) => { localStorage.setItem("toExport", data); - }) + }); return null; }; navigator.getGamepads = vi.fn().mockReturnValue([]); @@ -100,7 +101,7 @@ export default class GameWrapper { injectMandatory() { this.game.config = { seed: ["test"], - } + }; this.scene.game = this.game; this.game.renderer = { maxTextures: -1, @@ -138,7 +139,7 @@ export default class GameWrapper { setPostPipeline: () => null, removePostPipeline: () => null, }, - } + }; this.scene.tweens = { add: (data) => { @@ -223,13 +224,9 @@ export default class GameWrapper { return resolve(response); }); }; - this.scene.make = { - graphics: (config) => new MockGraphics(mockTextureManager, config), - rexTransitionImagePack: () => ({ - transit: () => null, - }), - }; + this.scene.make = new MockGameObjectCreator(mockTextureManager); this.scene.time = new MockClock(this.scene); + this.scene.remove = vi.fn(); } } @@ -257,4 +254,4 @@ function createFetchBadResponse(data) { json: () => Promise.resolve(data), text: () => Promise.resolve(JSON.stringify(data)), }; -} \ No newline at end of file +} diff --git a/src/test/utils/inputsHandler.ts b/src/test/utils/inputsHandler.ts index 043dcffbdb9..e41667dc873 100644 --- a/src/test/utils/inputsHandler.ts +++ b/src/test/utils/inputsHandler.ts @@ -1,8 +1,8 @@ import BattleScene from "#app/battle-scene"; import Phaser from "phaser"; -import {InputsController} from "#app/inputs-controller"; +import { InputsController } from "#app/inputs-controller"; import pad_xbox360 from "#app/configs/inputs/pad_xbox360"; -import {holdOn} from "#app/test/utils/gameManagerUtils"; +import { holdOn } from "#test/utils/gameManagerUtils"; import TouchControl from "#app/touch-controls"; import { JSDOM } from "jsdom"; import fs from "fs"; diff --git a/src/test/utils/misc.test.ts b/src/test/utils/misc.test.ts index da67fb48192..c1947dbe8a2 100644 --- a/src/test/utils/misc.test.ts +++ b/src/test/utils/misc.test.ts @@ -1,8 +1,8 @@ -import {afterEach, beforeAll, beforeEach, describe, expect, it, vi} from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import Phaser from "phaser"; -import GameManager from "#app/test/utils/gameManager"; -import {apiFetch} from "#app/utils"; -import {waitUntil} from "#app/test/utils/gameManagerUtils"; +import GameManager from "#test/utils/gameManager"; +import { apiFetch } from "#app/utils"; +import { waitUntil } from "#test/utils/gameManagerUtils"; describe("Test misc", () => { let phaserGame: Phaser.Game; @@ -59,7 +59,7 @@ describe("Test misc", () => { it("test apifetch mock sync", async () => { const data = await game.scene.cachedFetch("./battle-anims/splishy-splash.json"); - expect(data).not.toBeUndefined(); + expect(data).toBeDefined(); }); it("testing wait phase queue", async () => { diff --git a/src/test/utils/mocks/mockGameObjectCreator.ts b/src/test/utils/mocks/mockGameObjectCreator.ts new file mode 100644 index 00000000000..19406a46923 --- /dev/null +++ b/src/test/utils/mocks/mockGameObjectCreator.ts @@ -0,0 +1,23 @@ +import { vi } from "vitest"; +import MockGraphics from "./mocksContainer/mockGraphics"; +import MockTextureManager from "./mockTextureManager"; + +export class MockGameObjectCreator { + private readonly textureManager: MockTextureManager; + + constructor(textureManager: MockTextureManager) { + console.log("Mocking Phaser.GameObjects.GameObjectCreator;"); + this.textureManager = textureManager; + } + + graphics(config: any) { + return new MockGraphics(this.textureManager, config); + } + + rexTransitionImagePack() { + return { + transit: vi.fn(), + once: vi.fn(), + }; + } +} diff --git a/src/test/utils/mocks/mockTextureManager.ts b/src/test/utils/mocks/mockTextureManager.ts index e207f96b722..36a09efcf5a 100644 --- a/src/test/utils/mocks/mockTextureManager.ts +++ b/src/test/utils/mocks/mockTextureManager.ts @@ -1,10 +1,10 @@ -import MockContainer from "#app/test/utils/mocks/mocksContainer/mockContainer"; -import MockSprite from "#app/test/utils/mocks/mocksContainer/mockSprite"; -import MockRectangle from "#app/test/utils/mocks/mocksContainer/mockRectangle"; -import MockNineslice from "#app/test/utils/mocks/mocksContainer/mockNineslice"; -import MockImage from "#app/test/utils/mocks/mocksContainer/mockImage"; -import MockText from "#app/test/utils/mocks/mocksContainer/mockText"; -import MockPolygon from "#app/test/utils/mocks/mocksContainer/mockPolygon"; +import MockContainer from "#test/utils/mocks/mocksContainer/mockContainer"; +import MockSprite from "#test/utils/mocks/mocksContainer/mockSprite"; +import MockRectangle from "#test/utils/mocks/mocksContainer/mockRectangle"; +import MockNineslice from "#test/utils/mocks/mocksContainer/mockNineslice"; +import MockImage from "#test/utils/mocks/mocksContainer/mockImage"; +import MockText from "#test/utils/mocks/mocksContainer/mockText"; +import MockPolygon from "#test/utils/mocks/mocksContainer/mockPolygon"; export default class MockTextureManager { diff --git a/src/test/utils/mocks/mocksContainer/mockContainer.ts b/src/test/utils/mocks/mocksContainer/mockContainer.ts index 2e2b9567796..b74c46b4e86 100644 --- a/src/test/utils/mocks/mocksContainer/mockContainer.ts +++ b/src/test/utils/mocks/mocksContainer/mockContainer.ts @@ -1,4 +1,4 @@ -import MockTextureManager from "#app/test/utils/mocks/mockTextureManager"; +import MockTextureManager from "#test/utils/mocks/mockTextureManager"; export default class MockContainer { protected x; diff --git a/src/test/utils/mocks/mocksContainer/mockImage.ts b/src/test/utils/mocks/mocksContainer/mockImage.ts index 601dfd22811..be183a0dd89 100644 --- a/src/test/utils/mocks/mocksContainer/mockImage.ts +++ b/src/test/utils/mocks/mocksContainer/mockImage.ts @@ -1,4 +1,4 @@ -import MockContainer from "#app/test/utils/mocks/mocksContainer/mockContainer"; +import MockContainer from "#test/utils/mocks/mocksContainer/mockContainer"; export default class MockImage extends MockContainer { diff --git a/src/test/utils/mocks/mocksContainer/mockNineslice.ts b/src/test/utils/mocks/mocksContainer/mockNineslice.ts index 3edbbb18c31..a8e10036a72 100644 --- a/src/test/utils/mocks/mocksContainer/mockNineslice.ts +++ b/src/test/utils/mocks/mocksContainer/mockNineslice.ts @@ -1,4 +1,4 @@ -import MockContainer from "#app/test/utils/mocks/mocksContainer/mockContainer"; +import MockContainer from "#test/utils/mocks/mocksContainer/mockContainer"; export default class MockNineslice extends MockContainer { diff --git a/src/test/utils/mocks/mocksContainer/mockPolygon.ts b/src/test/utils/mocks/mocksContainer/mockPolygon.ts index cf448883ce0..12b60904a96 100644 --- a/src/test/utils/mocks/mocksContainer/mockPolygon.ts +++ b/src/test/utils/mocks/mocksContainer/mockPolygon.ts @@ -1,4 +1,4 @@ -import MockContainer from "#app/test/utils/mocks/mocksContainer/mockContainer"; +import MockContainer from "#test/utils/mocks/mocksContainer/mockContainer"; export default class MockPolygon extends MockContainer { diff --git a/src/test/utils/mocks/mocksContainer/mockSprite.ts b/src/test/utils/mocks/mocksContainer/mockSprite.ts index 3a5de09b258..fb7f84741e8 100644 --- a/src/test/utils/mocks/mocksContainer/mockSprite.ts +++ b/src/test/utils/mocks/mocksContainer/mockSprite.ts @@ -31,6 +31,7 @@ export default class MockSprite { }; this.anims = { pause: () => null, + stop: () => null, }; } diff --git a/src/test/utils/overridesHelper.ts b/src/test/utils/overridesHelper.ts new file mode 100644 index 00000000000..e51928cc784 --- /dev/null +++ b/src/test/utils/overridesHelper.ts @@ -0,0 +1,282 @@ +import { StatusEffect } from "#app/data/status-effect.js"; +import { Weather, WeatherType } from "#app/data/weather"; +import { Abilities } from "#app/enums/abilities.js"; +import { Biome } from "#app/enums/biome"; +import { Moves } from "#app/enums/moves.js"; +import { Species } from "#app/enums/species.js"; +import * as GameMode from "#app/game-mode"; +import { GameModes, getGameMode } from "#app/game-mode"; +import { ModifierOverride } from "#app/modifier/modifier-type.js"; +import Overrides from "#app/overrides"; +import GameManager from "#test/utils/gameManager"; +import { vi } from "vitest"; + +/** + * Helper to handle overrides in tests + */ +export class OverridesHelper { + private readonly game: GameManager; + + constructor(game: GameManager) { + this.game = game; + } + + /** + * Override the starting biome + * @warning Any event listeners that are attached to [NewArenaEvent](events\battle-scene.ts) may need to be handled down the line + * @param biome the biome to set + */ + startingBiome(biome: Biome): this { + this.game.scene.newArena(biome); + this.log(`Starting biome set to ${Biome[biome]} (=${biome})!`); + return this; + } + + /** + * Override the starting wave (index) + * @param wave the wave (index) to set. Classic: `1`-`200` + * @returns this + */ + startingWave(wave: number): this { + vi.spyOn(Overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(wave); + this.log(`Starting wave set to ${wave}!`); + return this; + } + + /** + * Override the player (pokemon) starting level + * @param level the (pokemon) level to set + * @returns this + */ + startingLevel(level: Species | number): this { + vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(level); + this.log(`Player Pokemon starting level set to ${level}!`); + return this; + } + + /** + * Override the player (pokemon) starting held items + * @param items the items to hold + * @returns this + */ + startingHeldItems(items: ModifierOverride[]) { + vi.spyOn(Overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue(items); + this.log("Player Pokemon starting held items set to:", items); + return this; + } + + /** + * Override the player (pokemon) {@linkcode Species | species} + * @param species the (pokemon) {@linkcode Species | species} to set + * @returns this + */ + starterSpecies(species: Species | number): this { + vi.spyOn(Overrides, "STARTER_SPECIES_OVERRIDE", "get").mockReturnValue(species); + this.log(`Player Pokemon species set to ${Species[species]} (=${species})!`); + return this; + } + + /** + * Override the player (pokemons) forms + * @param forms the (pokemon) forms to set + * @returns this + */ + starterForms(forms: Partial>): this { + vi.spyOn(Overrides, "STARTER_FORM_OVERRIDES", "get").mockReturnValue(forms); + const formsStr = Object.entries(forms) + .map(([speciesId, formIndex]) => `${Species[speciesId]}=${formIndex}`) + .join(", "); + this.log(`Player Pokemon form set to: ${formsStr}!`); + return this; + } + + /** + * Override the player (pokemon) {@linkcode Abilities | ability} + * @param ability the (pokemon) {@linkcode Abilities | ability} to set + * @returns this + */ + ability(ability: Abilities): this { + vi.spyOn(Overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(ability); + this.log(`Player Pokemon ability set to ${Abilities[ability]} (=${ability})!`); + return this; + } + + /** + * Override the player (pokemon) **passive** {@linkcode Abilities | ability} + * @param passiveAbility the (pokemon) **passive** {@linkcode Abilities | ability} to set + * @returns this + */ + passiveAbility(passiveAbility: Abilities): this { + vi.spyOn(Overrides, "PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(passiveAbility); + this.log(`Player Pokemon PASSIVE ability set to ${Abilities[passiveAbility]} (=${passiveAbility})!`); + return this; + } + + /** + * Override the player (pokemon) {@linkcode Moves | moves}set + * @param moveset the {@linkcode Moves | moves}set to set + * @returns this + */ + moveset(moveset: Moves[]): this { + vi.spyOn(Overrides, "MOVESET_OVERRIDE", "get").mockReturnValue(moveset); + const movesetStr = moveset.map((moveId) => Moves[moveId]).join(", "); + this.log(`Player Pokemon moveset set to ${movesetStr} (=[${moveset.join(", ")}])!`); + return this; + } + + /** + * Override the player (pokemon) {@linkcode StatusEffect | status-effect} + * @param statusEffect the {@linkcode StatusEffect | status-effect} to set + * @returns + */ + statusEffect(statusEffect: StatusEffect): this { + vi.spyOn(Overrides, "STATUS_OVERRIDE", "get").mockReturnValue(statusEffect); + this.log(`Player Pokemon status-effect set to ${StatusEffect[statusEffect]} (=${statusEffect})!`); + return this; + } + + /** + * Override each wave to not have standard trainer battles + * @returns this + */ + disableTrainerWaves(): this { + const realFn = getGameMode; + vi.spyOn(GameMode, "getGameMode").mockImplementation((gameMode: GameModes) => { + const mode = realFn(gameMode); + mode.hasTrainers = false; + return mode; + }); + this.log("Standard trainer waves are disabled!"); + return this; + } + + /** + * Override each wave to not have critical hits + * @returns this + */ + disableCrits() { + vi.spyOn(Overrides, "NEVER_CRIT_OVERRIDE", "get").mockReturnValue(true); + this.log("Critical hits are disabled!"); + return this; + } + + /** + * Override the {@linkcode WeatherType | weather (type)} + * @param type {@linkcode WeatherType | weather type} to set + * @returns this + */ + weather(type: WeatherType): this { + vi.spyOn(Overrides, "WEATHER_OVERRIDE", "get").mockReturnValue(type); + this.log(`Weather set to ${Weather[type]} (=${type})!`); + return this; + } + + /** + * Override the seed + * @param seed the seed to set + * @returns this + */ + seed(seed: string): this { + vi.spyOn(this.game.scene, "resetSeed").mockImplementation(() => { + this.game.scene.waveSeed = seed; + Phaser.Math.RND.sow([seed]); + this.game.scene.rngCounter = 0; + }); + this.game.scene.resetSeed(); + this.log(`Seed set to "${seed}"!`); + return this; + } + + /** + * Override the battle type (single or double) + * @param battleType battle type to set + * @returns this + */ + battleType(battleType: "single" | "double"): this { + vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue(battleType); + this.log(`Battle type set to ${battleType} only!`); + return this; + } + + /** + * Override the enemy (pokemon) {@linkcode Species | species} + * @param species the (pokemon) {@linkcode Species | species} to set + * @returns this + */ + enemySpecies(species: Species | number): this { + vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(species); + this.log(`Enemy Pokemon species set to ${Species[species]} (=${species})!`); + return this; + } + + /** + * Override the enemy (pokemon) {@linkcode Abilities | ability} + * @param ability the (pokemon) {@linkcode Abilities | ability} to set + * @returns this + */ + enemyAbility(ability: Abilities): this { + vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(ability); + this.log(`Enemy Pokemon ability set to ${Abilities[ability]} (=${ability})!`); + return this; + } + + /** + * Override the enemy (pokemon) **passive** {@linkcode Abilities | ability} + * @param passiveAbility the (pokemon) **passive** {@linkcode Abilities | ability} to set + * @returns this + */ + enemyPassiveAbility(passiveAbility: Abilities): this { + vi.spyOn(Overrides, "OPP_PASSIVE_ABILITY_OVERRIDE", "get").mockReturnValue(passiveAbility); + this.log(`Enemy Pokemon PASSIVE ability set to ${Abilities[passiveAbility]} (=${passiveAbility})!`); + return this; + } + + /** + * Override the enemy (pokemon) {@linkcode Moves | moves}set + * @param moveset the {@linkcode Moves | moves}set to set + * @returns this + */ + enemyMoveset(moveset: Moves[]): this { + vi.spyOn(Overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue(moveset); + const movesetStr = moveset.map((moveId) => Moves[moveId]).join(", "); + this.log(`Enemy Pokemon moveset set to ${movesetStr} (=[${moveset.join(", ")}])!`); + return this; + } + + /** + * Override the enemy (pokemon) level + * @param level the level to set + * @returns this + */ + enemyLevel(level: number): this { + vi.spyOn(Overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(level); + this.log(`Enemy Pokemon level set to ${level}!`); + return this; + } + + /** + * Override the enemy (pokemon) {@linkcode StatusEffect | status-effect} + * @param statusEffect the {@linkcode StatusEffect | status-effect} to set + * @returns + */ + enemyStatusEffect(statusEffect: StatusEffect): this { + vi.spyOn(Overrides, "OPP_STATUS_OVERRIDE", "get").mockReturnValue(statusEffect); + this.log(`Enemy Pokemon status-effect set to ${StatusEffect[statusEffect]} (=${statusEffect})!`); + return this; + } + + /** + * Override the enemy (pokemon) held items + * @param items the items to hold + * @returns this + */ + enemyHeldItems(items: ModifierOverride[]) { + vi.spyOn(Overrides, "OPP_HELD_ITEMS_OVERRIDE", "get").mockReturnValue(items); + this.log("Enemy Pokemon held items set to:", items); + return this; + } + + private log(...params: any[]) { + console.log("Overrides:", ...params); + } +} diff --git a/src/test/utils/phaseInterceptor.ts b/src/test/utils/phaseInterceptor.ts index e8cec7c9989..383624bf298 100644 --- a/src/test/utils/phaseInterceptor.ts +++ b/src/test/utils/phaseInterceptor.ts @@ -34,10 +34,10 @@ import { UnavailablePhase, VictoryPhase } from "#app/phases"; -import UI, {Mode} from "#app/ui/ui"; -import {Phase} from "#app/phase"; +import UI, { Mode } from "#app/ui/ui"; +import { Phase } from "#app/phase"; import ErrorInterceptor from "#app/test/utils/errorInterceptor"; -import {QuietFormChangePhase} from "#app/form-change-phase"; +import { QuietFormChangePhase } from "#app/form-change-phase"; export default class PhaseInterceptor { public scene; diff --git a/src/test/utils/testUtils.ts b/src/test/utils/testUtils.ts index 0a9be16a4b5..476775fd268 100644 --- a/src/test/utils/testUtils.ts +++ b/src/test/utils/testUtils.ts @@ -1,3 +1,4 @@ +import BattleScene from "#app/battle-scene.js"; import { Moves } from "#app/enums/moves.js"; import i18next, { type ParseKeys } from "i18next"; import { vi } from "vitest"; @@ -26,3 +27,12 @@ export function arrayOfRange(start: integer, end: integer) { return Array.from({ length: end - start }, (_v, k) => k + start); } +/** + * Removes all held items from enemy pokemon + * @param scene `game.scene` + */ +export function removeEnemyHeldItems(scene: BattleScene) { + scene.clearEnemyHeldItemModifiers(); + scene.clearEnemyModifiers(); + console.log("Enemy held items removed"); +} diff --git a/src/test/vitest.setup.ts b/src/test/vitest.setup.ts index 7cddf4bf3b7..b2861b7071c 100644 --- a/src/test/vitest.setup.ts +++ b/src/test/vitest.setup.ts @@ -1,4 +1,4 @@ -import "#app/test/fontFace.setup"; +import "#test/fontFace.setup"; import "vitest-canvas-mock"; import { initLoggedInUser } from "#app/account"; diff --git a/src/ui/confirm-ui-handler.ts b/src/ui/confirm-ui-handler.ts index 2d83508384b..4a60b0c9689 100644 --- a/src/ui/confirm-ui-handler.ts +++ b/src/ui/confirm-ui-handler.ts @@ -28,7 +28,7 @@ export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler { label: i18next.t("partyUiHandler:SUMMARY"), handler: () => { args[0](); - return false; + return true; }, }, { label: i18next.t("menu:yes"), diff --git a/src/ui/dropdown.ts b/src/ui/dropdown.ts index 34ff96d66ee..80935d16a71 100644 --- a/src/ui/dropdown.ts +++ b/src/ui/dropdown.ts @@ -2,15 +2,19 @@ import BattleScene from "#app/battle-scene.js"; import { SceneBase } from "#app/scene-base.js"; import { addTextObject, TextStyle } from "./text"; import { addWindow, WindowVariant } from "./ui-theme"; +import i18next from "i18next"; export enum DropDownState { ON = 0, - OFF + OFF = 1, + EXCLUDE = 2 } export enum DropDownType { - MULTI = 0, - SINGLE + SINGLE = 0, + MULTI = 1, + HYBRID = 2, + RADIAL = 3 } export enum SortDirection { @@ -18,76 +22,253 @@ export enum SortDirection { DESC = 1 } +export class DropDownLabel { + public state: DropDownState; + public text: string; + public sprite?: Phaser.GameObjects.Sprite; + + constructor(label: string, sprite?: Phaser.GameObjects.Sprite, state: DropDownState = DropDownState.OFF) { + this.text = label || ""; + this.sprite = sprite; + this.state = state; + } +} + + export class DropDownOption extends Phaser.GameObjects.Container { public state: DropDownState = DropDownState.ON; public toggle: Phaser.GameObjects.Sprite; public text: Phaser.GameObjects.Text; - public sprite?: Phaser.GameObjects.Sprite; public val: any; public dir: SortDirection = SortDirection.ASC; + private currentLabelIndex: number; + private labels: DropDownLabel[]; + private onColor = 0x33bbff; + private offColor = 0x272727; + private excludeColor = 0xff5555; - constructor(scene: SceneBase, val: any, text: string, sprite?: Phaser.GameObjects.Sprite, state: DropDownState = DropDownState.ON) { + constructor(scene: SceneBase, val: any, labels: DropDownLabel | DropDownLabel[]) { super(scene); this.val = val; - if (text) { - this.text = addTextObject(scene, 0, 0, text, TextStyle.TOOLTIP_CONTENT); - this.text.setOrigin(0, 0.5); - this.add(this.text); - } - if (sprite) { - this.sprite = sprite.setOrigin(0, 0.5); - this.add(this.sprite); + if (Array.isArray(labels)) { + this.labels = labels; + } else { + this.labels = labels? [ labels ] : [ new DropDownLabel("") ]; + } + this.currentLabelIndex = 0; + const currentLabel = this.labels[this.currentLabelIndex]; + + this.state = currentLabel.state; + this.text = addTextObject(scene, 0, 0, currentLabel.text || "", TextStyle.TOOLTIP_CONTENT); + this.text.setOrigin(0, 0.5); + this.add(this.text); + + // Add to container the sprite for each label if there is one + for (let i=0; i < this.labels.length; i++) { + const sprite = this.labels[i].sprite; + if (sprite) { + this.add(sprite); + sprite.setOrigin(0, 0.5); + if (i!== this.currentLabelIndex) { + sprite.setVisible(false); + } + } } - this.state = state; } - public setupToggle(type: DropDownType): void { - if (type === DropDownType.MULTI) { - this.toggle = this.scene.add.sprite(0, 0, "candy"); - this.toggle.setScale(0.3); - this.toggle.setOrigin(0, 0.5); - } else { + /** + * Initialize the toggle icon based on the provided DropDownType + * For DropDownType.SINGLE: uses a cursor arrow icon + * For other types: uses a candy icon + * @param type the DropDownType to use + * @param visible whether the icon should be visible or not + */ + setupToggleIcon(type: DropDownType, visible: boolean): void { + if (type === DropDownType.SINGLE) { this.toggle = this.scene.add.sprite(0, 0, "cursor"); this.toggle.setScale(0.5); this.toggle.setOrigin(0, 0.5); this.toggle.setRotation(Math.PI / 180 * -90); + } else { + this.toggle = this.scene.add.sprite(0, 0, "candy"); + this.toggle.setScale(0.3); + this.toggle.setOrigin(0, 0.5); } this.add(this.toggle); + this.toggle.setVisible(visible); + this.updateToggleIconColor(); } - public setOptionState(state: DropDownState): DropDownState { - this.state = state % 2; - if (this.state === DropDownState.OFF) { - this.toggle.setTint(0x272727); - } else { - this.toggle.setTint(0x55ff55); + /** + * Set the toggle icon color based on the current state + */ + private updateToggleIconColor(): void { + switch (this.state) { + case DropDownState.ON: + this.toggle.setTint(this.onColor); + break; + case DropDownState.OFF: + this.toggle.setTint(this.offColor); + break; + case DropDownState.EXCLUDE: + this.toggle.setTint(this.excludeColor); + break; } + } + + /** + * Switch the option to its next state and update visuals + * If only ON/OFF are possible, toggle between the two + * For radials, move to the next state in the list + * @returns the updated DropDownState + */ + public toggleOptionState(): DropDownState { + if (this.labels.length > 1) { + return this.setCurrentLabel((this.currentLabelIndex + 1) % this.labels.length); + } + const newState = this.state === DropDownState.ON ? DropDownState.OFF : DropDownState.ON; + return this.setOptionState(newState); + } + + /** + * Set the option to the given state and update visuals + * @param newState the state to switch to + * @returns the new DropDownState + */ + public setOptionState(newState: DropDownState): DropDownState { + const newLabelIndex = this.labels.findIndex(label => label.state === newState); + if (newLabelIndex !== -1 && newLabelIndex !== this.currentLabelIndex) { + return this.setCurrentLabel(newLabelIndex); + } + + this.state = newState; + this.updateToggleIconColor(); + return newState; + } + + /** + * Change the option state to the one at the given index and update visuals + * @param index index of the state to switch to + * @returns the new DropDownState + */ + private setCurrentLabel(index: number): DropDownState { + const currentLabel = this.labels[this.currentLabelIndex]; + const newLabel = this.labels[index]; + + if (!newLabel) { + return this.state; + } + + this.currentLabelIndex = index; + + // update state, sprite and text to fit the new label + this.state = newLabel.state; + this.updateToggleIconColor(); + + if (currentLabel.sprite) { + this.text.x -= currentLabel.sprite.displayWidth + 2; + currentLabel.sprite.setVisible(false); + } + if (newLabel.sprite) { + this.text.x += newLabel.sprite.displayWidth + 2; + newLabel.sprite.setVisible(true); + } + this.text.setText(newLabel.text); + return this.state; } - public toggleOptionState(): DropDownState { - return this.setOptionState(this.state + 1); - } - + /** + * Set the current SortDirection to the provided value and update icon accordingly + * @param SortDirection the new SortDirection to use + */ public setDirection(dir: SortDirection): void { this.dir = dir; this.toggle.flipX = this.dir === SortDirection.DESC; } + /** + * Toggle the current SortDirection value + */ public toggleDirection(): void { this.setDirection(this.dir * -1); } + + /** + * Place the label elements (text and sprite if there is one) to the provided x and y position + * @param x the horizontal position + * @param y the vertical position + */ + setLabelPosition(x: number, y: number) { + let textX = x; + for (let i=0; i < this.labels.length; i++) { + const label = this.labels[i]; + if (label.sprite) { + label.sprite.x = x; + label.sprite.y = y; + if (i === this.currentLabelIndex) { + textX += label.sprite.displayWidth + 2; + } + } + } + if (this.text) { + this.text.x = textX; + this.text.y = y; + } + } + + /** + * Place the toggle icon at the provided position + * @param x the horizontal position + * @param y the vertical position + */ + setTogglePosition(x: number, y: number) { + if (this.toggle) { + this.toggle.x = x; + this.toggle.y = y; + } + } + + /** + * @returns the x position to use for the current label depending on if it has a sprite or not + */ + getCurrentLabelX(): number { + if (this.labels[this.currentLabelIndex].sprite) { + return this.labels[this.currentLabelIndex].sprite.x; + } + return this.text.x; + } + + /** + * @returns max width needed to display all of the labels + */ + getWidth(): number { + let w = 0; + const currentText = this.text.text; + for (const label of this.labels) { + this.text.setText(label.text); + const spriteWidth = label.sprite? label.sprite.displayWidth + 2 : 0; + w = Math.max(w, this.text.displayWidth + spriteWidth); + } + this.text.setText(currentText); + return w; + } + } + export class DropDown extends Phaser.GameObjects.Container { public options: DropDownOption[]; private window: Phaser.GameObjects.NineSlice; private cursorObj: Phaser.GameObjects.Image; - private dropDownType: DropDownType = DropDownType.MULTI; - public cursor: integer = 0; + public dropDownType: DropDownType = DropDownType.MULTI; + public cursor: number = 0; + private lastCursor: number = -1; + public defaultCursor: number = 0; private onChange: () => void; private lastDir: SortDirection = SortDirection.ASC; + private defaultSettings: any[]; constructor(scene: BattleScene, x: number, y: number, options: DropDownOption[], onChange: () => void, type: DropDownType = DropDownType.MULTI, optionSpacing: number = 2) { const windowPadding = 5; @@ -107,31 +288,31 @@ export class DropDown extends Phaser.GameObjects.Container { this.cursorObj.setOrigin(0, 0.5); this.cursorObj.setVisible(false); - if (this.dropDownType === DropDownType.MULTI) { - this.options.unshift(new DropDownOption(scene, "ALL", "All", null, this.checkForAllOn() ? DropDownState.ON : DropDownState.OFF)); + // For MULTI and HYBRID filter, add an ALL option at the top + if (this.dropDownType === DropDownType.MULTI || this.dropDownType === DropDownType.HYBRID) { + this.options.unshift(new DropDownOption(scene, "ALL", new DropDownLabel(i18next.t("filterBar:all"), undefined, this.checkForAllOn() ? DropDownState.ON : DropDownState.OFF))); } + this.defaultSettings = this.getSettings(); + + // Place ui elements in the correct spot options.forEach((option, index) => { - option.setupToggle(type); - if (type === DropDownType.SINGLE && option.state === DropDownState.OFF) { - option.toggle.setVisible(false); - } - option.setOptionState(option.state); + const toggleVisibility = type !== DropDownType.SINGLE || option.state === DropDownState.ON; + option.setupToggleIcon(type, toggleVisibility); option.width = optionWidth; option.y = index * optionHeight + index * optionSpacing + optionPaddingY; - if (option.text) { - option.text.x = cursorOffset + optionPaddingX + 3 + 8; - option.text.y = optionHeight / 2; + const baseX = cursorOffset + optionPaddingX + 3; + const baseY = optionHeight / 2; + option.setLabelPosition(baseX + 8, baseY); + if (type === DropDownType.SINGLE) { + option.setTogglePosition(baseX + 3, baseY + 1); + } else { + option.setTogglePosition(baseX, baseY); } - if (option.sprite) { - option.sprite.x = cursorOffset + optionPaddingX + 3 + 8; - option.sprite.y = optionHeight / 2; - } - option.toggle.x = cursorOffset + optionPaddingX + 3 + (type === DropDownType.MULTI ? 0 : 3); - option.toggle.y = optionHeight / 2 + (type === DropDownType.MULTI ? 0 : 1); }); + this.window = addWindow(scene, 0, 0, optionWidth, options[options.length - 1].y + optionHeight + optionPaddingY, false, false, null, null, WindowVariant.XTHIN); this.add(this.window); this.add(options); @@ -139,10 +320,32 @@ export class DropDown extends Phaser.GameObjects.Container { this.setVisible(false); } - toggle(): void { + getWidth(): number { + return this.window? this.window.width : this.width; + } + + toggleVisibility(): void { this.setVisible(!this.visible); } + setVisible(value: boolean): this { + super.setVisible(value); + + if (value) { + this.autoSize(); + } + + return this; + } + + resetCursor(): boolean { + // If we are an hybrid dropdown in "hover" mode, don't move the cursor back to 0 + if (this.dropDownType === DropDownType.HYBRID && this.checkForAllOff()) { + return this.setCursor(this.lastCursor); + } + return this.setCursor(this.defaultCursor); + } + setCursor(cursor: integer): boolean { this.cursor = cursor; if (cursor < 0) { @@ -157,89 +360,217 @@ export class DropDown extends Phaser.GameObjects.Container { } else { this.cursorObj.y = this.options[cursor].y + 3.5; this.cursorObj.setVisible(true); + // If hydrid type, we need to update the filters when going up/down in the list + if (this.dropDownType === DropDownType.HYBRID) { + this.lastCursor = cursor; + this.onChange(); + } } return true; } - toggleOptionState(): void { - if (this.dropDownType === DropDownType.MULTI) { - const newState = this.options[this.cursor].toggleOptionState(); - - if (this.cursor === 0) { - this.options.forEach((option, index) => { - if (index !== this.cursor) { - option.setOptionState(newState); - } - }); + /** + * Switch the option at the provided index to its next state and update visuals + * Update accordingly the other options if needed: + * - if "all" is toggled, also update all other options + * - for DropDownType.SINGLE, unselect the previously selected option if applicable + * @param index the index of the option for which to update the state + */ + toggleOptionState(index: number = this.cursor): void { + const option: DropDownOption = this.options[index]; + if (this.dropDownType === DropDownType.MULTI || this.dropDownType === DropDownType.HYBRID) { + const newState = option.toggleOptionState(); + if (index === 0) { + // we are on the All option > put all other options to the newState + this.setAllOptions(newState); } else { - if (this.checkForAllOff()) { - this.options[0].setOptionState(DropDownState.OFF); - } else if (this.checkForAllOn()) { + // select the "all" option if all others are selected, other unselect it + if (newState === DropDownState.ON && this.checkForAllOn()) { this.options[0].setOptionState(DropDownState.ON); } else { this.options[0].setOptionState(DropDownState.OFF); } } - } else { - if (this.options[this.cursor].state === DropDownState.OFF) { + } else if (this.dropDownType === DropDownType.SINGLE) { + if (option.state === DropDownState.OFF) { this.options.forEach((option) => { option.setOptionState(DropDownState.OFF); option.setDirection(SortDirection.ASC); option.toggle.setVisible(false); }); - this.options[this.cursor].setOptionState(DropDownState.ON); - this.options[this.cursor].setDirection(this.lastDir); - this.options[this.cursor].toggle.setVisible(true); + option.setOptionState(DropDownState.ON); + option.setDirection(this.lastDir); + option.toggle.setVisible(true); } else { - this.options[this.cursor].toggleDirection(); + option.toggleDirection(); this.lastDir = this.options[this.cursor].dir; } + } else if (this.dropDownType === DropDownType.RADIAL) { + option.toggleOptionState(); } this.onChange(); } - setVisible(value: boolean): this { - super.setVisible(value); - - if (value) { - this.autoSize(); - } - - return this; - } - + /** + * Check whether all options except the "ALL" one are ON + * @returns true if all options are set to DropDownState.ON, false otherwise + */ checkForAllOn(): boolean { return this.options.every((option, i) => i === 0 || option.state === DropDownState.ON); } + /** + * Check whether all options except the "ALL" one are OFF + * @returns true if all options are set to DropDownState.OFF, false otherwise + */ checkForAllOff(): boolean { return this.options.every((option, i) => i === 0 || option.state === DropDownState.OFF); } + /** + * Get the current selected values for each option + * @returns an array of values, depending on the DropDownType + * - if MULTI or HYBRID, an array of all the values of the options set to ON (except the ALL one) + * - if RADIAL, an array where the value for each option is of the form { val: any, state: DropDownState } + * - if SINGLE, a single object of the form { val: any, state: SortDirection } + */ getVals(): any[] { if (this.dropDownType === DropDownType.MULTI) { return this.options.filter((option, i) => i > 0 && option.state === DropDownState.ON).map((option) => option.val); + } else if (this.dropDownType === DropDownType.HYBRID) { + const selected = this.options.filter((option, i) => i > 0 && option.state === DropDownState.ON).map((option) => option.val); + if (selected.length > 0) { + return selected; + } + // if nothing is selected and the ALL option is hovered, return all elements + if (this.cursor === 0) { + return this.options.filter((_, i) => i > 0).map(option => option.val); + } + // if nothing is selected and a single option is hovered, return that one + return [this.options[this.cursor].val]; + } else if (this.dropDownType === DropDownType.RADIAL) { + return this.options.map((option) => { + return { val: option.val, state: option.state }; + }); } else { - return this.options.filter((option, i) => option.state === DropDownState.ON).map((option) => { - return {val: option.val, dir: option.dir}; + return this.options.filter(option => option.state === DropDownState.ON).map((option) => { + return { val: option.val, dir: option.dir }; }); } } + /** + * Get the current selected settings dictionary for each option + * @returns an array of dictionaries with the current state of each option + * - the settings dictionary is like this { val: any, state: DropDownState, cursor: boolean, dir: SortDirection } + */ + private getSettings(): any[] { + const settings = []; + for (let i = 0; i < this.options.length; i++) { + settings.push({ val: this.options[i].val, state: this.options[i].state , cursor: (this.cursor === i), dir: this.options[i].dir }); + } + return settings; + } + + /** + * Check whether the values of all options are the same as the default ones + * @returns true if they are the same, false otherwise + */ + public hasDefaultValues(): boolean { + const currentValues = this.getSettings(); + + const compareValues = (keys: string[]): boolean => { + return currentValues.length === this.defaultSettings.length && + currentValues.every((value, index) => + keys.every(key => value[key] === this.defaultSettings[index][key]) + ); + }; + + switch (this.dropDownType) { + case DropDownType.MULTI: + case DropDownType.RADIAL: + return compareValues(["val", "state"]); + + case DropDownType.HYBRID: + return compareValues(["val", "state", "cursor"]); + + case DropDownType.SINGLE: + return compareValues(["val", "state", "dir"]); + + default: + return false; + } + } + + /** + * Set all values to their default state + */ + public resetToDefault(): void { + if (this.defaultSettings.length > 0) { + this.setCursor(this.defaultCursor); + this.lastDir = SortDirection.ASC; + + for (let i = 0; i < this.options.length; i++) { + // reset values with the defaultValues + if (this.dropDownType === DropDownType.SINGLE) { + if (this.defaultSettings[i].state === DropDownState.OFF) { + this.options[i].setOptionState(DropDownState.OFF); + this.options[i].setDirection(SortDirection.ASC); + this.options[i].toggle.setVisible(false); + } else { + this.options[i].setOptionState(DropDownState.ON); + this.options[i].setDirection(SortDirection.ASC); + this.options[i].toggle.setVisible(true); + } + } else { + if (this.defaultSettings[i]) { + this.options[i].setOptionState(this.defaultSettings[i]["state"]); + } + } + } + } + } + + /** + * Set all options to a specific state + * @param state the DropDownState to assign to each option + */ + private setAllOptions(state: DropDownState) : void { + // For single type dropdown, setting all options is not relevant + if (this.dropDownType === DropDownType.SINGLE) { + return; + } + + for (const option of this.options) { + option.setOptionState(state); + } + } + + /** + * Set all options to their ON state + */ + public selectAllOptions() { + this.setAllOptions(DropDownState.ON); + } + + /** + * Set all options to their OFF state + */ + public unselectAllOptions() { + this.setAllOptions(DropDownState.OFF); + } + + /** + * Automatically set the width and position based on the size of options + */ autoSize(): void { let maxWidth = 0; let x = 0; for (let i = 0; i < this.options.length; i++) { - if (this.options[i].sprite) { - if (this.options[i].sprite.displayWidth > maxWidth) { - maxWidth = this.options[i].sprite.displayWidth; - x = this.options[i].sprite.x; - } - } else { - if (this.options[i].text.displayWidth > maxWidth) { - maxWidth = this.options[i].text.displayWidth; - x = this.options[i].text.x; - } + const optionWidth = this.options[i].getWidth(); + if (optionWidth > maxWidth) { + maxWidth = optionWidth; + x = this.options[i].getCurrentLabelX(); } } this.window.width = maxWidth + x - this.window.x + 6; @@ -249,7 +580,4 @@ export class DropDown extends Phaser.GameObjects.Container { } } - isActive(): boolean { - return this.options.some((option) => option.state === DropDownState.ON); - } } diff --git a/src/ui/filter-bar.ts b/src/ui/filter-bar.ts index cc4723799d5..52266a3a06b 100644 --- a/src/ui/filter-bar.ts +++ b/src/ui/filter-bar.ts @@ -1,30 +1,29 @@ import BattleScene from "#app/battle-scene.js"; -import { DropDown } from "./dropdown"; +import { DropDown, DropDownType } from "./dropdown"; import { StarterContainer } from "./starter-container"; -import { addTextObject, TextStyle } from "./text"; +import { addTextObject, getTextColor, TextStyle } from "./text"; +import { UiTheme } from "#enums/ui-theme"; import { addWindow, WindowVariant } from "./ui-theme"; export enum DropDownColumn { GEN, TYPES, + CAUGHT, UNLOCKS, - WIN, + MISC, SORT } export class FilterBar extends Phaser.GameObjects.Container { private window: Phaser.GameObjects.NineSlice; - public labels: Phaser.GameObjects.Text[] = []; - public dropDowns: DropDown[] = []; + private labels: Phaser.GameObjects.Text[] = []; + private dropDowns: DropDown[] = []; + private columns: DropDownColumn[] = []; public cursorObj: Phaser.GameObjects.Image; public numFilters: number = 0; public openDropDown: boolean = false; private lastCursor: number = -1; - public defaultGenVals: any[] = []; - public defaultTypeVals: any[] = []; - public defaultUnlockVals: any[] = []; - public defaultWinVals: any[] = []; - public defaultSortVals: any[] = []; + private uiTheme: UiTheme; constructor(scene: BattleScene, x: number, y: number, width: number, height: number) { super(scene, x, y); @@ -40,10 +39,26 @@ export class FilterBar extends Phaser.GameObjects.Container { this.cursorObj.setVisible(false); this.cursorObj.setOrigin(0, 0); this.add(this.cursorObj); + + this.uiTheme = scene.uiTheme; } - addFilter(text: string, dropDown: DropDown): void { - const filterTypesLabel = addTextObject(this.scene, 0, 3, text, TextStyle.TOOLTIP_CONTENT); + /** + * Add a new filter to the FilterBar, as long that a unique DropDownColumn is provided + * @param column the DropDownColumn that will be used to access the filter values + * @param title the string that will get displayed in the filter bar + * @param dropDown the DropDown with all options for this filter + * @returns true if successful, false if the provided column was already in use for another filter + */ + addFilter(column: DropDownColumn, title: string, dropDown: DropDown): boolean { + // The column should be unique to each filter, + if (this.columns.includes(column)) { + return false; + } + + this.columns.push(column); + + const filterTypesLabel = addTextObject(this.scene, 0, 3, title, TextStyle.TOOLTIP_CONTENT); this.labels.push(filterTypesLabel); this.add(filterTypesLabel); this.dropDowns.push(dropDown); @@ -51,61 +66,39 @@ export class FilterBar extends Phaser.GameObjects.Container { this.calcFilterPositions(); this.numFilters++; + + return true; } + /** + * Get the DropDown associated to a given filter + * @param col the DropDownColumn used to register the filter to retrieve + * @returns the associated DropDown if it exists, undefined otherwise + */ + getFilter(col: DropDownColumn) : DropDown { + return this.dropDowns[this.columns.indexOf(col)]; + } + /** + * Highlight the labels of the FilterBar if the filters are different from their default values + */ updateFilterLabels(): void { - const genVals = this.getVals(DropDownColumn.GEN); - const typeVals = this.getVals(DropDownColumn.TYPES); - const unlockVals = this.getVals(DropDownColumn.UNLOCKS); - const winVals = this.getVals(DropDownColumn.WIN); - const sortVals = this.getVals(DropDownColumn.SORT); - - // onColor is Yellow, offColor is White - const onColor = 0xffef5c; - const offColor = 0xffffff; - - // if genVals and defaultGenVals has same elements, set the label to White else set it to Green - if (genVals.length === this.defaultGenVals.length && genVals.every((value, index) => value === this.defaultGenVals[index])) { - this.labels[DropDownColumn.GEN].setTint(offColor); - } else { - this.labels[DropDownColumn.GEN].setTint(onColor); - } - - // if typeVals and defaultTypeVals has same elements, set the label to White else set it to Green - if (typeVals.length === this.defaultTypeVals.length && typeVals.every((value, index) => value === this.defaultTypeVals[index])) { - this.labels[DropDownColumn.TYPES].setTint(offColor); - } else { - this.labels[DropDownColumn.TYPES].setTint(onColor); - } - - // if unlockVals and defaultUnlockVals has same elements, set the label to White else set it to Green - if (unlockVals.length === this.defaultUnlockVals.length && unlockVals.every((value, index) => value === this.defaultUnlockVals[index])) { - this.labels[DropDownColumn.UNLOCKS].setTint(offColor); - } else { - this.labels[DropDownColumn.UNLOCKS].setTint(onColor); - } - - // if winVals and defaultWinVals has same elements, set the label to White else set it to Green - if (winVals.length === this.defaultWinVals.length && winVals.every((value, index) => value === this.defaultWinVals[index])) { - this.labels[DropDownColumn.WIN].setTint(offColor); - } else { - this.labels[DropDownColumn.WIN].setTint(onColor); - } - - // if sortVals and defaultSortVals has same value and dir, set the label to White else set it to Green - if (sortVals[0]["dir"] === this.defaultSortVals[0]["dir"] && sortVals[0]["val"] === this.defaultSortVals[0]["val"]) { - this.labels[DropDownColumn.SORT].setTint(offColor); - } else { - this.labels[DropDownColumn.SORT].setTint(onColor); + for (let i = 0; i < this.numFilters; i++) { + if (this.dropDowns[i].hasDefaultValues()) { + this.labels[i].setColor(getTextColor(TextStyle.TOOLTIP_CONTENT, false, this.uiTheme)); + } else { + this.labels[i].setColor(getTextColor(TextStyle.STATS_LABEL, false, this.uiTheme)); + } } } - calcFilterPositions(): void { + /** + * Position the filter dropdowns evenly across the width of the container + */ + private calcFilterPositions(): void { const paddingX = 6; const cursorOffset = 8; - // position labels with even space across the width of the container let totalWidth = paddingX * 2 + cursorOffset; this.labels.forEach(label => { totalWidth += label.displayWidth + cursorOffset; @@ -124,12 +117,25 @@ export class FilterBar extends Phaser.GameObjects.Container { } } + /** + * Move the leftmost dropdown to the left of the FilterBar instead of below it + */ + offsetHybridFilters(): void { + for (let i=0; i -1) { if (this.dropDowns[this.lastCursor].visible) { this.dropDowns[this.lastCursor].setVisible(false); this.dropDowns[cursor].setVisible(true); - this.dropDowns[cursor].setCursor(0); + this.dropDowns[cursor].resetCursor(); } } @@ -139,9 +145,9 @@ export class FilterBar extends Phaser.GameObjects.Container { } toggleDropDown(index: number): void { - this.dropDowns[index].toggle(); + this.dropDowns[index].toggleVisibility(); this.openDropDown = this.dropDowns[index].visible; - this.dropDowns[index].setCursor(0); + this.dropDowns[index].resetCursor(); } hideDropDowns(): void { @@ -172,11 +178,22 @@ export class FilterBar extends Phaser.GameObjects.Container { } getVals(col: DropDownColumn): any[] { - return this.dropDowns[col].getVals(); + return this.getFilter(col).getVals(); } + setValsToDefault(): void { + for (const dropDown of this.dropDowns) { + dropDown.resetToDefault(); + } + } + + /** + * Find the nearest filter to the provided container + * @param container the StarterContainer to compare position against + * @returns the index of the closest filter + */ getNearestFilter(container: StarterContainer): number { - // find the nearest filter to the x position + const midx = container.x + container.icon.displayWidth / 2; let nearest = 0; let nearestDist = 1000; @@ -191,11 +208,4 @@ export class FilterBar extends Phaser.GameObjects.Container { return nearest; } - getLastFilterX(): number { - return this.labels[this.lastCursor].x + this.labels[this.lastCursor].displayWidth / 2; - } - - isFilterActive(index: number) { - return this.dropDowns[index].isActive(); - } } diff --git a/src/ui/menu-ui-handler.ts b/src/ui/menu-ui-handler.ts index a0cea2f78d5..4710c575ce9 100644 --- a/src/ui/menu-ui-handler.ts +++ b/src/ui/menu-ui-handler.ts @@ -40,8 +40,8 @@ export default class MenuUiHandler extends MessageUiHandler { private cursorObj: Phaser.GameObjects.Image; - protected ignoredMenuOptions: MenuOptions[]; - protected menuOptions: MenuOptions[]; + private excludedMenus: () => ConditionalMenu[]; + private menuOptions: MenuOptions[]; protected manageDataConfig: OptionSelectConfig; protected communityConfig: OptionSelectConfig; @@ -52,13 +52,19 @@ export default class MenuUiHandler extends MessageUiHandler { constructor(scene: BattleScene, mode?: Mode) { super(scene, mode); - this.ignoredMenuOptions = !bypassLogin - ? [ ] - : [ MenuOptions.LOG_OUT ]; - this.menuOptions = Utils.getEnumKeys(MenuOptions).map(m => parseInt(MenuOptions[m]) as MenuOptions).filter(m => !this.ignoredMenuOptions.includes(m)); + this.excludedMenus = () => [ + { condition: [Mode.COMMAND, Mode.TITLE].includes(mode ?? Mode.TITLE), options: [ MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST] }, + { condition: bypassLogin, options: [ MenuOptions.LOG_OUT ] } + ]; + + this.menuOptions = Utils.getEnumKeys(MenuOptions) + .map(m => parseInt(MenuOptions[m]) as MenuOptions) + .filter(m => { + return !this.excludedMenus().some(exclusion => exclusion.condition && exclusion.options.includes(m)); + }); } - setup() { + setup(): void { const ui = this.getUi(); // wiki url directs based on languges available on wiki const lang = i18next.resolvedLanguage.substring(0,2); @@ -80,10 +86,25 @@ export default class MenuUiHandler extends MessageUiHandler { this.menuOverlay.setOrigin(0,0); this.menuContainer.add(this.menuOverlay); - const menuMessageText = addTextObject(this.scene, 8, 8, "", TextStyle.WINDOW, { maxLines: 2 }); - menuMessageText.setName("menu-message"); - menuMessageText.setWordWrapWidth(1224); - menuMessageText.setOrigin(0, 0); + this.menuContainer.add(this.bgmBar); + + this.menuContainer.setVisible(false); + + } + + + render() { + const ui = this.getUi(); + this.excludedMenus = () => [ + { condition: ![Mode.COMMAND, Mode.TITLE].includes(ui.getModeChain()[0]), options: [ MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST] }, + { condition: bypassLogin, options: [ MenuOptions.LOG_OUT ] } + ]; + + this.menuOptions = Utils.getEnumKeys(MenuOptions) + .map(m => parseInt(MenuOptions[m]) as MenuOptions) + .filter(m => { + return !this.excludedMenus().some(exclusion => exclusion.condition && exclusion.options.includes(m)); + }); this.optionSelectText = addTextObject(this.scene, 0, 0, this.menuOptions.map(o => `${i18next.t(`menuUiHandler:${MenuOptions[o]}`)}`).join("\n"), TextStyle.WINDOW, { maxLines: this.menuOptions.length }); this.optionSelectText.setLineSpacing(12); @@ -108,10 +129,12 @@ export default class MenuUiHandler extends MessageUiHandler { menuMessageBox.setOrigin(0, 0); this.menuMessageBoxContainer.add(menuMessageBox); + const menuMessageText = addTextObject(this.scene, 8, 8, "", TextStyle.WINDOW, { maxLines: 2 }); + menuMessageText.setName("menu-message"); + menuMessageText.setWordWrapWidth(1224); + menuMessageText.setOrigin(0, 0); this.menuMessageBoxContainer.add(menuMessageText); - this.menuContainer.add(this.bgmBar); - this.message = menuMessageText; this.menuContainer.add(this.menuMessageBoxContainer); @@ -270,16 +293,19 @@ export default class MenuUiHandler extends MessageUiHandler { xOffset: 98, options: communityOptions }; - this.setCursor(0); - - this.menuContainer.setVisible(false); } show(args: any[]): boolean { - + this.render(); super.show(args); + this.menuOptions = Utils.getEnumKeys(MenuOptions) + .map(m => parseInt(MenuOptions[m]) as MenuOptions) + .filter(m => { + return !this.excludedMenus().some(exclusion => exclusion.condition && exclusion.options.includes(m)); + }); + this.menuContainer.setVisible(true); this.setCursor(0); @@ -305,11 +331,15 @@ export default class MenuUiHandler extends MessageUiHandler { if (button === Button.ACTION) { let adjustedCursor = this.cursor; - for (const imo of this.ignoredMenuOptions) { - if (adjustedCursor >= imo) { - adjustedCursor++; - } else { - break; + const excludedMenu = this.excludedMenus().find(e => e.condition); + if (excludedMenu !== undefined && excludedMenu.options !== undefined && excludedMenu.options.length > 0) { + const sortedOptions = excludedMenu.options.sort(); + for (const imo of sortedOptions) { + if (adjustedCursor >= imo) { + adjustedCursor++; + } else { + break; + } } } switch (adjustedCursor) { @@ -506,3 +536,8 @@ export default class MenuUiHandler extends MessageUiHandler { this.cursorObj = null; } } + +interface ConditionalMenu { + condition: boolean; + options: MenuOptions[]; +} diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index b3718b8854c..b10bcbb18f6 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -10,6 +10,7 @@ import {Button} from "#enums/buttons"; import MoveInfoOverlay from "./move-info-overlay"; import { allMoves } from "../data/move"; import * as Utils from "./../utils"; +import Overrides from "#app/overrides"; import i18next from "i18next"; export const SHOP_OPTIONS_ROW_LIMIT = 6; @@ -726,9 +727,10 @@ class ModifierOption extends Phaser.GameObjects.Container { updateCostText(): void { const scene = this.scene as BattleScene; - const textStyle = this.modifierTypeOption.cost <= scene.money ? TextStyle.MONEY : TextStyle.PARTY_RED; + const cost = Overrides.WAIVE_ROLL_FEE_OVERRIDE ? 0 : this.modifierTypeOption.cost; + const textStyle = cost <= scene.money ? TextStyle.MONEY : TextStyle.PARTY_RED; - const formattedMoney = Utils.formatMoney(scene.moneyFormat, this.modifierTypeOption.cost); + const formattedMoney = Utils.formatMoney(scene.moneyFormat, cost); this.itemCostText.setText(i18next.t("modifierSelectUiHandler:itemCost", { formattedMoney })); this.itemCostText.setColor(getTextColor(textStyle, false, scene.uiTheme)); diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 9bb8162ce2a..80ce318532b 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -288,6 +288,36 @@ export default class PartyUiHandler extends MessageUiHandler { const pokemon = this.scene.getParty()[this.cursor]; if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode && option !== PartyOption.CANCEL) { this.startTransfer(); + + let ableToTransfer: string; + for (let p = 0; p < this.scene.getParty().length; p++) { // this fore look goes through each of the party pokemon + const newPokemon = this.scene.getParty()[p]; + // this next line gets all of the transferable items from pokemon [p]; it does this by getting all the held modifiers that are transferable and checking to see if they belong to pokemon [p] + const getTransferrableItemsFromPokemon = (newPokemon: PlayerPokemon) => + this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).isTransferrable && (m as PokemonHeldItemModifier).pokemonId === newPokemon.id) as PokemonHeldItemModifier[]; + // this next bit checks to see if the the selected item from the original transfer pokemon exists on the new pokemon [p]; this returns undefined if the new pokemon doesn't have the item at all, otherwise it returns the pokemonHeldItemModifier for that item + const matchingModifier = newPokemon.scene.findModifier(m => m instanceof PokemonHeldItemModifier && m.pokemonId === newPokemon.id && m.matchType(getTransferrableItemsFromPokemon(pokemon)[this.transferOptionCursor])) as PokemonHeldItemModifier; + const partySlot = this.partySlots.filter(m => m.getPokemon() === newPokemon)[0]; // this gets pokemon [p] for us + if (p !== this.transferCursor) { // this skips adding the able/not able labels on the pokemon doing the transfer + if (matchingModifier) { // if matchingModifier exists then the item exists on the new pokemon + if (matchingModifier.getMaxStackCount(this.scene) === matchingModifier.stackCount) { // checks to see if the stack of items is at max stack; if so, set the description label to "Not able" + ableToTransfer = "Not able"; + } else { // if the pokemon isn't at max stack, make the label "Able" + ableToTransfer = "Able"; + } + } else { // if matchingModifier doesn't exist, that means the pokemon doesn't have any of the item, and we need to show "Able" + ableToTransfer = "Able"; + } + } else { // this else relates to the transfer pokemon. We set the text to be blank so there's no "Able"/"Not able" text + ableToTransfer = ""; + } + partySlot.slotHpBar.setVisible(false); + partySlot.slotHpOverlay.setVisible(false); + partySlot.slotHpText.setVisible(false); + partySlot.slotDescriptionLabel.setText(ableToTransfer); + partySlot.slotDescriptionLabel.setVisible(true); + } + this.clearOptions(); ui.playSelect(); return true; @@ -947,6 +977,12 @@ export default class PartyUiHandler extends MessageUiHandler { this.transferMode = false; this.transferAll = false; this.partySlots[this.transferCursor].setTransfer(false); + for (let i = 0; i < this.partySlots.length; i++) { + this.partySlots[i].slotDescriptionLabel.setVisible(false); + this.partySlots[i].slotHpBar.setVisible(true); + this.partySlots[i].slotHpOverlay.setVisible(true); + this.partySlots[i].slotHpText.setVisible(true); + } } doRelease(slotIndex: integer): void { @@ -1041,6 +1077,12 @@ class PartySlot extends Phaser.GameObjects.Container { private slotBg: Phaser.GameObjects.Image; private slotPb: Phaser.GameObjects.Sprite; + public slotName: Phaser.GameObjects.Text; + public slotHpBar: Phaser.GameObjects.Image; + public slotHpOverlay: Phaser.GameObjects.Sprite; + public slotHpText: Phaser.GameObjects.Text; + public slotDescriptionLabel: Phaser.GameObjects.Text; // this is used to show text instead of the HP bar i.e. for showing "Able"/"Not Able" for TMs when you try to learn them + private pokemonIcon: Phaser.GameObjects.Container; private iconAnimHandler: PokemonIconAnimHandler; @@ -1057,6 +1099,10 @@ class PartySlot extends Phaser.GameObjects.Container { this.setup(partyUiMode, tmMoveId); } + getPokemon(): PlayerPokemon { + return this.pokemon; + } + setup(partyUiMode: PartyUiMode, tmMoveId: Moves) { const battlerCount = (this.scene as BattleScene).currentBattle.getBattlerCount(); @@ -1095,19 +1141,19 @@ class PartySlot extends Phaser.GameObjects.Container { nameSizeTest.destroy(); - const slotName = addTextObject(this.scene, 0, 0, displayName, TextStyle.PARTY); - slotName.setPositionRelative(slotBg, this.slotIndex >= battlerCount ? 21 : 24, this.slotIndex >= battlerCount ? 2 : 10); - slotName.setOrigin(0, 0); + this.slotName = addTextObject(this.scene, 0, 0, displayName, TextStyle.PARTY); + this.slotName.setPositionRelative(slotBg, this.slotIndex >= battlerCount ? 21 : 24, this.slotIndex >= battlerCount ? 2 : 10); + this.slotName.setOrigin(0, 0); const slotLevelLabel = this.scene.add.image(0, 0, "party_slot_overlay_lv"); - slotLevelLabel.setPositionRelative(slotName, 8, 12); + slotLevelLabel.setPositionRelative(this.slotName, 8, 12); slotLevelLabel.setOrigin(0, 0); const slotLevelText = addTextObject(this.scene, 0, 0, this.pokemon.level.toString(), this.pokemon.level < (this.scene as BattleScene).getMaxExpLevel() ? TextStyle.PARTY : TextStyle.PARTY_RED); slotLevelText.setPositionRelative(slotLevelLabel, 9, 0); slotLevelText.setOrigin(0, 0.25); - slotInfoContainer.add([ slotName, slotLevelLabel, slotLevelText ]); + slotInfoContainer.add([this.slotName, slotLevelLabel, slotLevelText ]); const genderSymbol = getGenderSymbol(this.pokemon.getGender(true)); @@ -1118,7 +1164,7 @@ class PartySlot extends Phaser.GameObjects.Container { if (this.slotIndex >= battlerCount) { slotGenderText.setPositionRelative(slotLevelLabel, 36, 0); } else { - slotGenderText.setPositionRelative(slotName, 76 - (this.pokemon.fusionSpecies ? 8 : 0), 3); + slotGenderText.setPositionRelative(this.slotName, 76 - (this.pokemon.fusionSpecies ? 8 : 0), 3); } slotGenderText.setOrigin(0, 0.25); @@ -1132,7 +1178,7 @@ class PartySlot extends Phaser.GameObjects.Container { if (this.slotIndex >= battlerCount) { splicedIcon.setPositionRelative(slotLevelLabel, 36 + (genderSymbol ? 8 : 0), 0.5); } else { - splicedIcon.setPositionRelative(slotName, 76, 3.5); + splicedIcon.setPositionRelative(this.slotName, 76, 3.5); } slotInfoContainer.add(splicedIcon); @@ -1152,7 +1198,7 @@ class PartySlot extends Phaser.GameObjects.Container { const shinyStar = this.scene.add.image(0, 0, `shiny_star_small${doubleShiny ? "_1" : ""}`); shinyStar.setOrigin(0, 0); - shinyStar.setPositionRelative(slotName, -9, 3); + shinyStar.setPositionRelative(this.slotName, -9, 3); shinyStar.setTint(getVariantTint(!doubleShiny ? this.pokemon.getVariant() : this.pokemon.variant)); slotInfoContainer.add(shinyStar); @@ -1167,24 +1213,40 @@ class PartySlot extends Phaser.GameObjects.Container { } } + this.slotHpBar = this.scene.add.image(0, 0, "party_slot_hp_bar"); + this.slotHpBar.setPositionRelative(slotBg, this.slotIndex >= battlerCount ? 72 : 8, this.slotIndex >= battlerCount ? 6 : 31); + this.slotHpBar.setOrigin(0, 0); + this.slotHpBar.setVisible(false); + + const hpRatio = this.pokemon.getHpRatio(); + + this.slotHpOverlay = this.scene.add.sprite(0, 0, "party_slot_hp_overlay", hpRatio > 0.5 ? "high" : hpRatio > 0.25 ? "medium" : "low"); + this.slotHpOverlay.setPositionRelative(this.slotHpBar, 16, 2); + this.slotHpOverlay.setOrigin(0, 0); + this.slotHpOverlay.setScale(hpRatio, 1); + this.slotHpOverlay.setVisible(false); + + this.slotHpText = addTextObject(this.scene, 0, 0, `${this.pokemon.hp}/${this.pokemon.getMaxHp()}`, TextStyle.PARTY); + this.slotHpText.setPositionRelative(this.slotHpBar, this.slotHpBar.width - 3, this.slotHpBar.height - 2); + this.slotHpText.setOrigin(1, 0); + this.slotHpText.setVisible(false); + + this.slotDescriptionLabel = addTextObject(this.scene, 0, 0, "", TextStyle.MESSAGE); + this.slotDescriptionLabel.setPositionRelative(slotBg, this.slotIndex >= battlerCount ? 94 : 32, this.slotIndex >= battlerCount ? 16 : 46); + this.slotDescriptionLabel.setOrigin(0, 1); + this.slotDescriptionLabel.setVisible(false); + + slotInfoContainer.add([this.slotHpBar, this.slotHpOverlay, this.slotHpText, this.slotDescriptionLabel]); + if (partyUiMode !== PartyUiMode.TM_MODIFIER) { - const slotHpBar = this.scene.add.image(0, 0, "party_slot_hp_bar"); - slotHpBar.setPositionRelative(slotBg, this.slotIndex >= battlerCount ? 72 : 8, this.slotIndex >= battlerCount ? 6 : 31); - slotHpBar.setOrigin(0, 0); - - const hpRatio = this.pokemon.getHpRatio(); - - const slotHpOverlay = this.scene.add.sprite(0, 0, "party_slot_hp_overlay", hpRatio > 0.5 ? "high" : hpRatio > 0.25 ? "medium" : "low"); - slotHpOverlay.setPositionRelative(slotHpBar, 16, 2); - slotHpOverlay.setOrigin(0, 0); - slotHpOverlay.setScale(hpRatio, 1); - - const slotHpText = addTextObject(this.scene, 0, 0, `${this.pokemon.hp}/${this.pokemon.getMaxHp()}`, TextStyle.PARTY); - slotHpText.setPositionRelative(slotHpBar, slotHpBar.width - 3, slotHpBar.height - 2); - slotHpText.setOrigin(1, 0); - - slotInfoContainer.add([ slotHpBar, slotHpOverlay, slotHpText ]); + this.slotDescriptionLabel.setVisible(false); + this.slotHpBar.setVisible(true); + this.slotHpOverlay.setVisible(true); + this.slotHpText.setVisible(true); } else { + this.slotHpBar.setVisible(false); + this.slotHpOverlay.setVisible(false); + this.slotHpText.setVisible(false); let slotTmText: string; switch (true) { case (this.pokemon.compatibleTms.indexOf(tmMoveId) === -1): @@ -1198,11 +1260,9 @@ class PartySlot extends Phaser.GameObjects.Container { break; } - const slotTmLabel = addTextObject(this.scene, 0, 0, slotTmText, TextStyle.MESSAGE); - slotTmLabel.setPositionRelative(slotBg, this.slotIndex >= battlerCount ? 94 : 32, this.slotIndex >= battlerCount ? 16 : 46); - slotTmLabel.setOrigin(0, 1); + this.slotDescriptionLabel.setText(slotTmText); + this.slotDescriptionLabel.setVisible(true); - slotInfoContainer.add(slotTmLabel); } } diff --git a/src/ui/pokemon-info-container.ts b/src/ui/pokemon-info-container.ts index 1e958ae53b7..b2ee5a9164a 100644 --- a/src/ui/pokemon-info-container.ts +++ b/src/ui/pokemon-info-container.ts @@ -216,7 +216,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { this.pokemonGenderText.setShadowColor(getGenderColor(pokemon.gender, true)); this.pokemonGenderText.setVisible(true); - const newGender = BigInt(Math.pow(2, pokemon.gender)) * DexAttr.MALE; + const newGender = BigInt(1 << pokemon.gender) * DexAttr.MALE; this.pokemonGenderNewText.setText("(+)"); this.pokemonGenderNewText.setColor(getTextColor(TextStyle.SUMMARY_BLUE, false, this.scene.uiTheme)); this.pokemonGenderNewText.setShadowColor(getTextColor(TextStyle.SUMMARY_BLUE, true, this.scene.uiTheme)); @@ -229,7 +229,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { if (pokemon.species.forms?.[pokemon.formIndex]?.formName) { this.pokemonFormLabelText.setVisible(true); this.pokemonFormText.setVisible(true); - const newForm = BigInt(Math.pow(2, pokemon.formIndex)) * DexAttr.DEFAULT_FORM; + const newForm = BigInt(1 << pokemon.formIndex) * DexAttr.DEFAULT_FORM; if ((newForm & caughtAttr) === BigInt(0)) { this.pokemonFormLabelText.setColor(getTextColor(TextStyle.SUMMARY_BLUE, false, this.scene.uiTheme)); @@ -266,7 +266,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { */ const opponentPokemonOneNormalAbility = (pokemon.species.getAbilityCount() === 2); const opponentPokemonAbilityIndex = (opponentPokemonOneNormalAbility && pokemon.abilityIndex === 1) ? 2 : pokemon.abilityIndex; - const opponentPokemonAbilityAttr = Math.pow(2, opponentPokemonAbilityIndex); + const opponentPokemonAbilityAttr = 1 << opponentPokemonAbilityIndex; const rootFormHasHiddenAbility = pokemon.scene.gameData.starterData[pokemon.species.getRootSpeciesId()].abilityAttr & opponentPokemonAbilityAttr; @@ -281,7 +281,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { this.pokemonNatureText.setText(getNatureName(pokemon.getNature(), true, false, false, this.scene.uiTheme)); const dexNatures = pokemon.scene.gameData.dexData[pokemon.species.speciesId].natureAttr; - const newNature = Math.pow(2, pokemon.nature + 1); + const newNature = 1 << (pokemon.nature + 1); if (!(dexNatures & newNature)) { this.pokemonNatureLabelText.setColor(getTextColor(TextStyle.SUMMARY_BLUE, false, this.scene.uiTheme)); @@ -305,8 +305,8 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { this.pokemonShinyIcon.on("pointerover", () => (this.scene as BattleScene).ui.showTooltip(null, `${i18next.t("common:shinyOnHover")}${shinyDescriptor ? ` (${shinyDescriptor})` : ""}`, true)); this.pokemonShinyIcon.on("pointerout", () => (this.scene as BattleScene).ui.hideTooltip()); - const newShiny = BigInt(Math.pow(2, (pokemon.shiny ? 1 : 0))); - const newVariant = BigInt(Math.pow(2, pokemon.variant + 4)); + const newShiny = BigInt(1 << (pokemon.shiny ? 1 : 0)); + const newVariant = BigInt(1 << (pokemon.variant + 4)); this.pokemonShinyNewIcon.setText("(+)"); this.pokemonShinyNewIcon.setColor(getTextColor(TextStyle.SUMMARY_BLUE, false, this.scene.uiTheme)); diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 1307f46d28f..6735f5f1251 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -40,7 +40,7 @@ import { Species } from "#enums/species"; import {Button} from "#enums/buttons"; import { EggSourceType } from "#app/enums/egg-source-types.js"; import AwaitableUiHandler from "./awaitable-ui-handler"; -import { DropDown, DropDownOption, DropDownState, DropDownType } from "./dropdown"; +import { DropDown, DropDownLabel, DropDownOption, DropDownState, DropDownType } from "./dropdown"; import { StarterContainer } from "./starter-container"; import { DropDownColumn, FilterBar } from "./filter-bar"; import { ScrollBar } from "./scroll-bar"; @@ -119,6 +119,14 @@ const starterCandyCosts: { passive: integer, costReduction: [integer, integer], { passive: 10, costReduction: [3, 10], egg: 10 }, // 10 ]; +// Position of UI elements +const filterBarHeight = 17; +const speciesContainerX = 109; // if team on the RIGHT: 109 / if on the LEFT: 143 +const teamWindowX = 285; // if team on the RIGHT: 285 / if on the LEFT: 109 +const teamWindowY = 18; +const teamWindowWidth = 34; +const teamWindowHeight = 132; + function getPassiveCandyCount(baseValue: integer): integer { return starterCandyCosts[baseValue - 1].passive; } @@ -145,14 +153,66 @@ function calcStarterPosition(index: number, scrollCursor:number = 0): {x: number return {x: x, y: y}; } +/** + * Calculates the y position for the icon of stater pokemon selected for the team + * @param index index of the Pokemon in the team (0-5) + * @returns the y position to use for the icon + */ +function calcStarterIconY(index: number) { + const starterSpacing = teamWindowHeight / 7; + const firstStarterY = teamWindowY + starterSpacing / 2; + return Math.round(firstStarterY + starterSpacing * index); +} + +/** + * Finds the index of the team Pokemon closest vertically to the given y position + * @param y the y position to find closest starter Pokemon + * @param teamSize how many Pokemon are in the team (0-6) + * @returns index of the closest Pokemon in the team container + */ +function findClosestStarterIndex(y: number, teamSize: number = 6): number { + let smallestDistance = teamWindowHeight; + let closestStarterIndex = 0; + for (let i = 0; i < teamSize; i++) { + const distance = Math.abs(y - (calcStarterIconY(i) - 13)); + if (distance < smallestDistance) { + closestStarterIndex = i; + smallestDistance = distance; + } + } + return closestStarterIndex; +} + +/** + * Finds the row of the filtered Pokemon closest vertically to the given Pokemon in the team + * @param index index of the Pokemon in the team (0-5) + * @param numberOfRows the number of rows to check against + * @returns index of the row closest vertically to the given Pokemon + */ +function findClosestStarterRow(index: number, numberOfRows: number) { + const currentY = calcStarterIconY(index) - 13; + let smallestDistance = teamWindowHeight; + let closestRowIndex = 0; + for (let i=0; i < numberOfRows; i++) { + const distance = Math.abs(currentY - calcStarterPosition(i * 9).y); + if (distance < smallestDistance) { + closestRowIndex = i; + smallestDistance = distance; + } + } + return closestRowIndex; +} + + export default class StarterSelectUiHandler extends MessageUiHandler { private starterSelectContainer: Phaser.GameObjects.Container; private starterSelectScrollBar: ScrollBar; private filterBarContainer: Phaser.GameObjects.Container; private filterBar: FilterBar; private shinyOverlay: Phaser.GameObjects.Image; - private starterContainer: StarterContainer[] = []; + private starterContainers: StarterContainer[] = []; private filteredStarterContainers: StarterContainer[] = []; + private validStarterContainers: StarterContainer[] = []; private pokemonNumberText: Phaser.GameObjects.Text; private pokemonSprite: Phaser.GameObjects.Sprite; private pokemonNameText: Phaser.GameObjects.Text; @@ -296,40 +356,33 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.shinyOverlay.setVisible(false); this.starterSelectContainer.add(this.shinyOverlay); - const starterContainerWindow = addWindow(this.scene, 109, 18, 175, 161); - const starterContainerBg = this.scene.add.image(110, 19, "starter_container_bg"); + const starterContainerWindow = addWindow(this.scene, speciesContainerX, filterBarHeight + 1, 175, 161); + const starterContainerBg = this.scene.add.image(speciesContainerX+1, filterBarHeight + 2, "starter_container_bg"); starterContainerBg.setOrigin(0, 0); this.starterSelectContainer.add(starterContainerBg); - this.starterSelectContainer.add(addWindow(this.scene, 285, 59, 34, 91)); - this.starterSelectContainer.add(addWindow(this.scene, 285, 145, 34, 34, true)); + this.starterSelectContainer.add(addWindow(this.scene, teamWindowX, teamWindowY, teamWindowWidth, teamWindowHeight)); + this.starterSelectContainer.add(addWindow(this.scene, teamWindowX, teamWindowY + teamWindowHeight - 5, teamWindowWidth, teamWindowWidth, true)); this.starterSelectContainer.add(starterContainerWindow); + // Create and initialise filter bar this.filterBarContainer = this.scene.add.container(0, 0); - - // this.filterBar = new FilterBar(this.scene, 143, 1, 175, 17); - this.filterBar = new FilterBar(this.scene, 109, 1, 175, 17); + this.filterBar = new FilterBar(this.scene, Math.min(speciesContainerX, teamWindowX), 1, 210, filterBarHeight); // gen filter const genOptions: DropDownOption[] = [ - new DropDownOption(this.scene, 1, i18next.t("starterSelectUiHandler:gen1"), null, DropDownState.ON), - new DropDownOption(this.scene, 2, i18next.t("starterSelectUiHandler:gen2"), null, DropDownState.ON), - new DropDownOption(this.scene, 3, i18next.t("starterSelectUiHandler:gen3"), null, DropDownState.ON), - new DropDownOption(this.scene, 4, i18next.t("starterSelectUiHandler:gen4"), null, DropDownState.ON), - new DropDownOption(this.scene, 5, i18next.t("starterSelectUiHandler:gen5"), null, DropDownState.ON), - new DropDownOption(this.scene, 6, i18next.t("starterSelectUiHandler:gen6"), null, DropDownState.ON), - new DropDownOption(this.scene, 7, i18next.t("starterSelectUiHandler:gen7"), null, DropDownState.ON), - new DropDownOption(this.scene, 8, i18next.t("starterSelectUiHandler:gen8"), null, DropDownState.ON), - new DropDownOption(this.scene, 9, i18next.t("starterSelectUiHandler:gen9"), null, DropDownState.ON), + new DropDownOption(this.scene, 1, new DropDownLabel(i18next.t("starterSelectUiHandler:gen1"))), + new DropDownOption(this.scene, 2, new DropDownLabel(i18next.t("starterSelectUiHandler:gen2"))), + new DropDownOption(this.scene, 3, new DropDownLabel(i18next.t("starterSelectUiHandler:gen3"))), + new DropDownOption(this.scene, 4, new DropDownLabel(i18next.t("starterSelectUiHandler:gen4"))), + new DropDownOption(this.scene, 5, new DropDownLabel(i18next.t("starterSelectUiHandler:gen5"))), + new DropDownOption(this.scene, 6, new DropDownLabel(i18next.t("starterSelectUiHandler:gen6"))), + new DropDownOption(this.scene, 7, new DropDownLabel(i18next.t("starterSelectUiHandler:gen7"))), + new DropDownOption(this.scene, 8, new DropDownLabel(i18next.t("starterSelectUiHandler:gen8"))), + new DropDownOption(this.scene, 9, new DropDownLabel(i18next.t("starterSelectUiHandler:gen9"))), ]; - this.filterBar.addFilter("Gen", new DropDown(this.scene, 0, 0, genOptions, this.updateStarters, DropDownType.MULTI)); - this.filterBar.defaultGenVals = this.filterBar.getVals(DropDownColumn.GEN); - // set gen filter to all off except for the I GEN - for (const option of genOptions) { - if (option.val !== 1) { - option.setOptionState(DropDownState.OFF); - } - } + const genDropDown: DropDown = new DropDown(this.scene, 0, 0, genOptions, this.updateStarters, DropDownType.HYBRID); + this.filterBar.addFilter(DropDownColumn.GEN, i18next.t("filterBar:genFilter"), genDropDown); // type filter const typeKeys = Object.keys(Type).filter(v => isNaN(Number(v))); @@ -341,51 +394,96 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const typeSprite = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); typeSprite.setScale(0.5); typeSprite.setFrame(type.toLowerCase()); - typeOptions.push(new DropDownOption(this.scene, index, null, typeSprite)); + typeOptions.push(new DropDownOption(this.scene, index, new DropDownLabel("", typeSprite))); }); - this.filterBar.addFilter("Type", new DropDown(this.scene, 0, 0, typeOptions, this.updateStarters, DropDownType.MULTI, 0.5)); - this.filterBar.defaultTypeVals = this.filterBar.getVals(DropDownColumn.TYPES); + this.filterBar.addFilter(DropDownColumn.TYPES, i18next.t("filterBar:typeFilter"), new DropDown(this.scene, 0, 0, typeOptions, this.updateStarters, DropDownType.HYBRID, 0.5)); - // Unlocks filter - const shiny1Sprite = this.scene.add.sprite(0, 0, "shiny_star_small"); + // caught filter + const shiny1Sprite = this.scene.add.sprite(0, 0, "shiny_icons"); + shiny1Sprite.setOrigin(0.15, 0.2); + shiny1Sprite.setScale(0.6); + shiny1Sprite.setFrame(getVariantIcon(0)); shiny1Sprite.setTint(getVariantTint(0)); - const shiny2Sprite = this.scene.add.sprite(0, 0, "shiny_star_small"); + const shiny2Sprite = this.scene.add.sprite(0, 0, "shiny_icons"); + shiny2Sprite.setOrigin(0.15, 0.2); + shiny2Sprite.setScale(0.6); + shiny2Sprite.setFrame(getVariantIcon(1)); shiny2Sprite.setTint(getVariantTint(1)); - const shiny3Sprite = this.scene.add.sprite(0, 0, "shiny_star_small"); + const shiny3Sprite = this.scene.add.sprite(0, 0, "shiny_icons"); + shiny3Sprite.setOrigin(0.15, 0.2); + shiny3Sprite.setScale(0.6); + shiny3Sprite.setFrame(getVariantIcon(2)); shiny3Sprite.setTint(getVariantTint(2)); + const caughtOptions = [ + new DropDownOption(this.scene, "SHINY3", new DropDownLabel("", shiny3Sprite)), + new DropDownOption(this.scene, "SHINY2", new DropDownLabel("", shiny2Sprite)), + new DropDownOption(this.scene, "SHINY", new DropDownLabel("", shiny1Sprite)), + new DropDownOption(this.scene, "NORMAL", new DropDownLabel(i18next.t("filterBar:normal"))), + new DropDownOption(this.scene, "UNCAUGHT", new DropDownLabel(i18next.t("filterBar:uncaught"))) + ]; + + this.filterBar.addFilter(DropDownColumn.CAUGHT, i18next.t("filterBar:caughtFilter"), new DropDown(this.scene, 0, 0, caughtOptions, this.updateStarters, DropDownType.HYBRID)); + + // unlocks filter + const passiveLabels = [ + new DropDownLabel(i18next.t("filterBar:passive"), undefined, DropDownState.OFF), + new DropDownLabel(i18next.t("filterBar:passiveUnlocked"), undefined, DropDownState.ON), + new DropDownLabel(i18next.t("filterBar:passiveLocked"), undefined, DropDownState.EXCLUDE), + ]; + + const costReductionLabels = [ + new DropDownLabel(i18next.t("filterBar:costReduction"), undefined, DropDownState.OFF), + new DropDownLabel(i18next.t("filterBar:costReductionUnlocked"), undefined, DropDownState.ON), + new DropDownLabel(i18next.t("filterBar:costReductionLocked"), undefined, DropDownState.EXCLUDE), + ]; + const unlocksOptions = [ - new DropDownOption(this.scene, "SHINY3", null, shiny3Sprite), - new DropDownOption(this.scene, "SHINY2", null, shiny2Sprite), - new DropDownOption(this.scene, "SHINY", null, shiny1Sprite), - new DropDownOption(this.scene, "NORMAL", "Normal"), - new DropDownOption(this.scene, "UNCAUGHT", "Not Caught"), - new DropDownOption(this.scene, "PASSIVEUNLOCKED", "Passive Unlocked"), - new DropDownOption(this.scene, "PASSIVELOCKED", "Passive Locked"),]; + new DropDownOption(this.scene, "PASSIVE", passiveLabels), + new DropDownOption(this.scene, "COST_REDUCTION", costReductionLabels), + ]; - this.filterBar.addFilter("Unlocks", new DropDown(this.scene, 0, 0, unlocksOptions, this.updateStarters, DropDownType.MULTI)); - this.filterBar.defaultUnlockVals = this.filterBar.getVals(DropDownColumn.UNLOCKS); + this.filterBar.addFilter(DropDownColumn.UNLOCKS, i18next.t("filterBar:unlocksFilter"), new DropDown(this.scene, 0, 0, unlocksOptions, this.updateStarters, DropDownType.RADIAL)); - // win filter - const winOptions = [ - new DropDownOption(this.scene, "WIN", "has won"), - new DropDownOption(this.scene, "NOTWIN", "hasn't won yet")]; - this.filterBar.addFilter("Win", new DropDown(this.scene, 0, 0, winOptions, this.updateStarters, DropDownType.MULTI)); - this.filterBar.defaultWinVals = this.filterBar.getVals(DropDownColumn.WIN); + // misc filter + const winLabels = [ + new DropDownLabel(i18next.t("filterBar:ribbon"), undefined, DropDownState.OFF), + new DropDownLabel(i18next.t("filterBar:hasWon"), undefined, DropDownState.ON), + new DropDownLabel(i18next.t("filterBar:hasNotWon"), undefined, DropDownState.EXCLUDE), + ]; + const hiddenAbilityLabels = [ + new DropDownLabel(i18next.t("filterBar:hiddenAbility"), undefined, DropDownState.OFF), + new DropDownLabel(i18next.t("filterBar:hasHiddenAbility"), undefined, DropDownState.ON), + new DropDownLabel(i18next.t("filterBar:noHiddenAbility"), undefined, DropDownState.EXCLUDE), + ]; + const pokerusLabels = [ + new DropDownLabel(i18next.t("filterBar:pokerus"), undefined, DropDownState.OFF), + new DropDownLabel(i18next.t("filterBar:hasPokerus"), undefined, DropDownState.ON), + new DropDownLabel(i18next.t("filterBar:noPokerus"), undefined, DropDownState.EXCLUDE), + ]; + const miscOptions = [ + new DropDownOption(this.scene, "WIN", winLabels), + new DropDownOption(this.scene, "HIDDEN_ABILITY", hiddenAbilityLabels), + new DropDownOption(this.scene, "POKERUS", pokerusLabels), + ]; + this.filterBar.addFilter(DropDownColumn.MISC, i18next.t("filterBar:miscFilter"), new DropDown(this.scene, 0, 0, miscOptions, this.updateStarters, DropDownType.RADIAL)); // sort filter const sortOptions = [ - new DropDownOption(this.scene, 0, "No."), - new DropDownOption(this.scene, 1, "Cost", null, DropDownState.OFF), - new DropDownOption(this.scene, 2, "# Candies", null, DropDownState.OFF), - new DropDownOption(this.scene, 3, "IVs", null, DropDownState.OFF), - new DropDownOption(this.scene, 4, "Name", null, DropDownState.OFF)]; - this.filterBar.addFilter("Sort", new DropDown(this.scene, 0, 0, sortOptions, this.updateStarters, DropDownType.SINGLE)); + new DropDownOption(this.scene, 0, new DropDownLabel(i18next.t("filterBar:sortByNumber"), undefined, DropDownState.ON)), + new DropDownOption(this.scene, 1, new DropDownLabel(i18next.t("filterBar:sortByCost"))), + new DropDownOption(this.scene, 2, new DropDownLabel(i18next.t("filterBar:sortByCandies"))), + new DropDownOption(this.scene, 3, new DropDownLabel(i18next.t("filterBar:sortByIVs"))), + new DropDownOption(this.scene, 4, new DropDownLabel(i18next.t("filterBar:sortByName"))) + ]; + this.filterBar.addFilter(DropDownColumn.SORT, i18next.t("filterBar:sortFilter"), new DropDown(this.scene, 0, 0, sortOptions, this.updateStarters, DropDownType.SINGLE)); this.filterBarContainer.add(this.filterBar); - this.filterBar.defaultSortVals = this.filterBar.getVals(DropDownColumn.SORT); this.starterSelectContainer.add(this.filterBarContainer); + // Offset the generation filter dropdown to avoid covering the filtered pokemon + this.filterBar.offsetHybridFilters(); + if (!this.scene.uiTheme) { starterContainerWindow.setVisible(false); } @@ -461,22 +559,22 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonEggMoveBgs = []; this.pokemonEggMoveLabels = []; - this.valueLimitLabel = addTextObject(this.scene, 302, 150, "0/10", TextStyle.TOOLTIP_CONTENT); + this.valueLimitLabel = addTextObject(this.scene, teamWindowX+17, 150, "0/10", TextStyle.TOOLTIP_CONTENT); this.valueLimitLabel.setOrigin(0.5, 0); this.starterSelectContainer.add(this.valueLimitLabel); - const startLabel = addTextObject(this.scene, 302, 162, i18next.t("common:start"), TextStyle.TOOLTIP_CONTENT); + const startLabel = addTextObject(this.scene, teamWindowX+17, 162, i18next.t("common:start"), TextStyle.TOOLTIP_CONTENT); startLabel.setOrigin(0.5, 0); this.starterSelectContainer.add(startLabel); - this.startCursorObj = this.scene.add.nineslice(289, 160, "select_cursor", null, 26, 15, 6, 6, 6, 6); + this.startCursorObj = this.scene.add.nineslice(teamWindowX+4, 160, "select_cursor", null, 26, 15, 6, 6, 6, 6); this.startCursorObj.setVisible(false); this.startCursorObj.setOrigin(0, 0); this.starterSelectContainer.add(this.startCursorObj); const starterSpecies: Species[] = []; - const starterBoxContainer = this.scene.add.container(115, 9); + const starterBoxContainer = this.scene.add.container(speciesContainerX + 6, 9); //115 this.starterSelectScrollBar = new ScrollBar(this.scene, 161, 12, 0); @@ -519,14 +617,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const starterContainer = new StarterContainer(this.scene, species).setVisible(false); this.iconAnimHandler.addOrUpdate(starterContainer.icon, PokemonIconAnimMode.NONE); - this.starterContainer.push(starterContainer); + this.starterContainers.push(starterContainer); starterBoxContainer.add(starterContainer); } this.starterSelectContainer.add(starterBoxContainer); this.starterIcons = new Array(6).fill(null).map((_, i) => { - const icon = this.scene.add.sprite(292, 63 + 13 * i, "pokemon_icons_0"); + const icon = this.scene.add.sprite(teamWindowX + 7, calcStarterIconY(i), "pokemon_icons_0"); icon.setScale(0.5); icon.setOrigin(0, 0); icon.setFrame("unknown"); @@ -803,7 +901,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterSelectContainer.setVisible(true); this.allSpecies.forEach((species, s) => { - const icon = this.starterContainer[s].icon; + const icon = this.starterContainers[s].icon; const dexEntry = this.scene.gameData.dexData[species.speciesId]; if (dexEntry.caughtAttr) { @@ -815,6 +913,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.setUpgradeAnimation(icon, species); }); + this.resetFilters(); this.updateStarters(); this.setFilterMode(false); @@ -830,6 +929,20 @@ export default class StarterSelectUiHandler extends MessageUiHandler { return false; } + /** + * Set the selections for all filters to their default starting value + */ + resetFilters() : void { + const genDropDown: DropDown = this.filterBar.getFilter(DropDownColumn.GEN); + + this.filterBar.setValsToDefault(); + + if (!this.scene.gameMode.isChallenge) { + // if not in a challenge, in Gen hybrid filter hovering mode, set the cursor to the Gen1 + genDropDown.setCursor(1); + } + } + showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer) { super.showText(text, delay, callback, callbackDelay, prompt, promptDelay); @@ -1008,18 +1121,16 @@ export default class StarterSelectUiHandler extends MessageUiHandler { return false; } + const maxColumns = 9; + const maxRows = 9; const numberOfStarters = this.filteredStarterContainers.length; - const numOfRows = Math.ceil(numberOfStarters / 9); - const currentRow = Math.floor(this.cursor / 9); - const onScreenFirstIndex = this.scrollCursor * 9; // this is first starter index on the screen - const onScreenLastIndex = Math.min(onScreenFirstIndex + 9*9, numberOfStarters) - 1; // this is the last starter index on the screen + const numOfRows = Math.ceil(numberOfStarters / maxColumns); + const currentRow = Math.floor(this.cursor / maxColumns); + const onScreenFirstIndex = this.scrollCursor * maxColumns; // this is first starter index on the screen + const onScreenLastIndex = Math.min(this.filteredStarterContainers.length - 1, onScreenFirstIndex + maxRows * maxColumns - 1); // this is the last starter index on the screen const onScreenNumberOfStarters = onScreenLastIndex - onScreenFirstIndex + 1; - const onScreenNumberOfRows = Math.ceil(onScreenNumberOfStarters / 9); - // const onScreenFirstRow = Math.floor(onScreenFirstIndex / 9); - const onScreenCurrentRow = Math.floor((this.cursor - onScreenFirstIndex) / 9); - - - // console.log("this.cursor: ", this.cursor, "this.scrollCursor" , this.scrollCursor, "numberOfStarters: ", numberOfStarters, "numOfRows: ", numOfRows, "currentRow: ", currentRow, "onScreenFirstIndex: ", onScreenFirstIndex, "onScreenLastIndex: ", onScreenLastIndex, "onScreenNumberOfStarters: ", onScreenNumberOfStarters, "onScreenNumberOfRow: ", onScreenNumberOfRows, "onScreenCurrentRow: ", onScreenCurrentRow); + const onScreenNumberOfRows = Math.ceil(onScreenNumberOfStarters / maxColumns); + const onScreenCurrentRow = Math.floor((this.cursor - onScreenFirstIndex) / maxColumns); const ui = this.getUi(); @@ -1034,8 +1145,18 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } } else if (button === Button.CANCEL) { if (this.filterMode && this.filterBar.openDropDown) { + // CANCEL with a filter menu open > close it this.filterBar.toggleDropDown(this.filterBarCursor); + + // if there are possible starters go the first one of the list + if (numberOfStarters > 0) { + this.setFilterMode(false); + this.scrollCursor = 0; + this.updateScroll(); + this.setCursor(0); + } success = true; + } else if (this.statsMode) { this.toggleStatsMode(false); success = true; @@ -1044,14 +1165,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { success = true; this.updateInstructions(); } else { - this.blockInput = true; - this.scene.clearPhaseQueue(); - if (this.scene.gameMode.isChallenge) { - this.scene.pushPhase(new SelectChallengePhase(this.scene)); - } else { - this.scene.pushPhase(new TitlePhase(this.scene)); - } - this.scene.getCurrentPhase().end(); + this.tryExit(); success = true; } } else if (this.startCursorObj.visible) { // this checks to see if the start button is selected @@ -1069,6 +1183,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterIconsCursorIndex = this.starterSpecies.length - 1; this.moveStarterIconsCursor(this.starterIconsCursorIndex); } else { + // up from start button with no Pokemon in the team > go to filter + this.startCursorObj.setVisible(false); + this.filterBarCursor = Math.max(1, this.filterBar.numFilters - 1); this.setFilterMode(true); } success = true; @@ -1079,6 +1196,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterIconsCursorIndex = 0; this.moveStarterIconsCursor(this.starterIconsCursorIndex); } else { + // down from start button with no Pokemon in the team > go to filter + this.startCursorObj.setVisible(false); + this.filterBarCursor = Math.max(1, this.filterBar.numFilters - 1); this.setFilterMode(true); } success = true; @@ -1117,27 +1237,31 @@ export default class StarterSelectUiHandler extends MessageUiHandler { success = this.filterBar.decDropDownCursor(); // else if there is filtered starters } else if (numberOfStarters > 0) { + // UP from filter bar to bottom of Pokemon list this.setFilterMode(false); this.scrollCursor = Math.max(0,numOfRows - 9); this.updateScroll(); const proportion = (this.filterBarCursor + 0.5) / this.filterBar.numFilters; - const targetCol = Math.floor(proportion * 9); + const targetCol = Math.min(8, Math.floor(proportion * 11)); if (numberOfStarters % 9 > targetCol) { - success = this.setCursor(numberOfStarters - (numberOfStarters) % 9 + targetCol); + this.setCursor(numberOfStarters - (numberOfStarters) % 9 + targetCol); } else { - success = this.setCursor(Math.max(numberOfStarters - (numberOfStarters) % 9 + targetCol - 9,0)); + this.setCursor(Math.max(numberOfStarters - (numberOfStarters) % 9 + targetCol - 9, 0)); } + success = true; } break; case Button.DOWN: if (this.filterBar.openDropDown) { success = this.filterBar.incDropDownCursor(); } else if (numberOfStarters > 0) { + // DOWN from filter bar to top of Pokemon list this.setFilterMode(false); this.scrollCursor = 0; this.updateScroll(); const proportion = this.filterBarCursor / Math.max(1, this.filterBar.numFilters - 1); - this.setCursor(Math.round(proportion * (Math.min(9, numberOfStarters) - 1))); + const targetCol = Math.min(8, Math.floor(proportion * 11)); + this.setCursor(Math.min(targetCol, numberOfStarters)); success = true; } break; @@ -1154,7 +1278,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (button === Button.ACTION) { if (!this.speciesStarterDexEntry?.caughtAttr) { error = true; - } else if (this.starterSpecies.length < 6) { // checks to see you have less than 6 pokemon in your party + } else if (this.starterSpecies.length <= 6) { // checks to see if the party has 6 or fewer pokemon let species; @@ -1173,22 +1297,25 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const isPartyValid = this.isPartyValid(); const isValidForChallenge = new Utils.BooleanHolder(true); if (isPartyValid) { - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true)), !!(this.starterSpecies.length)); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true)), this.starterSpecies.length !== 0); } else { - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true)), !!(this.starterSpecies.length), false, false); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true)), this.starterSpecies.length !== 0, false, false); } const currentPartyValue = this.starterSpecies.map(s => s.generation).reduce((total: number, gen: number, i: number) => total += this.scene.gameData.getSpeciesStarterValue(this.starterSpecies[i].speciesId), 0); const newCost = this.scene.gameData.getSpeciesStarterValue(species.speciesId); - if (!isDupe && isValidForChallenge.value && currentPartyValue + newCost <= this.getValueLimit()) { // this checks to make sure the pokemon doesn't exist in your party, it's valid for the challenge and that it won't go over the cost limit; if it meets all these criteria it will add it to your party + if (!isDupe && isValidForChallenge.value && currentPartyValue + newCost <= this.getValueLimit() && this.starterSpecies.length < 6) { // this checks to make sure the pokemon doesn't exist in your party, it's valid for the challenge and that it won't go over the cost limit; if it meets all these criteria it will add it to your party options = [ { label: i18next.t("starterSelectUiHandler:addToParty"), handler: () => { ui.setMode(Mode.STARTER_SELECT); - - if (!isDupe && isValidForChallenge.value && this.tryUpdateValue(this.scene.gameData.getSpeciesStarterValue(species.speciesId), true)) { - this.addToParty(species); + const isOverValueLimit = this.tryUpdateValue(this.scene.gameData.getSpeciesStarterValue(species.speciesId), true); + if (!isDupe && isValidForChallenge.value && isOverValueLimit) { + const cursorObj = this.starterCursorObjs[this.starterSpecies.length]; + cursorObj.setVisible(true); + cursorObj.setPosition(this.cursorObj.x, this.cursorObj.y); + this.addToParty(species, this.dexAttrCursor, this.abilityCursor, this.natureCursor as unknown as Nature, this.starterMoveset.slice(0) as StarterMoveset); ui.playSelect(); } else { ui.playError(); // this should be redundant as there is now a trigger for when a pokemon can't be added to party @@ -1219,6 +1346,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { }); if (this.speciesStarterMoves.length > 1) { // this lets you change the pokemon moves const showSwapOptions = (moveset: StarterMoveset) => { + + this.blockInput = true; + ui.setMode(Mode.STARTER_SELECT).then(() => { ui.showText(i18next.t("starterSelectUiHandler:selectMoveSwapOut"), null, () => { this.moveInfoOverlay.show(allMoves[moveset[0]]); @@ -1228,6 +1358,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const option: OptionSelectItem = { label: allMoves[m].name, handler: () => { + this.blockInput = true; ui.setMode(Mode.STARTER_SELECT).then(() => { ui.showText(`${i18next.t("starterSelectUiHandler:selectMoveSwapWith")} ${allMoves[m].name}.`, null, () => { const possibleMoves = this.speciesStarterMoves.filter((sm: Moves) => sm !== m); @@ -1262,6 +1393,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { maxOptions: 8, yOffset: 19 }); + this.blockInput = false; }); }); return true; @@ -1287,6 +1419,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { maxOptions: 8, yOffset: 19 }); + this.blockInput = false; }); }); }; @@ -1304,6 +1437,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (this.canCycleNature) { // if we could cycle natures, enable the improved nature menu const showNatureOptions = () => { + + this.blockInput = true; + ui.setMode(Mode.STARTER_SELECT).then(() => { ui.showText(i18next.t("starterSelectUiHandler:selectNature"), null, () => { const natures = this.scene.gameData.getNaturesForAttr(this.speciesStarterDexEntry.natureAttr); @@ -1321,6 +1457,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { ui.setMode(Mode.STARTER_SELECT); // set nature for starter this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, undefined, undefined, n, undefined); + this.blockInput = false; return true; } }; @@ -1330,6 +1467,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { handler: () => { this.clearText(); ui.setMode(Mode.STARTER_SELECT); + this.blockInput = false; return true; } }), @@ -1643,9 +1781,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } } else { if (this.starterIconsCursorIndex === 0) { + // Up from first Pokemon in the team > go to filter this.starterIconsCursorObj.setVisible(false); this.setSpecies(null); - this.startCursorObj.setVisible(true); + this.filterBarCursor = Math.max(1, this.filterBar.numFilters - 1); + this.setFilterMode(true); } else { this.starterIconsCursorIndex--; this.moveStarterIconsCursor(this.starterIconsCursorIndex); @@ -1661,7 +1801,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } success = this.setCursor(this.cursor + 9); this.updateScroll(); - } else { // last row + } else if (numOfRows > 1) { + // DOWN from last row of Pokemon > Wrap around to first row + this.scrollCursor = 0; + this.updateScroll(); + success = this.setCursor(this.cursor % 9); + } else { + // DOWN from single row of Pokemon > Go to filters + this.filterBarCursor = this.filterBar.getNearestFilter(this.filteredStarterContainers[this.cursor]); this.setFilterMode(true); success = true; } @@ -1682,29 +1829,36 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (this.cursor % 9 !== 0) { success = this.setCursor(this.cursor - 1); } else { + // LEFT from filtered Pokemon, on the left edge + if (this.starterSpecies.length === 0) { - // just wrap around to the last column + // no starter in team > wrap around to the last column success = this.setCursor(this.cursor + Math.min(8, numberOfStarters - this.cursor)); - } else if (onScreenCurrentRow < 3) { - // always to the first starter - this.cursorObj.setVisible(false); - this.starterIconsCursorIndex = 0; - this.moveStarterIconsCursor(this.starterIconsCursorIndex); + } else if (onScreenCurrentRow < 7) { + // at least one pokemon in team > for the first 7 rows, go to closest starter this.cursorObj.setVisible(false); - this.starterIconsCursorIndex = Math.min(onScreenCurrentRow-2, this.starterSpecies.length - 1); + this.starterIconsCursorIndex = findClosestStarterIndex(this.cursorObj.y - 1, this.starterSpecies.length); this.moveStarterIconsCursor(this.starterIconsCursorIndex); + } else { + // at least one pokemon in team > from the bottom 2 rows, go to start run button this.cursorObj.setVisible(false); this.setSpecies(null); this.startCursorObj.setVisible(true); } success = true; } - } else { + } else if (numberOfStarters > 0) { + // LEFT from team > Go to closest filtered Pokemon + const closestRowIndex = findClosestStarterRow(this.starterIconsCursorIndex, onScreenNumberOfRows); this.starterIconsCursorObj.setVisible(false); this.cursorObj.setVisible(true); - success = this.setCursor(Math.min(onScreenFirstIndex + (this.starterIconsCursorIndex + 2) * 9 + 8,onScreenLastIndex)); // set last column + this.setCursor(Math.min(onScreenFirstIndex + closestRowIndex * 9 + 8, onScreenLastIndex)); + success = true; + } else { + // LEFT from team and no Pokemon in filter > do nothing + success = false; } break; case Button.RIGHT: @@ -1713,33 +1867,37 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (this.cursor % 9 < (currentRow < numOfRows - 1 ? 8 : (numberOfStarters - 1) % 9)) { success = this.setCursor(this.cursor + 1); } else { - // in right edge + // RIGHT from filtered Pokemon, on the right edge if (this.starterSpecies.length === 0) { - // just wrap around to the first column + // no selected starter in team > wrap around to the first column success = this.setCursor(this.cursor - Math.min(8, this.cursor % 9)); - } else if (onScreenCurrentRow < 3) { - // always to the first starter - this.cursorObj.setVisible(false); - this.starterIconsCursorIndex = 0; - this.moveStarterIconsCursor(this.starterIconsCursorIndex); + } else if (onScreenCurrentRow < 7) { + // at least one pokemon in team > for the first 7 rows, go to closest starter this.cursorObj.setVisible(false); - this.starterIconsCursorIndex = Math.min(onScreenCurrentRow-2, this.starterSpecies.length - 1); + this.starterIconsCursorIndex = findClosestStarterIndex(this.cursorObj.y - 1, this.starterSpecies.length); this.moveStarterIconsCursor(this.starterIconsCursorIndex); + } else { + // at least one pokemon in team > from the bottom 2 rows, go to start run button this.cursorObj.setVisible(false); this.setSpecies(null); this.startCursorObj.setVisible(true); } success = true; } - break; - } else { + } else if (numberOfStarters > 0) { + // RIGHT from team > Go to closest filtered Pokemon + const closestRowIndex = findClosestStarterRow(this.starterIconsCursorIndex, onScreenNumberOfRows); this.starterIconsCursorObj.setVisible(false); this.cursorObj.setVisible(true); - success = this.setCursor(Math.min(onScreenFirstIndex + (this.starterIconsCursorIndex + 2) * 9, onScreenLastIndex - (onScreenLastIndex % 9))); // set first column - break; + this.setCursor(Math.min(onScreenFirstIndex + closestRowIndex * 9, onScreenLastIndex - (onScreenLastIndex % 9))); + success = true; + } else { + // RIGHT from team and no Pokemon in filter > do nothing + success = false; } + break; } } } @@ -1766,19 +1924,17 @@ export default class StarterSelectUiHandler extends MessageUiHandler { return [isDupe, removeIndex]; } - addToParty(species: PokemonSpecies) { - const cursorObj = this.starterCursorObjs[this.starterSpecies.length]; - cursorObj.setVisible(true); - cursorObj.setPosition(this.cursorObj.x, this.cursorObj.y); - const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor); + addToParty(species: PokemonSpecies, dexAttr: bigint, abilityIndex: integer, nature: Nature, moveset: StarterMoveset) { + const props = this.scene.gameData.getSpeciesDexAttrProps(species, dexAttr); this.starterIcons[this.starterSpecies.length].setTexture(species.getIconAtlasKey(props.formIndex, props.shiny, props.variant)); this.starterIcons[this.starterSpecies.length].setFrame(species.getIconId(props.female, props.formIndex, props.shiny, props.variant)); this.checkIconId(this.starterIcons[this.starterSpecies.length], species, props.female, props.formIndex, props.shiny, props.variant); + this.starterSpecies.push(species); - this.starterAttr.push(this.dexAttrCursor); - this.starterAbilityIndexes.push(this.abilityCursor); - this.starterNatures.push(this.natureCursor as unknown as Nature); - this.starterMovesets.push(this.starterMoveset.slice(0) as StarterMoveset); + this.starterAttr.push(dexAttr); + this.starterAbilityIndexes.push(abilityIndex); + this.starterNatures.push(nature); + this.starterMovesets.push(moveset); if (this.speciesLoaded.get(species.speciesId)) { getPokemonSpeciesForm(species.speciesId, props.formIndex).cry(this.scene); } @@ -1926,16 +2082,34 @@ export default class StarterSelectUiHandler extends MessageUiHandler { updateStarters = () => { this.scrollCursor = 0; this.filteredStarterContainers = []; + this.validStarterContainers = []; this.pokerusCursorObjs.forEach(cursor => cursor.setVisible(false)); this.starterCursorObjs.forEach(cursor => cursor.setVisible(false)); this.filterBar.updateFilterLabels(); + // pre filter for challenges + if (this.scene.gameMode.modeId === GameModes.CHALLENGE) { + this.starterContainers.forEach(container => { + const isValidForChallenge = new Utils.BooleanHolder(true); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, container.species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(container.species, this.scene.gameData.getSpeciesDefaultDexAttr(container.species, false, true)), true); + if (isValidForChallenge.value) { + this.validStarterContainers.push(container); + } else { + container.setVisible(false); + } + }); + } else { + this.validStarterContainers = this.starterContainers; + } + // filter - this.starterContainer.forEach(container => { + this.validStarterContainers.forEach(container => { container.setVisible(false); + container.cost = this.scene.gameData.getSpeciesStarterValue(container.species.speciesId); + // First, ensure you have the caught attributes for the species else default to bigint 0 const caughtVariants = this.scene.gameData.dexData[container.species.speciesId]?.caughtAttr || BigInt(0); @@ -1946,43 +2120,83 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const isCaught = !!(caughtVariants & DexAttr.NON_SHINY); const isUncaught = !isCaught && !isVariantCaught && !isVariant2Caught && !isVariant3Caught; const isPassiveUnlocked = this.scene.gameData.starterData[container.species.speciesId].passiveAttr > 0; - - - const fitsGen = this.filterBar.getVals(DropDownColumn.GEN).includes(container.species.generation); - const fitsType = this.filterBar.getVals(DropDownColumn.TYPES).some(type => container.species.isOfType((type as number) - 1)); - const fitsShiny = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(variant => { - if (variant === "SHINY3") { - return isVariant3Caught; - } else if (variant === "SHINY2") { - return isVariant2Caught && !isVariant3Caught; - } else if (variant === "SHINY") { - return isVariantCaught && !isVariant2Caught && !isVariant3Caught; - } else if (variant === "NORMAL") { - return isCaught && !isVariantCaught && !isVariant2Caught && !isVariant3Caught; - } else if (variant === "UNCAUGHT") { - return isUncaught; - } - }); - const fitsPassive = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(variant => { - if (variant === "PASSIVEUNLOCKED") { - return isPassiveUnlocked; - } else if (variant === "PASSIVELOCKED") { - return !isPassiveUnlocked; - } - }); + const isCostReduced = this.scene.gameData.starterData[container.species.speciesId].valueReduction > 0; const isWin = this.scene.gameData.starterData[container.species.speciesId].classicWinCount > 0; const isNotWin = this.scene.gameData.starterData[container.species.speciesId].classicWinCount === 0; const isUndefined = this.scene.gameData.starterData[container.species.speciesId].classicWinCount === undefined; + const isHA = this.scene.gameData.starterData[container.species.speciesId].abilityAttr & AbilityAttr.ABILITY_HIDDEN; - const fitsWin = this.filterBar.getVals(DropDownColumn.WIN).some(win => { - if (win === "WIN") { - return isWin; - } else if (win === "NOTWIN") { - return isNotWin || isUndefined; + const fitsGen = this.filterBar.getVals(DropDownColumn.GEN).includes(container.species.generation); + + const fitsType = this.filterBar.getVals(DropDownColumn.TYPES).some(type => container.species.isOfType((type as number) - 1)); + + const fitsCaught = this.filterBar.getVals(DropDownColumn.CAUGHT).some(caught => { + if (caught === "SHINY3") { + return isVariant3Caught; + } else if (caught === "SHINY2") { + return isVariant2Caught && !isVariant3Caught; + } else if (caught === "SHINY") { + return isVariantCaught && !isVariant2Caught && !isVariant3Caught; + } else if (caught === "NORMAL") { + return isCaught && !isVariantCaught && !isVariant2Caught && !isVariant3Caught; + } else if (caught === "UNCAUGHT") { + return isUncaught; } }); - if (fitsGen && fitsType && fitsShiny && fitsPassive && fitsWin) { + const fitsPassive = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => { + if (unlocks.val === "PASSIVE" && unlocks.state === DropDownState.ON) { + return isPassiveUnlocked; + } else if (unlocks.val === "PASSIVE" && unlocks.state === DropDownState.EXCLUDE) { + return !isPassiveUnlocked; + } else if (unlocks.val === "PASSIVE" && unlocks.state === DropDownState.OFF) { + return true; + } + }); + + const fitsCostReduction = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => { + if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.ON) { + return isCostReduced; + } else if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.EXCLUDE) { + return !isCostReduced; + } else if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.OFF) { + return true; + } + }); + + const fitsWin = this.filterBar.getVals(DropDownColumn.MISC).some(misc => { + if (container.species.speciesId < 10) { + } + if (misc.val === "WIN" && misc.state === DropDownState.ON) { + return isWin; + } else if (misc.val === "WIN" && misc.state === DropDownState.EXCLUDE) { + return isNotWin || isUndefined; + } else if (misc.val === "WIN" && misc.state === DropDownState.OFF) { + return true; + } + }); + + const fitsHA = this.filterBar.getVals(DropDownColumn.MISC).some(misc => { + if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.ON) { + return isHA; + } else if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.EXCLUDE) { + return !isHA; + } else if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.OFF) { + return true; + } + }); + + const fitsPokerus = this.filterBar.getVals(DropDownColumn.MISC).some(misc => { + if (misc.val === "POKERUS" && misc.state === DropDownState.ON) { + return this.pokerusSpecies.includes(container.species); + } else if (misc.val === "POKERUS" && misc.state === DropDownState.EXCLUDE) { + return !this.pokerusSpecies.includes(container.species); + } else if (misc.val === "POKERUS" && misc.state === DropDownState.OFF) { + return true; + } + }); + + if (fitsGen && fitsType && fitsCaught && fitsPassive && fitsCostReduction && fitsWin && fitsHA && fitsPokerus) { this.filteredStarterContainers.push(container); } }); @@ -2018,8 +2232,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { }; updateScroll = () => { - const perRow = 9; + const maxColumns = 9; const maxRows = 9; + const onScreenFirstIndex = this.scrollCursor * maxColumns; + const onScreenLastIndex = Math.min(this.filteredStarterContainers.length - 1, onScreenFirstIndex + maxRows * maxColumns -1); this.starterSelectScrollBar.setPage(this.scrollCursor); @@ -2027,69 +2243,70 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.filteredStarterContainers.forEach((container, i) => { const pos = calcStarterPosition(i, this.scrollCursor); container.setPosition(pos.x, pos.y); - - if (i < (maxRows + this.scrollCursor) * perRow && i >= this.scrollCursor * perRow) { - container.setVisible(true); - } else { + if (i < onScreenFirstIndex || i > onScreenLastIndex) { container.setVisible(false); - } - if (this.pokerusSpecies.includes(container.species)) { - this.pokerusCursorObjs[pokerusCursorIndex].setPosition(pos.x - 1, pos.y + 1); - - if (i < (maxRows + this.scrollCursor) * perRow && i >= this.scrollCursor * perRow) { - this.pokerusCursorObjs[pokerusCursorIndex].setVisible(true); - } else { + if (this.pokerusSpecies.includes(container.species)) { + this.pokerusCursorObjs[pokerusCursorIndex].setPosition(pos.x - 1, pos.y + 1); this.pokerusCursorObjs[pokerusCursorIndex].setVisible(false); + pokerusCursorIndex++; } - pokerusCursorIndex++; - } - if (this.starterSpecies.includes(container.species)) { - this.starterCursorObjs[this.starterSpecies.indexOf(container.species)].setPosition(pos.x - 1, pos.y + 1); - - if (i < (maxRows + this.scrollCursor) * perRow && i >= this.scrollCursor * perRow) { - this.starterCursorObjs[this.starterSpecies.indexOf(container.species)].setVisible(true); - } else { + if (this.starterSpecies.includes(container.species)) { + this.starterCursorObjs[this.starterSpecies.indexOf(container.species)].setPosition(pos.x - 1, pos.y + 1); this.starterCursorObjs[this.starterSpecies.indexOf(container.species)].setVisible(false); } - } + return; + } else { + container.setVisible(true); - const speciesId = container.species.speciesId; - this.updateStarterValueLabel(container); - - container.label.setVisible(true); - const speciesVariants = speciesId && this.scene.gameData.dexData[speciesId].caughtAttr & DexAttr.SHINY - ? [ DexAttr.DEFAULT_VARIANT, DexAttr.VARIANT_2, DexAttr.VARIANT_3 ].filter(v => !!(this.scene.gameData.dexData[speciesId].caughtAttr & v)) - : []; - for (let v = 0; v < 3; v++) { - const hasVariant = speciesVariants.length > v; - container.shinyIcons[v].setVisible(hasVariant); - if (hasVariant) { - container.shinyIcons[v].setTint(getVariantTint(speciesVariants[v] === DexAttr.DEFAULT_VARIANT ? 0 : speciesVariants[v] === DexAttr.VARIANT_2 ? 1 : 2)); - } - } - - container.starterPassiveBgs.setVisible(!!this.scene.gameData.starterData[speciesId].passiveAttr); - container.hiddenAbilityIcon.setVisible(!!this.scene.gameData.dexData[speciesId].caughtAttr && !!(this.scene.gameData.starterData[speciesId].abilityAttr & 4)); - container.classicWinIcon.setVisible(this.scene.gameData.starterData[speciesId].classicWinCount > 0); - - // 'Candy Icon' mode - if (this.scene.candyUpgradeDisplay === 0) { - - if (!starterColors[speciesId]) { - // Default to white if no colors are found - starterColors[speciesId] = [ "ffffff", "ffffff" ]; + if (this.pokerusSpecies.includes(container.species)) { + this.pokerusCursorObjs[pokerusCursorIndex].setPosition(pos.x - 1, pos.y + 1); + this.pokerusCursorObjs[pokerusCursorIndex].setVisible(true); + pokerusCursorIndex++; } - // Set the candy colors - container.candyUpgradeIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(starterColors[speciesId][0]))); - container.candyUpgradeOverlayIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(starterColors[speciesId][1]))); + if (this.starterSpecies.includes(container.species)) { + this.starterCursorObjs[this.starterSpecies.indexOf(container.species)].setPosition(pos.x - 1, pos.y + 1); + this.starterCursorObjs[this.starterSpecies.indexOf(container.species)].setVisible(true); + } - this.setUpgradeIcon(container); - } else if (this.scene.candyUpgradeDisplay === 1) { - container.candyUpgradeIcon.setVisible(false); - container.candyUpgradeOverlayIcon.setVisible(false); + const speciesId = container.species.speciesId; + this.updateStarterValueLabel(container); + + container.label.setVisible(true); + const speciesVariants = speciesId && this.scene.gameData.dexData[speciesId].caughtAttr & DexAttr.SHINY + ? [ DexAttr.DEFAULT_VARIANT, DexAttr.VARIANT_2, DexAttr.VARIANT_3 ].filter(v => !!(this.scene.gameData.dexData[speciesId].caughtAttr & v)) + : []; + for (let v = 0; v < 3; v++) { + const hasVariant = speciesVariants.length > v; + container.shinyIcons[v].setVisible(hasVariant); + if (hasVariant) { + container.shinyIcons[v].setTint(getVariantTint(speciesVariants[v] === DexAttr.DEFAULT_VARIANT ? 0 : speciesVariants[v] === DexAttr.VARIANT_2 ? 1 : 2)); + } + } + + container.starterPassiveBgs.setVisible(!!this.scene.gameData.starterData[speciesId].passiveAttr); + container.hiddenAbilityIcon.setVisible(!!this.scene.gameData.dexData[speciesId].caughtAttr && !!(this.scene.gameData.starterData[speciesId].abilityAttr & 4)); + container.classicWinIcon.setVisible(this.scene.gameData.starterData[speciesId].classicWinCount > 0); + + // 'Candy Icon' mode + if (this.scene.candyUpgradeDisplay === 0) { + + if (!starterColors[speciesId]) { + // Default to white if no colors are found + starterColors[speciesId] = [ "ffffff", "ffffff" ]; + } + + // Set the candy colors + container.candyUpgradeIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(starterColors[speciesId][0]))); + container.candyUpgradeOverlayIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(starterColors[speciesId][1]))); + + this.setUpgradeIcon(container); + } else if (this.scene.candyUpgradeDisplay === 1) { + container.candyUpgradeIcon.setVisible(false); + container.candyUpgradeOverlayIcon.setVisible(false); + } } }); }; @@ -2129,31 +2346,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { return changed; } - getGenCursorWithScroll(): integer { - return undefined; - // return this.genCursor !== undefined - // ? this.genCursor + this.genScrollCursor - // : undefined; - } - - updateGenOptions(): void { - // let text = ""; - // for (let g = this.genScrollCursor; g <= this.genScrollCursor + 2; g++) { - // let optionText = ""; - // if (g === this.genScrollCursor && this.genScrollCursor) { - // optionText = "↑"; - // } else if (g === this.genScrollCursor + 2 && this.genScrollCursor < gens.length - 3) { - // optionText = "↓"; - // } else { - // optionText = i18next.t(`starterSelectUiHandler:gen${g + 1}`); - // } - // text += `${text ? "\n" : ""}${optionText}`; - // } - // this.genOptionsText.setText(text); - } - setFilterMode(filterMode: boolean): boolean { - // this.genCursorObj.setVisible(!filterMode); this.cursorObj.setVisible(!filterMode); this.filterBar.cursorObj.setVisible(filterMode); @@ -2256,12 +2449,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const dexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(this.lastSpecies, false, true); const props = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, dexAttr); const speciesIndex = this.allSpecies.indexOf(this.lastSpecies); - const lastSpeciesIcon = this.starterContainer[speciesIndex].icon; + const lastSpeciesIcon = this.starterContainers[speciesIndex].icon; this.checkIconId(lastSpeciesIcon, this.lastSpecies, props.female, props.formIndex, props.shiny, props.variant); this.iconAnimHandler.addOrUpdate(lastSpeciesIcon, PokemonIconAnimMode.NONE); // Resume the animation for the previously selected species - const icon = this.starterContainer[speciesIndex].icon; + const icon = this.starterContainers[speciesIndex].icon; this.scene.tweens.getTweensOf(icon).forEach(tween => tween.resume()); } @@ -2357,7 +2550,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { // Pause the animation when the species is selected const speciesIndex = this.allSpecies.indexOf(species); - const icon = this.starterContainer[speciesIndex].icon; + const icon = this.starterContainers[speciesIndex].icon; if (this.isUpgradeAnimationEnabled()) { this.scene.tweens.getTweensOf(icon).forEach(tween => tween.pause()); @@ -2369,8 +2562,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { // Initiates the small up and down idle animation this.iconAnimHandler.addOrUpdate(icon, PokemonIconAnimMode.PASSIVE); - let starterIndex = -1; - starterIndex = this.starterSpecies.indexOf(species); + const starterIndex = this.starterSpecies.indexOf(species); let props: DexAttrProps; @@ -2523,8 +2715,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonNumberText.setShadowColor(this.getTextColor(shiny ? TextStyle.SUMMARY_GOLD : TextStyle.SUMMARY, true)); if (forSeen ? this.speciesStarterDexEntry?.seenAttr : this.speciesStarterDexEntry?.caughtAttr) { - let starterIndex = -1; - starterIndex = this.starterSpecies.indexOf(species); + const starterIndex = this.starterSpecies.indexOf(species); if (starterIndex > -1) { this.starterAttr[starterIndex] = this.dexAttrCursor; @@ -2596,7 +2787,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.speciesStarterMoves.push(...levelMoves.filter(lm => lm[0] > 0 && lm[0] <= 5).map(lm => lm[1])); if (speciesEggMoves.hasOwnProperty(species.speciesId)) { for (let em = 0; em < 4; em++) { - if (this.scene.gameData.starterData[species.speciesId].eggMoves & Math.pow(2, em)) { + if (this.scene.gameData.starterData[species.speciesId].eggMoves & (1 << em)) { this.speciesStarterMoves.push(speciesEggMoves[species.speciesId][em]); } } @@ -2608,7 +2799,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { ? speciesMoveData as StarterMoveset : (speciesMoveData as StarterFormMoveData)[formIndex] : null; - const availableStarterMoves = this.speciesStarterMoves.concat(speciesEggMoves.hasOwnProperty(species.speciesId) ? speciesEggMoves[species.speciesId].filter((_, em: integer) => this.scene.gameData.starterData[species.speciesId].eggMoves & Math.pow(2, em)) : []); + const availableStarterMoves = this.speciesStarterMoves.concat(speciesEggMoves.hasOwnProperty(species.speciesId) ? speciesEggMoves[species.speciesId].filter((_, em: integer) => this.scene.gameData.starterData[species.speciesId].eggMoves & (1 << em)) : []); this.starterMoveset = (moveData || (this.speciesStarterMoves.slice(0, 4) as StarterMoveset)).filter(m => availableStarterMoves.find(sm => sm === m)) as StarterMoveset; // Consolidate move data if it contains an incompatible move if (this.starterMoveset.length < 4 && this.starterMoveset.length < availableStarterMoves.length) { @@ -2665,7 +2856,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { for (let em = 0; em < 4; em++) { const eggMove = hasEggMoves ? allMoves[speciesEggMoves[species.speciesId][em]] : null; - const eggMoveUnlocked = eggMove && this.scene.gameData.starterData[species.speciesId].eggMoves & Math.pow(2, em); + const eggMoveUnlocked = eggMove && this.scene.gameData.starterData[species.speciesId].eggMoves & (1 << em); this.pokemonEggMoveBgs[em].setFrame(Type[eggMove ? eggMove.type : Type.UNKNOWN].toString().toLowerCase()); this.pokemonEggMoveLabels[em].setText(eggMove && eggMoveUnlocked ? eggMove.name : "???"); } @@ -2706,6 +2897,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const props = this.scene.gameData.getSpeciesDexAttrProps(species, currentDexAttr); this.starterIcons[s].setTexture(species.getIconAtlasKey(props.formIndex, props.shiny, props.variant)); this.starterIcons[s].setFrame(species.getIconId(props.female, props.formIndex, props.shiny, props.variant)); + this.checkIconId(this.starterIcons[s], species, props.female, props.formIndex, props.shiny, props.variant); if (s >= index) { this.starterCursorObjs[s].setPosition(this.starterCursorObjs[s + 1].x, this.starterCursorObjs[s + 1].y); this.starterCursorObjs[s].setVisible(this.starterCursorObjs[s + 1].visible); @@ -2720,8 +2912,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (this.starterSpecies.length > 0) { this.starterIconsCursorIndex--; } else { + // No more Pokemon selected, go back to filters this.starterIconsCursorObj.setVisible(false); this.setSpecies(null); + this.filterBarCursor = Math.max(1, this.filterBar.numFilters - 1); this.setFilterMode(true); } } @@ -2795,7 +2989,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { /** Used to detect if this pokemon is registered in starter */ const speciesStarterDexEntry = this.scene.gameData.dexData[this.allSpecies[s].speciesId]; /** {@linkcode Phaser.GameObjects.Sprite} object of Pokémon for setting the alpha value */ - const speciesSprite = this.starterContainer[s].icon; + const speciesSprite = this.starterContainers[s].icon; /** * If remainValue greater than or equal pokemon species and the pokemon is legal for this challenge, the user can select. @@ -2844,6 +3038,32 @@ export default class StarterSelectUiHandler extends MessageUiHandler { return true; } + tryExit(): boolean { + this.blockInput = true; + const ui = this.getUi(); + + const cancel = () => { + ui.setMode(Mode.STARTER_SELECT); + this.clearText(); + this.blockInput = false; + }; + ui.showText(i18next.t("starterSelectUiHandler:confirmExit"), null, () => { + ui.setModeWithoutClear(Mode.CONFIRM, () => { + ui.setMode(Mode.STARTER_SELECT); + this.scene.clearPhaseQueue(); + if (this.scene.gameMode.isChallenge) { + this.scene.pushPhase(new SelectChallengePhase(this.scene)); + } else { + this.scene.pushPhase(new TitlePhase(this.scene)); + } + this.clearText(); + this.scene.getCurrentPhase().end(); + }, cancel, null, null, 19); + }); + + return true; + } + tryStart(manualTrigger: boolean = false): boolean { if (!this.starterSpecies.length) { return false; @@ -2902,7 +3122,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { for (let s = 0; s < this.starterSpecies.length; s++) { const isValidForChallenge = new Utils.BooleanHolder(true); const species = this.starterSpecies[s]; - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor), !!(this.starterSpecies.length), false, false); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor), this.starterSpecies.length !== 0, false, false); canStart = canStart || isValidForChallenge.value; } return canStart; diff --git a/src/ui/ui.ts b/src/ui/ui.ts index ae1bc10a74f..6061baf3b4a 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -235,8 +235,8 @@ export default class UI extends Phaser.GameObjects.Container { (this.scene as BattleScene).uiContainer.add(this.tooltipContainer); } - getHandler(): UiHandler { - return this.handlers[this.mode]; + getHandler(): H { + return this.handlers[this.mode] as H; } getMessageHandler(): BattleMessageUiHandler { @@ -536,4 +536,8 @@ export default class UI extends Phaser.GameObjects.Container { this.revertMode().then(success => Utils.executeIf(success, this.revertModes).then(() => resolve())); }); } + + public getModeChain(): Mode[] { + return this.modeChain; + } } diff --git a/src/utils.ts b/src/utils.ts index 467d7601d38..ede0a4bd78a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -165,40 +165,20 @@ export function getPlayTimeString(totalSeconds: integer): string { return `${days.padStart(2, "0")}:${hours.padStart(2, "0")}:${minutes.padStart(2, "0")}:${seconds.padStart(2, "0")}`; } -export function binToDec(input: string): integer { - const place: integer[] = []; - const binary: string[] = []; - - let decimalNum = 0; - - for (let i = 0; i < input.length; i++) { - binary.push(input[i]); - place.push(Math.pow(2, i)); - decimalNum += place[i] * parseInt(binary[i]); - } - - return decimalNum; -} - -export function decToBin(input: integer): string { - let bin = ""; - let intNum = input; - while (intNum > 0) { - bin = intNum % 2 ? `1${bin}` : `0${bin}`; - intNum = Math.floor(intNum * 0.5); - } - - return bin; -} - -export function getIvsFromId(id: integer): integer[] { +/** + * Generates IVs from a given {@linkcode id} by extracting 5 bits at a time + * starting from the least significant bit up to the 30th most significant bit. + * @param id 32-bit number + * @returns An array of six numbers corresponding to 5-bit chunks from {@linkcode id} + */ +export function getIvsFromId(id: number): number[] { return [ - binToDec(decToBin(id).substring(0, 5)), - binToDec(decToBin(id).substring(5, 10)), - binToDec(decToBin(id).substring(10, 15)), - binToDec(decToBin(id).substring(15, 20)), - binToDec(decToBin(id).substring(20, 25)), - binToDec(decToBin(id).substring(25, 30)) + (id & 0x3E000000) >>> 25, + (id & 0x01F00000) >>> 20, + (id & 0x000F8000) >>> 15, + (id & 0x00007C00) >>> 10, + (id & 0x000003E0) >>> 5, + (id & 0x0000001F) ]; } diff --git a/vite.config.ts b/vite.config.ts index 6dce1272ee6..f5c95aa56bd 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,8 +1,12 @@ import { defineConfig, loadEnv } from 'vite'; import tsconfigPaths from 'vite-tsconfig-paths'; +import { minifyJsonPlugin } from "./src/plugins/vite/vite-minify-json-plugin"; export const defaultConfig = { - plugins: [tsconfigPaths() as any], + plugins: [ + tsconfigPaths() as any, + minifyJsonPlugin(["images", "battle-anims"], true) + ], clearScreen: false, build: { minify: 'esbuild' as const,