Merge branch 'beta' into substitute
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -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.**
|
|
||||||
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
|
|
||||||
|
|
||||||
**Describe the Feature**
|
|
||||||
<!-- 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 -->
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
<!-- Add any other context or screenshots about the feature request here. -->
|
|
39
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@ -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
|
5
.github/pull_request_template.md
vendored
@ -5,12 +5,12 @@
|
|||||||
## What are the changes?
|
## What are the changes?
|
||||||
<!-- Summarize what are the changes from a user perspective on the application -->
|
<!-- Summarize what are the changes from a user perspective on the application -->
|
||||||
|
|
||||||
## Why am I doing these changes?
|
## Why am I doing these changes the user will see?
|
||||||
<!-- Explain why you decided to introduce these changes -->
|
<!-- Explain why you decided to introduce these changes -->
|
||||||
<!-- Does it come from an issue or another PR? Please link it -->
|
<!-- Does it come from an issue or another PR? Please link it -->
|
||||||
<!-- Explain why you believe this can enhance user experience -->
|
<!-- Explain why you believe this can enhance user experience -->
|
||||||
|
|
||||||
## What did change?
|
## What are the changes from a developer perspective?
|
||||||
<!-- Explicitly state what are the changes introduced by the PR -->
|
<!-- Explicitly state what are the changes introduced by the PR -->
|
||||||
<!-- You can make use of a comparison between what was the state before and after your PR changes -->
|
<!-- You can make use of a comparison between what was the state before and after your PR changes -->
|
||||||
|
|
||||||
@ -30,6 +30,7 @@
|
|||||||
- [ ] The PR is self-contained and cannot be split into smaller PRs?
|
- [ ] The PR is self-contained and cannot be split into smaller PRs?
|
||||||
- [ ] Have I provided a clear explanation of the changes?
|
- [ ] Have I provided a clear explanation of the changes?
|
||||||
- [ ] Have I considered writing automated tests for the issue?
|
- [ ] 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)?
|
- [ ] Have I tested the changes (manually)?
|
||||||
- [ ] Are all unit tests still passing? (`npm run test`)
|
- [ ] Are all unit tests still passing? (`npm run test`)
|
||||||
- [ ] Are the changes visual?
|
- [ ] Are the changes visual?
|
||||||
|
224
docs/enemy-ai.md
Normal file
@ -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)**.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
%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:
|
||||||
|
|
||||||
|

|
||||||
|
2. Compute the stat-based multiplier:
|
||||||
|
|
||||||
|

|
||||||
|
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:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|

|
||||||
|
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.
|
BIN
public/audio/bgm/battle_hoenn_champion_g6.mp3
Normal file
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 7.3 KiB |
@ -1,272 +1,140 @@
|
|||||||
{
|
{
|
||||||
"textures": [
|
"textures":[
|
||||||
{
|
{
|
||||||
"image": "1001.png",
|
"image": "1001.png",
|
||||||
"format": "RGBA8888",
|
"format": "RGBA8888",
|
||||||
"size": {
|
"size": { "w": 161, "h": 157 },
|
||||||
"w": 237,
|
"scale": 1,
|
||||||
"h": 237
|
"frames": [
|
||||||
},
|
{
|
||||||
"scale": 1,
|
"filename": "0001.png",
|
||||||
"frames": [
|
"rotated": false,
|
||||||
{
|
"trimmed": true,
|
||||||
"filename": "0001.png",
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"rotated": false,
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 },
|
||||||
"trimmed": false,
|
"frame": { "x": 80, "y": 78, "w": 79, "h": 79 }
|
||||||
"sourceSize": {
|
},
|
||||||
"w": 79,
|
{
|
||||||
"h": 79
|
"filename": "0002.png",
|
||||||
},
|
"rotated": false,
|
||||||
"spriteSourceSize": {
|
"trimmed": true,
|
||||||
"x": 0,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"y": 0,
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 },
|
||||||
"w": 79,
|
"frame": { "x": 80, "y": 78, "w": 79, "h": 79 }
|
||||||
"h": 79
|
},
|
||||||
},
|
{
|
||||||
"frame": {
|
"filename": "0003.png",
|
||||||
"x": 0,
|
"rotated": false,
|
||||||
"y": 0,
|
"trimmed": true,
|
||||||
"w": 79,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"h": 79
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 },
|
||||||
}
|
"frame": { "x": 80, "y": 78, "w": 79, "h": 79 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "0002.png",
|
"filename": "0004.png",
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"sourceSize": {
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"w": 79,
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 },
|
||||||
"h": 79
|
"frame": { "x": 80, "y": 78, "w": 79, "h": 79 }
|
||||||
},
|
},
|
||||||
"spriteSourceSize": {
|
{
|
||||||
"x": 0,
|
"filename": "0005.png",
|
||||||
"y": 1,
|
"rotated": false,
|
||||||
"w": 79,
|
"trimmed": true,
|
||||||
"h": 78
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
},
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 },
|
||||||
"frame": {
|
"frame": { "x": 0, "y": 79, "w": 80, "h": 78 }
|
||||||
"x": 79,
|
},
|
||||||
"y": 0,
|
{
|
||||||
"w": 79,
|
"filename": "0006.png",
|
||||||
"h": 78
|
"rotated": false,
|
||||||
}
|
"trimmed": true,
|
||||||
},
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
{
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 },
|
||||||
"filename": "0012.png",
|
"frame": { "x": 0, "y": 79, "w": 80, "h": 78 }
|
||||||
"rotated": false,
|
},
|
||||||
"trimmed": true,
|
{
|
||||||
"sourceSize": {
|
"filename": "0007.png",
|
||||||
"w": 79,
|
"rotated": false,
|
||||||
"h": 79
|
"trimmed": true,
|
||||||
},
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"spriteSourceSize": {
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 },
|
||||||
"x": 0,
|
"frame": { "x": 0, "y": 79, "w": 80, "h": 78 }
|
||||||
"y": 1,
|
},
|
||||||
"w": 79,
|
{
|
||||||
"h": 78
|
"filename": "0008.png",
|
||||||
},
|
"rotated": false,
|
||||||
"frame": {
|
"trimmed": true,
|
||||||
"x": 79,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"y": 0,
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 },
|
||||||
"w": 79,
|
"frame": { "x": 0, "y": 79, "w": 80, "h": 78 }
|
||||||
"h": 78
|
},
|
||||||
}
|
{
|
||||||
},
|
"filename": "0009.png",
|
||||||
{
|
"rotated": false,
|
||||||
"filename": "0003.png",
|
"trimmed": true,
|
||||||
"rotated": false,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"trimmed": true,
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 },
|
||||||
"sourceSize": {
|
"frame": { "x": 80, "y": 0, "w": 81, "h": 78 }
|
||||||
"w": 79,
|
},
|
||||||
"h": 79
|
{
|
||||||
},
|
"filename": "0010.png",
|
||||||
"spriteSourceSize": {
|
"rotated": false,
|
||||||
"x": 0,
|
"trimmed": true,
|
||||||
"y": 3,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"w": 79,
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 },
|
||||||
"h": 76
|
"frame": { "x": 80, "y": 0, "w": 81, "h": 78 }
|
||||||
},
|
},
|
||||||
"frame": {
|
{
|
||||||
"x": 158,
|
"filename": "0011.png",
|
||||||
"y": 0,
|
"rotated": false,
|
||||||
"w": 79,
|
"trimmed": true,
|
||||||
"h": 76
|
"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,
|
"filename": "0012.png",
|
||||||
"trimmed": true,
|
"rotated": false,
|
||||||
"sourceSize": {
|
"trimmed": true,
|
||||||
"w": 79,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"h": 79
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 },
|
||||||
},
|
"frame": { "x": 80, "y": 0, "w": 81, "h": 78 }
|
||||||
"spriteSourceSize": {
|
},
|
||||||
"x": 0,
|
{
|
||||||
"y": 3,
|
"filename": "0013.png",
|
||||||
"w": 79,
|
"rotated": false,
|
||||||
"h": 76
|
"trimmed": true,
|
||||||
},
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"frame": {
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 },
|
||||||
"x": 158,
|
"frame": { "x": 0, "y": 0, "w": 80, "h": 79 }
|
||||||
"y": 0,
|
},
|
||||||
"w": 79,
|
{
|
||||||
"h": 76
|
"filename": "0014.png",
|
||||||
}
|
"rotated": false,
|
||||||
},
|
"trimmed": true,
|
||||||
{
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"filename": "0004.png",
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 },
|
||||||
"rotated": false,
|
"frame": { "x": 0, "y": 0, "w": 80, "h": 79 }
|
||||||
"trimmed": true,
|
},
|
||||||
"sourceSize": {
|
{
|
||||||
"w": 79,
|
"filename": "0015.png",
|
||||||
"h": 79
|
"rotated": false,
|
||||||
},
|
"trimmed": true,
|
||||||
"spriteSourceSize": {
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"x": 0,
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 },
|
||||||
"y": 4,
|
"frame": { "x": 0, "y": 0, "w": 80, "h": 79 }
|
||||||
"w": 79,
|
},
|
||||||
"h": 75
|
{
|
||||||
},
|
"filename": "0016.png",
|
||||||
"frame": {
|
"rotated": false,
|
||||||
"x": 158,
|
"trimmed": true,
|
||||||
"y": 76,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"w": 79,
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 },
|
||||||
"h": 75
|
"frame": { "x": 0, "y": 0, "w": 80, "h": 79 }
|
||||||
}
|
}
|
||||||
},
|
]}],
|
||||||
{
|
"meta": {"app": "https://www.aseprite.org/","version": "1.3.7-x64"
|
||||||
"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$"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.4 KiB |
@ -1,272 +1,140 @@
|
|||||||
{
|
{
|
||||||
"textures": [
|
"textures":[
|
||||||
{
|
{
|
||||||
"image": "1001.png",
|
"image": "1001.png",
|
||||||
"format": "RGBA8888",
|
"format": "RGBA8888",
|
||||||
"size": {
|
"size": { "w": 161, "h": 157 },
|
||||||
"w": 237,
|
"scale": 1,
|
||||||
"h": 237
|
"frames": [
|
||||||
},
|
{
|
||||||
"scale": 1,
|
"filename": "0001.png",
|
||||||
"frames": [
|
"rotated": false,
|
||||||
{
|
"trimmed": true,
|
||||||
"filename": "0001.png",
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"rotated": false,
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 },
|
||||||
"trimmed": false,
|
"frame": { "x": 80, "y": 78, "w": 79, "h": 79 }
|
||||||
"sourceSize": {
|
},
|
||||||
"w": 79,
|
{
|
||||||
"h": 79
|
"filename": "0002.png",
|
||||||
},
|
"rotated": false,
|
||||||
"spriteSourceSize": {
|
"trimmed": true,
|
||||||
"x": 0,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"y": 0,
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 },
|
||||||
"w": 79,
|
"frame": { "x": 80, "y": 78, "w": 79, "h": 79 }
|
||||||
"h": 79
|
},
|
||||||
},
|
{
|
||||||
"frame": {
|
"filename": "0003.png",
|
||||||
"x": 0,
|
"rotated": false,
|
||||||
"y": 0,
|
"trimmed": true,
|
||||||
"w": 79,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"h": 79
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 },
|
||||||
}
|
"frame": { "x": 80, "y": 78, "w": 79, "h": 79 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "0002.png",
|
"filename": "0004.png",
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"sourceSize": {
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"w": 79,
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 79 },
|
||||||
"h": 79
|
"frame": { "x": 80, "y": 78, "w": 79, "h": 79 }
|
||||||
},
|
},
|
||||||
"spriteSourceSize": {
|
{
|
||||||
"x": 0,
|
"filename": "0005.png",
|
||||||
"y": 1,
|
"rotated": false,
|
||||||
"w": 79,
|
"trimmed": true,
|
||||||
"h": 78
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
},
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 },
|
||||||
"frame": {
|
"frame": { "x": 0, "y": 79, "w": 80, "h": 78 }
|
||||||
"x": 79,
|
},
|
||||||
"y": 0,
|
{
|
||||||
"w": 79,
|
"filename": "0006.png",
|
||||||
"h": 78
|
"rotated": false,
|
||||||
}
|
"trimmed": true,
|
||||||
},
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
{
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 },
|
||||||
"filename": "0012.png",
|
"frame": { "x": 0, "y": 79, "w": 80, "h": 78 }
|
||||||
"rotated": false,
|
},
|
||||||
"trimmed": true,
|
{
|
||||||
"sourceSize": {
|
"filename": "0007.png",
|
||||||
"w": 79,
|
"rotated": false,
|
||||||
"h": 79
|
"trimmed": true,
|
||||||
},
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"spriteSourceSize": {
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 },
|
||||||
"x": 0,
|
"frame": { "x": 0, "y": 79, "w": 80, "h": 78 }
|
||||||
"y": 1,
|
},
|
||||||
"w": 79,
|
{
|
||||||
"h": 78
|
"filename": "0008.png",
|
||||||
},
|
"rotated": false,
|
||||||
"frame": {
|
"trimmed": true,
|
||||||
"x": 79,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"y": 0,
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 80, "h": 78 },
|
||||||
"w": 79,
|
"frame": { "x": 0, "y": 79, "w": 80, "h": 78 }
|
||||||
"h": 78
|
},
|
||||||
}
|
{
|
||||||
},
|
"filename": "0009.png",
|
||||||
{
|
"rotated": false,
|
||||||
"filename": "0003.png",
|
"trimmed": true,
|
||||||
"rotated": false,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"trimmed": true,
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 },
|
||||||
"sourceSize": {
|
"frame": { "x": 80, "y": 0, "w": 81, "h": 78 }
|
||||||
"w": 79,
|
},
|
||||||
"h": 79
|
{
|
||||||
},
|
"filename": "0010.png",
|
||||||
"spriteSourceSize": {
|
"rotated": false,
|
||||||
"x": 0,
|
"trimmed": true,
|
||||||
"y": 3,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"w": 79,
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 },
|
||||||
"h": 76
|
"frame": { "x": 80, "y": 0, "w": 81, "h": 78 }
|
||||||
},
|
},
|
||||||
"frame": {
|
{
|
||||||
"x": 158,
|
"filename": "0011.png",
|
||||||
"y": 0,
|
"rotated": false,
|
||||||
"w": 79,
|
"trimmed": true,
|
||||||
"h": 76
|
"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,
|
"filename": "0012.png",
|
||||||
"trimmed": true,
|
"rotated": false,
|
||||||
"sourceSize": {
|
"trimmed": true,
|
||||||
"w": 79,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"h": 79
|
"spriteSourceSize": { "x": 0, "y": 1, "w": 81, "h": 78 },
|
||||||
},
|
"frame": { "x": 80, "y": 0, "w": 81, "h": 78 }
|
||||||
"spriteSourceSize": {
|
},
|
||||||
"x": 0,
|
{
|
||||||
"y": 3,
|
"filename": "0013.png",
|
||||||
"w": 79,
|
"rotated": false,
|
||||||
"h": 76
|
"trimmed": true,
|
||||||
},
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"frame": {
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 },
|
||||||
"x": 158,
|
"frame": { "x": 0, "y": 0, "w": 80, "h": 79 }
|
||||||
"y": 0,
|
},
|
||||||
"w": 79,
|
{
|
||||||
"h": 76
|
"filename": "0014.png",
|
||||||
}
|
"rotated": false,
|
||||||
},
|
"trimmed": true,
|
||||||
{
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"filename": "0004.png",
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 },
|
||||||
"rotated": false,
|
"frame": { "x": 0, "y": 0, "w": 80, "h": 79 }
|
||||||
"trimmed": true,
|
},
|
||||||
"sourceSize": {
|
{
|
||||||
"w": 79,
|
"filename": "0015.png",
|
||||||
"h": 79
|
"rotated": false,
|
||||||
},
|
"trimmed": true,
|
||||||
"spriteSourceSize": {
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"x": 0,
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 },
|
||||||
"y": 4,
|
"frame": { "x": 0, "y": 0, "w": 80, "h": 79 }
|
||||||
"w": 79,
|
},
|
||||||
"h": 75
|
{
|
||||||
},
|
"filename": "0016.png",
|
||||||
"frame": {
|
"rotated": false,
|
||||||
"x": 158,
|
"trimmed": true,
|
||||||
"y": 76,
|
"sourceSize": { "w": 81, "h": 79 },
|
||||||
"w": 79,
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 80, "h": 79 },
|
||||||
"h": 75
|
"frame": { "x": 0, "y": 0, "w": 80, "h": 79 }
|
||||||
}
|
}
|
||||||
},
|
]}],
|
||||||
{
|
"meta": {"app": "https://www.aseprite.org/","version": "1.3.7-x64"
|
||||||
"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$"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 303 B After Width: | Height: | Size: 303 B |
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 342 B |
BIN
public/images/pokemon/icons/9/1012-artisan.png
Normal file
After Width: | Height: | Size: 353 B |
BIN
public/images/pokemon/icons/9/1012s-artisan.png
Normal file
After Width: | Height: | Size: 359 B |
BIN
public/images/pokemon/icons/9/1013-masterpiece.png
Normal file
After Width: | Height: | Size: 346 B |
BIN
public/images/pokemon/icons/9/1013s-masterpiece.png
Normal file
After Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 846 B After Width: | Height: | Size: 846 B |
Before Width: | Height: | Size: 938 B After Width: | Height: | Size: 938 B |
Before Width: | Height: | Size: 510 B After Width: | Height: | Size: 510 B |
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 513 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 541 B After Width: | Height: | Size: 541 B |
Before Width: | Height: | Size: 557 B After Width: | Height: | Size: 557 B |
BIN
public/images/pokemon/icons/variant/7/778-busted_2.png
Normal file
After Width: | Height: | Size: 471 B |
BIN
public/images/pokemon/icons/variant/7/778-busted_3.png
Normal file
After Width: | Height: | Size: 482 B |
Before Width: | Height: | Size: 697 B After Width: | Height: | Size: 697 B |
Before Width: | Height: | Size: 661 B After Width: | Height: | Size: 661 B |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
41
public/images/trainer/aqua_admin_f.json
Normal file
@ -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$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/aqua_admin_f.png
Normal file
After Width: | Height: | Size: 865 B |
41
public/images/trainer/aqua_admin_m.json
Normal file
@ -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$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/aqua_admin_m.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
41
public/images/trainer/flare_admin_f.json
Normal file
@ -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$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/flare_admin_f.png
Normal file
After Width: | Height: | Size: 671 B |
41
public/images/trainer/flare_admin_m.json
Normal file
@ -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$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/flare_admin_m.png
Normal file
After Width: | Height: | Size: 789 B |
41
public/images/trainer/galactic_admin_f.json
Normal file
@ -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$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/galactic_admin_f.png
Normal file
After Width: | Height: | Size: 621 B |
41
public/images/trainer/galactic_admin_m.json
Normal file
@ -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$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/galactic_admin_m.png
Normal file
After Width: | Height: | Size: 689 B |
41
public/images/trainer/magma_admin_f.json
Normal file
@ -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$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/magma_admin_f.png
Normal file
After Width: | Height: | Size: 847 B |
41
public/images/trainer/magma_admin_m.json
Normal file
@ -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$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/magma_admin_m.png
Normal file
After Width: | Height: | Size: 845 B |
2120
public/images/trainer/plasma_sage.json
Normal file
BIN
public/images/trainer/plasma_sage.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
41
public/images/trainer/rocket_admin_f.json
Normal file
@ -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$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/rocket_admin_f.png
Normal file
After Width: | Height: | Size: 736 B |
41
public/images/trainer/rocket_admin_m.json
Normal file
@ -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$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/trainer/rocket_admin_m.png
Normal file
After Width: | Height: | Size: 645 B |
@ -1796,8 +1796,10 @@ export default class BattleScene extends SceneBase {
|
|||||||
return 13.950;
|
return 13.950;
|
||||||
case "battle_johto_champion": //B2W2 Johto Champion Battle
|
case "battle_johto_champion": //B2W2 Johto Champion Battle
|
||||||
return 23.498;
|
return 23.498;
|
||||||
case "battle_hoenn_champion": //B2W2 Hoenn Champion Battle
|
case "battle_hoenn_champion_g5": //B2W2 Hoenn Champion Battle
|
||||||
return 11.328;
|
return 11.328;
|
||||||
|
case "battle_hoenn_champion_g6": //ORAS Hoenn Champion Battle
|
||||||
|
return 11.762;
|
||||||
case "battle_sinnoh_champion": //B2W2 Sinnoh Champion Battle
|
case "battle_sinnoh_champion": //B2W2 Sinnoh Champion Battle
|
||||||
return 12.235;
|
return 12.235;
|
||||||
case "battle_champion_alder": //BW Unova Champion Battle
|
case "battle_champion_alder": //BW Unova Champion Battle
|
||||||
|
@ -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) => {
|
return (scene: BattleScene) => {
|
||||||
const rand = Utils.randSeedInt(trainerPool.length);
|
const rand = Utils.randSeedInt(trainerPool.length);
|
||||||
const trainerTypes: TrainerType[] = [];
|
const trainerTypes: TrainerType[] = [];
|
||||||
@ -435,11 +441,20 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): Get
|
|||||||
: trainerPoolEntry;
|
: trainerPoolEntry;
|
||||||
trainerTypes.push(trainerType);
|
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)
|
let trainerGender = TrainerVariant.DEFAULT;
|
||||||
if (trainerConfigs[trainerTypes[rand]].trainerTypeDouble && (trainerTypes[rand] === TrainerType.TATE || trainerTypes[rand] === TrainerType.LIZA)) {
|
if (randomGender) {
|
||||||
return new Trainer(scene, trainerTypes[rand], Utils.randSeedInt(3) ? TrainerVariant.DOUBLE : TrainerVariant.DEFAULT);
|
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
|
* Youngster/Lass on 5
|
||||||
* Rival on 8, 55, 95, 145, 195
|
* 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
|
* Evil leader on 115, 165
|
||||||
* E4 on 182, 184, 186, 188
|
* E4 on 182, 184, 186, 188
|
||||||
* Champion on 190
|
* Champion on 190
|
||||||
@ -462,21 +478,21 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
|||||||
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
||||||
[35]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[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)
|
[55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
.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)
|
[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)
|
[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)
|
[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)
|
[95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
.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)
|
[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)
|
[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)
|
[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 ])),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE ])),
|
||||||
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
|
@ -941,14 +941,19 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr {
|
|||||||
|
|
||||||
export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
|
export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
|
||||||
private weatherType: WeatherType;
|
private weatherType: WeatherType;
|
||||||
|
protected condition: PokemonDefendCondition | null;
|
||||||
|
|
||||||
constructor(weatherType: WeatherType) {
|
constructor(weatherType: WeatherType, condition?: PokemonDefendCondition) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.weatherType = weatherType;
|
this.weatherType = weatherType;
|
||||||
|
this.condition = condition ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
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()) {
|
if (!pokemon.scene.arena.weather?.isImmutable()) {
|
||||||
return pokemon.scene.arena.trySetWeather(this.weatherType, true);
|
return pokemon.scene.arena.trySetWeather(this.weatherType, true);
|
||||||
}
|
}
|
||||||
@ -5100,7 +5105,7 @@ export function initAbilities() {
|
|||||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.SOUND_BASED), 0.5)
|
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.SOUND_BASED), 0.5)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.SAND_SPIT, 8)
|
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)
|
new Ability(Abilities.ICE_SCALES, 8)
|
||||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.category === MoveCategory.SPECIAL, 0.5)
|
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.category === MoveCategory.SPECIAL, 0.5)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
|
@ -1836,7 +1836,7 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
|||||||
case BattlerTagType.RECEIVE_DOUBLE_DAMAGE:
|
case BattlerTagType.RECEIVE_DOUBLE_DAMAGE:
|
||||||
return new BattlerTag(tagType, BattlerTagLapseType.PRE_MOVE, 1, sourceMove);
|
return new BattlerTag(tagType, BattlerTagLapseType.PRE_MOVE, 1, sourceMove);
|
||||||
case BattlerTagType.BYPASS_SLEEP:
|
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:
|
case BattlerTagType.IGNORE_FLYING:
|
||||||
return new GroundedTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove);
|
return new GroundedTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove);
|
||||||
case BattlerTagType.ROOSTED:
|
case BattlerTagType.ROOSTED:
|
||||||
|
@ -406,14 +406,7 @@ export class SingleGenerationChallenge extends Challenge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false, checkEvolutions?: boolean): boolean {
|
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false, checkEvolutions?: boolean): boolean {
|
||||||
/**
|
const generations = [pokemon.generation];
|
||||||
* 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 checkPokemonEvolutions = checkEvolutions ?? true as boolean;
|
const checkPokemonEvolutions = checkEvolutions ?? true as boolean;
|
||||||
if (soft) {
|
if (soft) {
|
||||||
const speciesToCheck = [pokemon.speciesId];
|
const speciesToCheck = [pokemon.speciesId];
|
||||||
|
@ -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]: [
|
[TrainerType.MAGMA_GRUNT]: [
|
||||||
{
|
{
|
||||||
encounter: [
|
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]: [
|
[TrainerType.AQUA_GRUNT]: [
|
||||||
{
|
{
|
||||||
encounter: [
|
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]: [
|
[TrainerType.GALACTIC_GRUNT]: [
|
||||||
{
|
{
|
||||||
encounter: [
|
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]: [
|
[TrainerType.PLASMA_GRUNT]: [
|
||||||
{
|
{
|
||||||
encounter: [
|
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]: [
|
[TrainerType.FLARE_GRUNT]: [
|
||||||
{
|
{
|
||||||
encounter: [
|
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]: [
|
[TrainerType.ROCKET_BOSS_GIOVANNI_1]: [
|
||||||
{
|
{
|
||||||
encounter: [
|
encounter: [
|
||||||
|
@ -438,7 +438,7 @@ export const speciesEggMoves = {
|
|||||||
[Species.CHEWTLE]: [ Moves.FIRE_FANG, Moves.ACCELEROCK, Moves.SHELL_SMASH, Moves.FISHIOUS_REND ],
|
[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.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.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.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.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 ],
|
[Species.ARROKUDA]: [ Moves.SUPERCELL_SLAM, Moves.KNOCK_OFF, Moves.ICE_SPINNER, Moves.FILLET_AWAY ],
|
||||||
|
@ -2,7 +2,7 @@ import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./
|
|||||||
import { BattleEndPhase, MoveEndPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases";
|
import { BattleEndPhase, MoveEndPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases";
|
||||||
import { BattleStat, getBattleStatName } from "./battle-stat";
|
import { BattleStat, getBattleStatName } from "./battle-stat";
|
||||||
import { EncoreTag, HelpingHandTag, SemiInvulnerableTag, StockpilingTag, SubstituteTag, TypeBoostTag } from "./battler-tags";
|
import { EncoreTag, HelpingHandTag, SemiInvulnerableTag, StockpilingTag, SubstituteTag, 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 Pokemon, { AttackMoveResult, EnemyPokemon, HitResult, MoveResult, PlayerPokemon, PokemonMove, TurnMove } from "../field/pokemon";
|
||||||
import { StatusEffect, getStatusEffectHealText, isNonVolatileStatusEffect, getNonVolatileStatusEffects} from "./status-effect";
|
import { StatusEffect, getStatusEffectHealText, isNonVolatileStatusEffect, getNonVolatileStatusEffects} from "./status-effect";
|
||||||
import { getTypeResistances, Type } from "./type";
|
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 { 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 { allAbilities } from "./ability";
|
||||||
import { PokemonHeldItemModifier, BerryModifier, PreserveBerryModifier, PokemonMoveAccuracyBoosterModifier, AttackTypeBoosterModifier, PokemonMultiHitModifier } from "../modifier/modifier";
|
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 { Stat } from "./pokemon-stat";
|
||||||
import { TerrainType } from "./terrain";
|
import { TerrainType } from "./terrain";
|
||||||
import { SpeciesFormChangeActiveTrigger } from "./pokemon-forms";
|
|
||||||
import { ModifierPoolType } from "#app/modifier/modifier-type";
|
import { ModifierPoolType } from "#app/modifier/modifier-type";
|
||||||
import { Command } from "../ui/command-ui-handler";
|
import { Command } from "../ui/command-ui-handler";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
@ -1450,7 +1449,7 @@ export class HealAttr extends MoveEffectAttr {
|
|||||||
*/
|
*/
|
||||||
addHealPhase(target: Pokemon, healRatio: number) {
|
addHealPhase(target: Pokemon, healRatio: number) {
|
||||||
target.scene.unshiftPhase(new PokemonHealPhase(target.scene, target.getBattlerIndex(),
|
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 {
|
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
||||||
@ -1544,7 +1543,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);
|
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(),
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1879,13 +1878,10 @@ export class MultiHitAttr extends MoveAttr {
|
|||||||
}
|
}
|
||||||
case MultiHitType._2:
|
case MultiHitType._2:
|
||||||
return 2;
|
return 2;
|
||||||
break;
|
|
||||||
case MultiHitType._3:
|
case MultiHitType._3:
|
||||||
return 3;
|
return 3;
|
||||||
break;
|
|
||||||
case MultiHitType._10:
|
case MultiHitType._10:
|
||||||
return 10;
|
return 10;
|
||||||
break;
|
|
||||||
case MultiHitType.BEAT_UP:
|
case MultiHitType.BEAT_UP:
|
||||||
const party = user.isPlayer() ? user.scene.getParty() : user.scene.getEnemyParty();
|
const party = user.isPlayer() ? user.scene.getParty() : user.scene.getEnemyParty();
|
||||||
// No status means the ally pokemon can contribute to Beat Up
|
// No status means the ally pokemon can contribute to Beat Up
|
||||||
@ -2715,36 +2711,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<boolean> {
|
|
||||||
return new Promise<boolean>(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(i18next.t("moveTriggers:cutOwnHpAndMaximizedStat", {pokemonName: getPokemonNameWithAffix(user), statName: 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 {
|
export class CutHpStatBoostAttr extends StatChangeAttr {
|
||||||
private cutRatio: integer;
|
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);
|
super(stat, levels, true, null, true);
|
||||||
|
|
||||||
this.cutRatio = cutRatio;
|
this.cutRatio = cutRatio;
|
||||||
|
this.messageCallback = messageCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
|
||||||
@ -2752,13 +2727,16 @@ export class CutHpStatBoostAttr extends StatChangeAttr {
|
|||||||
user.damageAndUpdate(Math.floor(user.getMaxHp() / this.cutRatio), HitResult.OTHER, false, true);
|
user.damageAndUpdate(Math.floor(user.getMaxHp() / this.cutRatio), HitResult.OTHER, false, true);
|
||||||
user.updateInfo().then(() => {
|
user.updateInfo().then(() => {
|
||||||
const ret = super.apply(user, target, move, args);
|
const ret = super.apply(user, target, move, args);
|
||||||
|
if (this.messageCallback) {
|
||||||
|
this.messageCallback(user);
|
||||||
|
}
|
||||||
resolve(ret);
|
resolve(ret);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getCondition(): MoveConditionFunc {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2796,7 +2774,7 @@ export class InvertStatsAttr extends MoveEffectAttr {
|
|||||||
target.updateInfo();
|
target.updateInfo();
|
||||||
user.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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2818,7 +2796,7 @@ export class ResetStatsAttr extends MoveEffectAttr {
|
|||||||
target.updateInfo();
|
target.updateInfo();
|
||||||
user.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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4226,7 +4204,7 @@ export class DisableMoveAttr extends MoveEffectAttr {
|
|||||||
target.summonData.disabledMove = disabledMove.moveId;
|
target.summonData.disabledMove = disabledMove.moveId;
|
||||||
target.summonData.disabledTurns = 4;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4547,7 +4525,7 @@ export class FaintCountdownAttr extends AddBattlerTagAttr {
|
|||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4803,7 +4781,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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4898,19 +4876,14 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||||||
if (switchOutTarget.hp > 0) {
|
if (switchOutTarget.hp > 0) {
|
||||||
applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, switchOutTarget);
|
applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, switchOutTarget);
|
||||||
// switchOut below sets the UI to select party(this is not a separate Phase), then adds a SwitchSummonPhase with selected 'mon
|
// 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 {
|
} else {
|
||||||
resolve(false);
|
resolve(false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (user.scene.currentBattle.battleType) {
|
} else if (user.scene.currentBattle.battleType !== BattleType.WILD) {
|
||||||
// Switch out logic for the battle type
|
// Switch out logic for trainer battles
|
||||||
switchOutTarget.resetTurnData();
|
switchOutTarget.leaveField(!this.batonPass);
|
||||||
switchOutTarget.resetSummonData();
|
|
||||||
switchOutTarget.hideInfo();
|
|
||||||
switchOutTarget.setVisible(false);
|
|
||||||
switchOutTarget.scene.field.remove(switchOutTarget);
|
|
||||||
user.scene.triggerPokemonFormChange(switchOutTarget, SpeciesFormChangeActiveTrigger, true);
|
|
||||||
|
|
||||||
if (switchOutTarget.hp > 0) {
|
if (switchOutTarget.hp > 0) {
|
||||||
// for opponent switching out
|
// for opponent switching out
|
||||||
@ -5039,7 +5012,7 @@ export class CopyTypeAttr extends MoveEffectAttr {
|
|||||||
user.summonData.types = target.getTypes(true);
|
user.summonData.types = target.getTypes(true);
|
||||||
user.updateInfo();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5720,7 +5693,7 @@ export class SuppressAbilitiesAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
target.summonData.abilitySuppressed = true;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -6616,7 +6589,9 @@ export function initMoves() {
|
|||||||
new StatusMove(Moves.SWEET_KISS, Type.FAIRY, 75, 10, -1, 0, 2)
|
new StatusMove(Moves.SWEET_KISS, Type.FAIRY, 75, 10, -1, 0, 2)
|
||||||
.attr(ConfuseAttr),
|
.attr(ConfuseAttr),
|
||||||
new SelfStatusMove(Moves.BELLY_DRUM, Type.NORMAL, -1, 10, -1, 0, 2)
|
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)
|
new AttackMove(Moves.SLUDGE_BOMB, Type.POISON, MoveCategory.SPECIAL, 90, 100, 10, 30, 0, 2)
|
||||||
.attr(StatusEffectAttr, StatusEffect.POISON)
|
.attr(StatusEffectAttr, StatusEffect.POISON)
|
||||||
.ballBombMove(),
|
.ballBombMove(),
|
||||||
@ -6804,6 +6779,7 @@ export function initMoves() {
|
|||||||
.attr(StatChangeAttr, BattleStat.SPDEF, -1)
|
.attr(StatChangeAttr, BattleStat.SPDEF, -1)
|
||||||
.ballBombMove(),
|
.ballBombMove(),
|
||||||
new AttackMove(Moves.FUTURE_SIGHT, Type.PSYCHIC, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 2)
|
new AttackMove(Moves.FUTURE_SIGHT, Type.PSYCHIC, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 2)
|
||||||
|
.partial()
|
||||||
.attr(DelayedAttackAttr, ArenaTagType.FUTURE_SIGHT, ChargeAnim.FUTURE_SIGHT_CHARGING, i18next.t("moveTriggers:foresawAnAttack", {pokemonName: "{USER}"})),
|
.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)
|
new AttackMove(Moves.ROCK_SMASH, Type.FIGHTING, MoveCategory.PHYSICAL, 40, 100, 15, 50, 0, 2)
|
||||||
.attr(StatChangeAttr, BattleStat.DEF, -1),
|
.attr(StatChangeAttr, BattleStat.DEF, -1),
|
||||||
@ -7099,6 +7075,7 @@ export function initMoves() {
|
|||||||
.attr(ConfuseAttr)
|
.attr(ConfuseAttr)
|
||||||
.pulseMove(),
|
.pulseMove(),
|
||||||
new AttackMove(Moves.DOOM_DESIRE, Type.STEEL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 3)
|
new AttackMove(Moves.DOOM_DESIRE, Type.STEEL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 3)
|
||||||
|
.partial()
|
||||||
.attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, i18next.t("moveTriggers:choseDoomDesireAsDestiny", {pokemonName: "{USER}"})),
|
.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)
|
new AttackMove(Moves.PSYCHO_BOOST, Type.PSYCHIC, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 3)
|
||||||
.attr(StatChangeAttr, BattleStat.SPATK, -2, true),
|
.attr(StatChangeAttr, BattleStat.SPATK, -2, true),
|
||||||
@ -8089,7 +8066,7 @@ export function initMoves() {
|
|||||||
.makesContact(false)
|
.makesContact(false)
|
||||||
.partial(),
|
.partial(),
|
||||||
new AttackMove(Moves.CLANGING_SCALES, Type.DRAGON, MoveCategory.SPECIAL, 110, 100, 5, -1, 0, 7)
|
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()
|
.soundBased()
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
new AttackMove(Moves.DRAGON_HAMMER, Type.DRAGON, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 7),
|
new AttackMove(Moves.DRAGON_HAMMER, Type.DRAGON, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 7),
|
||||||
|
@ -1145,6 +1145,11 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.PAWMOT, 32, null, null)
|
new SpeciesEvolution(Species.PAWMOT, 32, null, null)
|
||||||
],
|
],
|
||||||
[Species.TANDEMAUS]: [
|
[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)
|
new SpeciesEvolution(Species.MAUSHOLD, 25, null, null)
|
||||||
],
|
],
|
||||||
[Species.FIDOUGH]: [
|
[Species.FIDOUGH]: [
|
||||||
|
@ -9,6 +9,7 @@ import { Moves } from "#enums/moves";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { TimeOfDay } from "#enums/time-of-day";
|
import { TimeOfDay } from "#enums/time-of-day";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages.js";
|
import { getPokemonNameWithAffix } from "#app/messages.js";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
export enum FormChangeItem {
|
export enum FormChangeItem {
|
||||||
NONE,
|
NONE,
|
||||||
@ -357,22 +358,21 @@ export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger {
|
|||||||
export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: SpeciesFormChange, preName: string): string {
|
export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: SpeciesFormChange, preName: string): string {
|
||||||
const isMega = formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -1;
|
const isMega = formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -1;
|
||||||
const isGmax = formChange.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -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 isRevert = !isMega && formChange.formKey === pokemon.species.forms[0].formKey;
|
||||||
const prefix = !pokemon.isPlayer() ? pokemon.hasTrainer() ? "Foe " : "Wild " : "Your ";
|
|
||||||
if (isMega) {
|
if (isMega) {
|
||||||
return `${prefix}${preName} Mega Evolved\ninto ${pokemon.name}!`;
|
return i18next.t("battlePokemonForm:megaChange", { preName, pokemonName: pokemon.name });
|
||||||
}
|
}
|
||||||
if (isGmax) {
|
if (isGmax) {
|
||||||
return `${prefix}${preName} Gigantamaxed\ninto ${pokemon.name}!`;
|
return i18next.t("battlePokemonForm:gigantamaxChange", { preName, pokemonName: pokemon.name });
|
||||||
}
|
}
|
||||||
if (isEmax) {
|
if (isEmax) {
|
||||||
return `${prefix}${preName} Eternamaxed\ninto ${pokemon.name}!`;
|
return i18next.t("battlePokemonForm:eternamaxChange", { preName, pokemonName: pokemon.name });
|
||||||
}
|
}
|
||||||
if (isRevert) {
|
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 });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17287,7 +17287,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
|
|||||||
],
|
],
|
||||||
[Species.DIPPLIN]: [
|
[Species.DIPPLIN]: [
|
||||||
[ EVOLVE_MOVE, Moves.DOUBLE_HIT ],
|
[ EVOLVE_MOVE, Moves.DOUBLE_HIT ],
|
||||||
[ RELEARN_MOVE, Moves.INFESTATION ],
|
[ RELEARN_MOVE, Moves.DRAGON_CHEER ], // Custom
|
||||||
[ 1, Moves.WITHDRAW ],
|
[ 1, Moves.WITHDRAW ],
|
||||||
[ 1, Moves.SWEET_SCENT ],
|
[ 1, Moves.SWEET_SCENT ],
|
||||||
[ 1, Moves.RECYCLE ],
|
[ 1, Moves.RECYCLE ],
|
||||||
@ -18666,7 +18666,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
[ 48, Moves.PIKA_PAPOW ],
|
[ 48, Moves.PIKA_PAPOW ],
|
||||||
],
|
],
|
||||||
3: [
|
3: [
|
||||||
[ EVOLVE_MOVE, Moves.METEOR_MASH ],
|
[ 1, Moves.METEOR_MASH ],
|
||||||
[ 1, Moves.TAIL_WHIP ],
|
[ 1, Moves.TAIL_WHIP ],
|
||||||
[ 1, Moves.GROWL ],
|
[ 1, Moves.GROWL ],
|
||||||
[ 1, Moves.THUNDER_SHOCK ],
|
[ 1, Moves.THUNDER_SHOCK ],
|
||||||
@ -18690,7 +18690,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
[ 48, Moves.PIKA_PAPOW ],
|
[ 48, Moves.PIKA_PAPOW ],
|
||||||
],
|
],
|
||||||
4: [
|
4: [
|
||||||
[ EVOLVE_MOVE, Moves.ICICLE_CRASH ],
|
[ 1, Moves.ICICLE_CRASH ],
|
||||||
[ 1, Moves.TAIL_WHIP ],
|
[ 1, Moves.TAIL_WHIP ],
|
||||||
[ 1, Moves.GROWL ],
|
[ 1, Moves.GROWL ],
|
||||||
[ 1, Moves.THUNDER_SHOCK ],
|
[ 1, Moves.THUNDER_SHOCK ],
|
||||||
@ -18714,7 +18714,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
[ 48, Moves.PIKA_PAPOW ],
|
[ 48, Moves.PIKA_PAPOW ],
|
||||||
],
|
],
|
||||||
5: [
|
5: [
|
||||||
[ EVOLVE_MOVE, Moves.DRAINING_KISS ],
|
[ 1, Moves.DRAINING_KISS ],
|
||||||
[ 1, Moves.TAIL_WHIP ],
|
[ 1, Moves.TAIL_WHIP ],
|
||||||
[ 1, Moves.GROWL ],
|
[ 1, Moves.GROWL ],
|
||||||
[ 1, Moves.THUNDER_SHOCK ],
|
[ 1, Moves.THUNDER_SHOCK ],
|
||||||
@ -18738,7 +18738,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
[ 48, Moves.PIKA_PAPOW ],
|
[ 48, Moves.PIKA_PAPOW ],
|
||||||
],
|
],
|
||||||
6: [
|
6: [
|
||||||
[ EVOLVE_MOVE, Moves.ELECTRIC_TERRAIN ],
|
[ 1, Moves.ELECTRIC_TERRAIN ],
|
||||||
[ 1, Moves.TAIL_WHIP ],
|
[ 1, Moves.TAIL_WHIP ],
|
||||||
[ 1, Moves.GROWL ],
|
[ 1, Moves.GROWL ],
|
||||||
[ 1, Moves.THUNDER_SHOCK ],
|
[ 1, Moves.THUNDER_SHOCK ],
|
||||||
@ -18762,7 +18762,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
[ 48, Moves.PIKA_PAPOW ],
|
[ 48, Moves.PIKA_PAPOW ],
|
||||||
],
|
],
|
||||||
7: [
|
7: [
|
||||||
[ EVOLVE_MOVE, Moves.FLYING_PRESS ],
|
[ 1, Moves.FLYING_PRESS ],
|
||||||
[ 1, Moves.TAIL_WHIP ],
|
[ 1, Moves.TAIL_WHIP ],
|
||||||
[ 1, Moves.GROWL ],
|
[ 1, Moves.GROWL ],
|
||||||
[ 1, Moves.THUNDER_SHOCK ],
|
[ 1, Moves.THUNDER_SHOCK ],
|
||||||
@ -18886,7 +18886,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
},
|
},
|
||||||
[Species.ROTOM]: {
|
[Species.ROTOM]: {
|
||||||
1: [
|
1: [
|
||||||
[ EVOLVE_MOVE, Moves.OVERHEAT ],
|
[ 1, Moves.OVERHEAT ],
|
||||||
[ 1, Moves.DOUBLE_TEAM ],
|
[ 1, Moves.DOUBLE_TEAM ],
|
||||||
[ 1, Moves.ASTONISH ],
|
[ 1, Moves.ASTONISH ],
|
||||||
[ 5, Moves.THUNDER_SHOCK ],
|
[ 5, Moves.THUNDER_SHOCK ],
|
||||||
@ -18902,7 +18902,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
[ 55, Moves.UPROAR ],
|
[ 55, Moves.UPROAR ],
|
||||||
],
|
],
|
||||||
2: [
|
2: [
|
||||||
[ EVOLVE_MOVE, Moves.HYDRO_PUMP ],
|
[ 1, Moves.HYDRO_PUMP ],
|
||||||
[ 1, Moves.DOUBLE_TEAM ],
|
[ 1, Moves.DOUBLE_TEAM ],
|
||||||
[ 1, Moves.ASTONISH ],
|
[ 1, Moves.ASTONISH ],
|
||||||
[ 5, Moves.THUNDER_SHOCK ],
|
[ 5, Moves.THUNDER_SHOCK ],
|
||||||
@ -18918,7 +18918,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
[ 55, Moves.UPROAR ],
|
[ 55, Moves.UPROAR ],
|
||||||
],
|
],
|
||||||
3: [
|
3: [
|
||||||
[ EVOLVE_MOVE, Moves.BLIZZARD ],
|
[ 1, Moves.BLIZZARD ],
|
||||||
[ 1, Moves.DOUBLE_TEAM ],
|
[ 1, Moves.DOUBLE_TEAM ],
|
||||||
[ 1, Moves.ASTONISH ],
|
[ 1, Moves.ASTONISH ],
|
||||||
[ 5, Moves.THUNDER_SHOCK ],
|
[ 5, Moves.THUNDER_SHOCK ],
|
||||||
@ -18934,7 +18934,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
[ 55, Moves.UPROAR ],
|
[ 55, Moves.UPROAR ],
|
||||||
],
|
],
|
||||||
4: [
|
4: [
|
||||||
[ EVOLVE_MOVE, Moves.AIR_SLASH ],
|
[ 1, Moves.AIR_SLASH ],
|
||||||
[ 1, Moves.DOUBLE_TEAM ],
|
[ 1, Moves.DOUBLE_TEAM ],
|
||||||
[ 1, Moves.ASTONISH ],
|
[ 1, Moves.ASTONISH ],
|
||||||
[ 5, Moves.THUNDER_SHOCK ],
|
[ 5, Moves.THUNDER_SHOCK ],
|
||||||
@ -18950,7 +18950,7 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
[ 55, Moves.UPROAR ],
|
[ 55, Moves.UPROAR ],
|
||||||
],
|
],
|
||||||
5: [
|
5: [
|
||||||
[ EVOLVE_MOVE, Moves.LEAF_STORM ],
|
[ 1, Moves.LEAF_STORM ],
|
||||||
[ 1, Moves.DOUBLE_TEAM ],
|
[ 1, Moves.DOUBLE_TEAM ],
|
||||||
[ 1, Moves.ASTONISH ],
|
[ 1, Moves.ASTONISH ],
|
||||||
[ 5, Moves.THUNDER_SHOCK ],
|
[ 5, Moves.THUNDER_SHOCK ],
|
||||||
|
@ -301,7 +301,7 @@ export abstract class PokemonSpeciesForm {
|
|||||||
let variantDataIndex: integer|string = this.speciesId;
|
let variantDataIndex: integer|string = this.speciesId;
|
||||||
const species = getPokemonSpecies(this.speciesId);
|
const species = getPokemonSpecies(this.speciesId);
|
||||||
if (species.forms.length > 0) {
|
if (species.forms.length > 0) {
|
||||||
formkey = species.forms[formIndex]?.formKey;
|
formkey = species.forms[formIndex]?.formSpriteKey;
|
||||||
if (formkey) {
|
if (formkey) {
|
||||||
variantDataIndex = `${this.speciesId}-${formkey}`;
|
variantDataIndex = `${this.speciesId}-${formkey}`;
|
||||||
}
|
}
|
||||||
@ -435,7 +435,7 @@ export abstract class PokemonSpeciesForm {
|
|||||||
for (const moveId of moveset) {
|
for (const moveId of moveset) {
|
||||||
if (speciesEggMoves.hasOwnProperty(rootSpeciesId)) {
|
if (speciesEggMoves.hasOwnProperty(rootSpeciesId)) {
|
||||||
const eggMoveIndex = speciesEggMoves[rootSpeciesId].findIndex(m => m === moveId);
|
const eggMoveIndex = speciesEggMoves[rootSpeciesId].findIndex(m => m === moveId);
|
||||||
if (eggMoveIndex > -1 && eggMoves & Math.pow(2, eggMoveIndex)) {
|
if (eggMoveIndex > -1 && (eggMoves & (1 << eggMoveIndex))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,7 +630,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
return i18next.t(`pokemonForm:${key}`, {pokemonName: this.name});
|
return i18next.t(`battlePokemonForm:${key}`, {pokemonName: this.name});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 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("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 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.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.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),
|
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.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.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 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 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.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.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),
|
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.BULBASAUR]: 3,
|
||||||
[Species.CHARMANDER]: 3,
|
[Species.CHARMANDER]: 3,
|
||||||
[Species.SQUIRTLE]: 3,
|
[Species.SQUIRTLE]: 3,
|
||||||
[Species.CATERPIE]: 1,
|
[Species.CATERPIE]: 2,
|
||||||
[Species.WEEDLE]: 1,
|
[Species.WEEDLE]: 1,
|
||||||
[Species.PIDGEY]: 2,
|
[Species.PIDGEY]: 1,
|
||||||
[Species.RATTATA]: 1,
|
[Species.RATTATA]: 1,
|
||||||
[Species.SPEAROW]: 2,
|
[Species.SPEAROW]: 1,
|
||||||
[Species.EKANS]: 2,
|
[Species.EKANS]: 2,
|
||||||
[Species.PIKACHU]: 4,
|
[Species.PIKACHU]: 3,
|
||||||
[Species.SANDSHREW]: 2,
|
[Species.SANDSHREW]: 2,
|
||||||
[Species.NIDORAN_F]: 3,
|
[Species.NIDORAN_F]: 3,
|
||||||
[Species.NIDORAN_M]: 3,
|
[Species.NIDORAN_M]: 3,
|
||||||
[Species.CLEFAIRY]: 4,
|
[Species.CLEFAIRY]: 3,
|
||||||
[Species.VULPIX]: 3,
|
[Species.VULPIX]: 3,
|
||||||
[Species.JIGGLYPUFF]: 4,
|
[Species.JIGGLYPUFF]: 2,
|
||||||
[Species.ZUBAT]: 2,
|
[Species.ZUBAT]: 3,
|
||||||
[Species.ODDISH]: 2,
|
[Species.ODDISH]: 3,
|
||||||
[Species.PARAS]: 1,
|
[Species.PARAS]: 2,
|
||||||
[Species.VENONAT]: 2,
|
[Species.VENONAT]: 2,
|
||||||
[Species.DIGLETT]: 3,
|
[Species.DIGLETT]: 2,
|
||||||
[Species.MEOWTH]: 4,
|
[Species.MEOWTH]: 3,
|
||||||
[Species.PSYDUCK]: 2,
|
[Species.PSYDUCK]: 2,
|
||||||
[Species.MANKEY]: 4,
|
[Species.MANKEY]: 4,
|
||||||
[Species.GROWLITHE]: 4,
|
[Species.GROWLITHE]: 4,
|
||||||
[Species.POLIWAG]: 3,
|
[Species.POLIWAG]: 2,
|
||||||
[Species.ABRA]: 3,
|
[Species.ABRA]: 4,
|
||||||
[Species.MACHOP]: 3,
|
[Species.MACHOP]: 3,
|
||||||
[Species.BELLSPROUT]: 3,
|
[Species.BELLSPROUT]: 2,
|
||||||
[Species.TENTACOOL]: 3,
|
[Species.TENTACOOL]: 3,
|
||||||
[Species.GEODUDE]: 3,
|
[Species.GEODUDE]: 3,
|
||||||
[Species.PONYTA]: 3,
|
[Species.PONYTA]: 2,
|
||||||
[Species.SLOWPOKE]: 3,
|
[Species.SLOWPOKE]: 3,
|
||||||
[Species.MAGNEMITE]: 3,
|
[Species.MAGNEMITE]: 4,
|
||||||
[Species.FARFETCHD]: 4,
|
[Species.FARFETCHD]: 2,
|
||||||
[Species.DODUO]: 4,
|
[Species.DODUO]: 3,
|
||||||
[Species.SEEL]: 3,
|
[Species.SEEL]: 1,
|
||||||
[Species.GRIMER]: 3,
|
[Species.GRIMER]: 2,
|
||||||
[Species.SHELLDER]: 4,
|
[Species.SHELLDER]: 5,
|
||||||
[Species.GASTLY]: 3,
|
[Species.GASTLY]: 4,
|
||||||
[Species.ONIX]: 4,
|
[Species.ONIX]: 3,
|
||||||
[Species.DROWZEE]: 3,
|
[Species.DROWZEE]: 2,
|
||||||
[Species.KRABBY]: 2,
|
[Species.KRABBY]: 3,
|
||||||
[Species.VOLTORB]: 2,
|
[Species.VOLTORB]: 2,
|
||||||
[Species.EXEGGCUTE]: 4,
|
[Species.EXEGGCUTE]: 3,
|
||||||
[Species.CUBONE]: 3,
|
[Species.CUBONE]: 3,
|
||||||
[Species.HITMONLEE]: 5,
|
[Species.HITMONLEE]: 4,
|
||||||
[Species.HITMONCHAN]: 5,
|
[Species.HITMONCHAN]: 4,
|
||||||
[Species.LICKITUNG]: 5,
|
[Species.LICKITUNG]: 3,
|
||||||
[Species.KOFFING]: 3,
|
[Species.KOFFING]: 2,
|
||||||
[Species.RHYHORN]: 3,
|
[Species.RHYHORN]: 3,
|
||||||
[Species.CHANSEY]: 5,
|
[Species.CHANSEY]: 3,
|
||||||
[Species.TANGELA]: 3,
|
[Species.TANGELA]: 3,
|
||||||
[Species.KANGASKHAN]: 5,
|
[Species.KANGASKHAN]: 4,
|
||||||
[Species.HORSEA]: 4,
|
[Species.HORSEA]: 3,
|
||||||
[Species.GOLDEEN]: 3,
|
[Species.GOLDEEN]: 2,
|
||||||
[Species.STARYU]: 4,
|
[Species.STARYU]: 3,
|
||||||
[Species.MR_MIME]: 4,
|
[Species.MR_MIME]: 3,
|
||||||
[Species.SCYTHER]: 5,
|
[Species.SCYTHER]: 5,
|
||||||
[Species.JYNX]: 4,
|
[Species.JYNX]: 3,
|
||||||
[Species.ELECTABUZZ]: 5,
|
[Species.ELECTABUZZ]: 4,
|
||||||
[Species.MAGMAR]: 5,
|
[Species.MAGMAR]: 4,
|
||||||
[Species.PINSIR]: 4,
|
[Species.PINSIR]: 4,
|
||||||
[Species.TAUROS]: 5,
|
[Species.TAUROS]: 4,
|
||||||
[Species.MAGIKARP]: 3,
|
[Species.MAGIKARP]: 4,
|
||||||
[Species.LAPRAS]: 5,
|
[Species.LAPRAS]: 4,
|
||||||
[Species.DITTO]: 2,
|
[Species.DITTO]: 2,
|
||||||
[Species.EEVEE]: 4,
|
[Species.EEVEE]: 3,
|
||||||
[Species.PORYGON]: 4,
|
[Species.PORYGON]: 4,
|
||||||
[Species.OMANYTE]: 3,
|
[Species.OMANYTE]: 3,
|
||||||
[Species.KABUTO]: 3,
|
[Species.KABUTO]: 3,
|
||||||
@ -2759,57 +2759,57 @@ export const speciesStarters = {
|
|||||||
[Species.MEWTWO]: 8,
|
[Species.MEWTWO]: 8,
|
||||||
[Species.MEW]: 6,
|
[Species.MEW]: 6,
|
||||||
|
|
||||||
[Species.CHIKORITA]: 3,
|
[Species.CHIKORITA]: 2,
|
||||||
[Species.CYNDAQUIL]: 3,
|
[Species.CYNDAQUIL]: 3,
|
||||||
[Species.TOTODILE]: 3,
|
[Species.TOTODILE]: 3,
|
||||||
[Species.SENTRET]: 1,
|
[Species.SENTRET]: 1,
|
||||||
[Species.HOOTHOOT]: 1,
|
[Species.HOOTHOOT]: 2,
|
||||||
[Species.LEDYBA]: 1,
|
[Species.LEDYBA]: 1,
|
||||||
[Species.SPINARAK]: 1,
|
[Species.SPINARAK]: 1,
|
||||||
[Species.CHINCHOU]: 3,
|
[Species.CHINCHOU]: 2,
|
||||||
[Species.PICHU]: 3,
|
[Species.PICHU]: 2,
|
||||||
[Species.CLEFFA]: 3,
|
[Species.CLEFFA]: 2,
|
||||||
[Species.IGGLYBUFF]: 3,
|
[Species.IGGLYBUFF]: 1,
|
||||||
[Species.TOGEPI]: 3,
|
[Species.TOGEPI]: 3,
|
||||||
[Species.NATU]: 2,
|
[Species.NATU]: 2,
|
||||||
[Species.MAREEP]: 3,
|
[Species.MAREEP]: 2,
|
||||||
[Species.MARILL]: 4,
|
[Species.MARILL]: 4,
|
||||||
[Species.SUDOWOODO]: 5,
|
[Species.SUDOWOODO]: 3,
|
||||||
[Species.HOPPIP]: 1,
|
[Species.HOPPIP]: 2,
|
||||||
[Species.AIPOM]: 3,
|
[Species.AIPOM]: 2,
|
||||||
[Species.SUNKERN]: 1,
|
[Species.SUNKERN]: 1,
|
||||||
[Species.YANMA]: 3,
|
[Species.YANMA]: 3,
|
||||||
[Species.WOOPER]: 2,
|
[Species.WOOPER]: 2,
|
||||||
[Species.MURKROW]: 4,
|
[Species.MURKROW]: 3,
|
||||||
[Species.MISDREAVUS]: 3,
|
[Species.MISDREAVUS]: 2,
|
||||||
[Species.UNOWN]: 1,
|
[Species.UNOWN]: 1,
|
||||||
[Species.WOBBUFFET]: 4,
|
[Species.WOBBUFFET]: 2,
|
||||||
[Species.GIRAFARIG]: 4,
|
[Species.GIRAFARIG]: 3,
|
||||||
[Species.PINECO]: 2,
|
[Species.PINECO]: 2,
|
||||||
[Species.DUNSPARCE]: 4,
|
[Species.DUNSPARCE]: 3,
|
||||||
[Species.GLIGAR]: 4,
|
[Species.GLIGAR]: 3,
|
||||||
[Species.SNUBBULL]: 3,
|
[Species.SNUBBULL]: 2,
|
||||||
[Species.QWILFISH]: 3,
|
[Species.QWILFISH]: 3,
|
||||||
[Species.SHUCKLE]: 4,
|
[Species.SHUCKLE]: 3,
|
||||||
[Species.HERACROSS]: 5,
|
[Species.HERACROSS]: 5,
|
||||||
[Species.SNEASEL]: 4,
|
[Species.SNEASEL]: 4,
|
||||||
[Species.TEDDIURSA]: 4,
|
[Species.TEDDIURSA]: 4,
|
||||||
[Species.SLUGMA]: 2,
|
[Species.SLUGMA]: 2,
|
||||||
[Species.SWINUB]: 3,
|
[Species.SWINUB]: 3,
|
||||||
[Species.CORSOLA]: 3,
|
[Species.CORSOLA]: 2,
|
||||||
[Species.REMORAID]: 3,
|
[Species.REMORAID]: 2,
|
||||||
[Species.DELIBIRD]: 3,
|
[Species.DELIBIRD]: 2,
|
||||||
[Species.MANTINE]: 4,
|
[Species.MANTINE]: 3,
|
||||||
[Species.SKARMORY]: 5,
|
[Species.SKARMORY]: 4,
|
||||||
[Species.HOUNDOUR]: 4,
|
[Species.HOUNDOUR]: 3,
|
||||||
[Species.PHANPY]: 3,
|
[Species.PHANPY]: 3,
|
||||||
[Species.STANTLER]: 4,
|
[Species.STANTLER]: 3,
|
||||||
[Species.SMEARGLE]: 3,
|
[Species.SMEARGLE]: 1,
|
||||||
[Species.TYROGUE]: 4,
|
[Species.TYROGUE]: 2,
|
||||||
[Species.SMOOCHUM]: 3,
|
[Species.SMOOCHUM]: 2,
|
||||||
[Species.ELEKID]: 4,
|
[Species.ELEKID]: 3,
|
||||||
[Species.MAGBY]: 4,
|
[Species.MAGBY]: 3,
|
||||||
[Species.MILTANK]: 5,
|
[Species.MILTANK]: 4,
|
||||||
[Species.RAIKOU]: 6,
|
[Species.RAIKOU]: 6,
|
||||||
[Species.ENTEI]: 6,
|
[Species.ENTEI]: 6,
|
||||||
[Species.SUICUNE]: 6,
|
[Species.SUICUNE]: 6,
|
||||||
@ -2819,68 +2819,68 @@ export const speciesStarters = {
|
|||||||
[Species.CELEBI]: 6,
|
[Species.CELEBI]: 6,
|
||||||
|
|
||||||
[Species.TREECKO]: 3,
|
[Species.TREECKO]: 3,
|
||||||
[Species.TORCHIC]: 3,
|
[Species.TORCHIC]: 4,
|
||||||
[Species.MUDKIP]: 3,
|
[Species.MUDKIP]: 3,
|
||||||
[Species.POOCHYENA]: 2,
|
[Species.POOCHYENA]: 2,
|
||||||
[Species.ZIGZAGOON]: 2,
|
[Species.ZIGZAGOON]: 2,
|
||||||
[Species.WURMPLE]: 1,
|
[Species.WURMPLE]: 1,
|
||||||
[Species.LOTAD]: 3,
|
[Species.LOTAD]: 3,
|
||||||
[Species.SEEDOT]: 3,
|
[Species.SEEDOT]: 2,
|
||||||
[Species.TAILLOW]: 3,
|
[Species.TAILLOW]: 3,
|
||||||
[Species.WINGULL]: 3,
|
[Species.WINGULL]: 2,
|
||||||
[Species.RALTS]: 3,
|
[Species.RALTS]: 3,
|
||||||
[Species.SURSKIT]: 2,
|
[Species.SURSKIT]: 2,
|
||||||
[Species.SHROOMISH]: 3,
|
[Species.SHROOMISH]: 3,
|
||||||
[Species.SLAKOTH]: 4,
|
[Species.SLAKOTH]: 4,
|
||||||
[Species.NINCADA]: 4,
|
[Species.NINCADA]: 4,
|
||||||
[Species.WHISMUR]: 3,
|
[Species.WHISMUR]: 2,
|
||||||
[Species.MAKUHITA]: 3,
|
[Species.MAKUHITA]: 3,
|
||||||
[Species.AZURILL]: 3,
|
[Species.AZURILL]: 4,
|
||||||
[Species.NOSEPASS]: 3,
|
[Species.NOSEPASS]: 2,
|
||||||
[Species.SKITTY]: 3,
|
[Species.SKITTY]: 1,
|
||||||
[Species.SABLEYE]: 3,
|
[Species.SABLEYE]: 2,
|
||||||
[Species.MAWILE]: 5,
|
[Species.MAWILE]: 3,
|
||||||
[Species.ARON]: 3,
|
[Species.ARON]: 3,
|
||||||
[Species.MEDITITE]: 4,
|
[Species.MEDITITE]: 3,
|
||||||
[Species.ELECTRIKE]: 3,
|
[Species.ELECTRIKE]: 2,
|
||||||
[Species.PLUSLE]: 2,
|
[Species.PLUSLE]: 2,
|
||||||
[Species.MINUN]: 2,
|
[Species.MINUN]: 2,
|
||||||
[Species.VOLBEAT]: 2,
|
[Species.VOLBEAT]: 2,
|
||||||
[Species.ILLUMISE]: 2,
|
[Species.ILLUMISE]: 2,
|
||||||
[Species.ROSELIA]: 4,
|
[Species.ROSELIA]: 3,
|
||||||
[Species.GULPIN]: 3,
|
[Species.GULPIN]: 1,
|
||||||
[Species.CARVANHA]: 3,
|
[Species.CARVANHA]: 3,
|
||||||
[Species.WAILMER]: 3,
|
[Species.WAILMER]: 2,
|
||||||
[Species.NUMEL]: 3,
|
[Species.NUMEL]: 2,
|
||||||
[Species.TORKOAL]: 4,
|
[Species.TORKOAL]: 3,
|
||||||
[Species.SPOINK]: 3,
|
[Species.SPOINK]: 2,
|
||||||
[Species.SPINDA]: 2,
|
[Species.SPINDA]: 1,
|
||||||
[Species.TRAPINCH]: 4,
|
[Species.TRAPINCH]: 3,
|
||||||
[Species.CACNEA]: 3,
|
[Species.CACNEA]: 2,
|
||||||
[Species.SWABLU]: 3,
|
[Species.SWABLU]: 2,
|
||||||
[Species.ZANGOOSE]: 5,
|
[Species.ZANGOOSE]: 4,
|
||||||
[Species.SEVIPER]: 4,
|
[Species.SEVIPER]: 3,
|
||||||
[Species.LUNATONE]: 4,
|
[Species.LUNATONE]: 3,
|
||||||
[Species.SOLROCK]: 4,
|
[Species.SOLROCK]: 3,
|
||||||
[Species.BARBOACH]: 3,
|
[Species.BARBOACH]: 2,
|
||||||
[Species.CORPHISH]: 3,
|
[Species.CORPHISH]: 3,
|
||||||
[Species.BALTOY]: 3,
|
[Species.BALTOY]: 2,
|
||||||
[Species.LILEEP]: 3,
|
[Species.LILEEP]: 3,
|
||||||
[Species.ANORITH]: 3,
|
[Species.ANORITH]: 3,
|
||||||
[Species.FEEBAS]: 4,
|
[Species.FEEBAS]: 4,
|
||||||
[Species.CASTFORM]: 2,
|
[Species.CASTFORM]: 1,
|
||||||
[Species.KECLEON]: 4,
|
[Species.KECLEON]: 2,
|
||||||
[Species.SHUPPET]: 3,
|
[Species.SHUPPET]: 2,
|
||||||
[Species.DUSKULL]: 3,
|
[Species.DUSKULL]: 3,
|
||||||
[Species.TROPIUS]: 5,
|
[Species.TROPIUS]: 3,
|
||||||
[Species.CHIMECHO]: 4,
|
[Species.CHIMECHO]: 3,
|
||||||
[Species.ABSOL]: 5,
|
[Species.ABSOL]: 4,
|
||||||
[Species.WYNAUT]: 3,
|
[Species.WYNAUT]: 2,
|
||||||
[Species.SNORUNT]: 3,
|
[Species.SNORUNT]: 2,
|
||||||
[Species.SPHEAL]: 3,
|
[Species.SPHEAL]: 2,
|
||||||
[Species.CLAMPERL]: 3,
|
[Species.CLAMPERL]: 3,
|
||||||
[Species.RELICANTH]: 4,
|
[Species.RELICANTH]: 3,
|
||||||
[Species.LUVDISC]: 2,
|
[Species.LUVDISC]: 1,
|
||||||
[Species.BAGON]: 4,
|
[Species.BAGON]: 4,
|
||||||
[Species.BELDUM]: 4,
|
[Species.BELDUM]: 4,
|
||||||
[Species.REGIROCK]: 6,
|
[Species.REGIROCK]: 6,
|
||||||
@ -2898,39 +2898,39 @@ export const speciesStarters = {
|
|||||||
[Species.CHIMCHAR]: 3,
|
[Species.CHIMCHAR]: 3,
|
||||||
[Species.PIPLUP]: 3,
|
[Species.PIPLUP]: 3,
|
||||||
[Species.STARLY]: 3,
|
[Species.STARLY]: 3,
|
||||||
[Species.BIDOOF]: 2,
|
[Species.BIDOOF]: 3,
|
||||||
[Species.KRICKETOT]: 1,
|
[Species.KRICKETOT]: 1,
|
||||||
[Species.SHINX]: 3,
|
[Species.SHINX]: 2,
|
||||||
[Species.BUDEW]: 3,
|
[Species.BUDEW]: 3,
|
||||||
[Species.CRANIDOS]: 3,
|
[Species.CRANIDOS]: 3,
|
||||||
[Species.SHIELDON]: 3,
|
[Species.SHIELDON]: 3,
|
||||||
[Species.BURMY]: 1,
|
[Species.BURMY]: 2,
|
||||||
[Species.COMBEE]: 2,
|
[Species.COMBEE]: 2,
|
||||||
[Species.PACHIRISU]: 3,
|
[Species.PACHIRISU]: 2,
|
||||||
[Species.BUIZEL]: 3,
|
[Species.BUIZEL]: 2,
|
||||||
[Species.CHERUBI]: 3,
|
[Species.CHERUBI]: 1,
|
||||||
[Species.SHELLOS]: 3,
|
[Species.SHELLOS]: 3,
|
||||||
[Species.DRIFLOON]: 3,
|
[Species.DRIFLOON]: 2,
|
||||||
[Species.BUNEARY]: 3,
|
[Species.BUNEARY]: 2,
|
||||||
[Species.GLAMEOW]: 3,
|
[Species.GLAMEOW]: 2,
|
||||||
[Species.CHINGLING]: 3,
|
[Species.CHINGLING]: 2,
|
||||||
[Species.STUNKY]: 3,
|
[Species.STUNKY]: 2,
|
||||||
[Species.BRONZOR]: 3,
|
[Species.BRONZOR]: 3,
|
||||||
[Species.BONSLY]: 4,
|
[Species.BONSLY]: 2,
|
||||||
[Species.MIME_JR]: 3,
|
[Species.MIME_JR]: 2,
|
||||||
[Species.HAPPINY]: 4,
|
[Species.HAPPINY]: 2,
|
||||||
[Species.CHATOT]: 4,
|
[Species.CHATOT]: 2,
|
||||||
[Species.SPIRITOMB]: 5,
|
[Species.SPIRITOMB]: 4,
|
||||||
[Species.GIBLE]: 4,
|
[Species.GIBLE]: 4,
|
||||||
[Species.MUNCHLAX]: 4,
|
[Species.MUNCHLAX]: 4,
|
||||||
[Species.RIOLU]: 4,
|
[Species.RIOLU]: 3,
|
||||||
[Species.HIPPOPOTAS]: 3,
|
[Species.HIPPOPOTAS]: 3,
|
||||||
[Species.SKORUPI]: 3,
|
[Species.SKORUPI]: 3,
|
||||||
[Species.CROAGUNK]: 3,
|
[Species.CROAGUNK]: 2,
|
||||||
[Species.CARNIVINE]: 4,
|
[Species.CARNIVINE]: 2,
|
||||||
[Species.FINNEON]: 3,
|
[Species.FINNEON]: 1,
|
||||||
[Species.MANTYKE]: 3,
|
[Species.MANTYKE]: 2,
|
||||||
[Species.SNOVER]: 3,
|
[Species.SNOVER]: 2,
|
||||||
[Species.ROTOM]: 5,
|
[Species.ROTOM]: 5,
|
||||||
[Species.UXIE]: 6,
|
[Species.UXIE]: 6,
|
||||||
[Species.MESPRIT]: 6,
|
[Species.MESPRIT]: 6,
|
||||||
@ -2946,75 +2946,75 @@ export const speciesStarters = {
|
|||||||
[Species.DARKRAI]: 6,
|
[Species.DARKRAI]: 6,
|
||||||
[Species.SHAYMIN]: 6,
|
[Species.SHAYMIN]: 6,
|
||||||
[Species.ARCEUS]: 9,
|
[Species.ARCEUS]: 9,
|
||||||
[Species.VICTINI]: 7,
|
|
||||||
|
|
||||||
|
[Species.VICTINI]: 7,
|
||||||
[Species.SNIVY]: 3,
|
[Species.SNIVY]: 3,
|
||||||
[Species.TEPIG]: 3,
|
[Species.TEPIG]: 3,
|
||||||
[Species.OSHAWOTT]: 3,
|
[Species.OSHAWOTT]: 3,
|
||||||
[Species.PATRAT]: 2,
|
[Species.PATRAT]: 1,
|
||||||
[Species.LILLIPUP]: 3,
|
[Species.LILLIPUP]: 3,
|
||||||
[Species.PURRLOIN]: 3,
|
[Species.PURRLOIN]: 2,
|
||||||
[Species.PANSAGE]: 3,
|
[Species.PANSAGE]: 2,
|
||||||
[Species.PANSEAR]: 3,
|
[Species.PANSEAR]: 2,
|
||||||
[Species.PANPOUR]: 3,
|
[Species.PANPOUR]: 2,
|
||||||
[Species.MUNNA]: 3,
|
[Species.MUNNA]: 2,
|
||||||
[Species.PIDOVE]: 2,
|
[Species.PIDOVE]: 1,
|
||||||
[Species.BLITZLE]: 3,
|
[Species.BLITZLE]: 2,
|
||||||
[Species.ROGGENROLA]: 3,
|
[Species.ROGGENROLA]: 3,
|
||||||
[Species.WOOBAT]: 3,
|
[Species.WOOBAT]: 3,
|
||||||
[Species.DRILBUR]: 4,
|
[Species.DRILBUR]: 4,
|
||||||
[Species.AUDINO]: 4,
|
[Species.AUDINO]: 3,
|
||||||
[Species.TIMBURR]: 3,
|
[Species.TIMBURR]: 4,
|
||||||
[Species.TYMPOLE]: 3,
|
[Species.TYMPOLE]: 3,
|
||||||
[Species.THROH]: 5,
|
[Species.THROH]: 4,
|
||||||
[Species.SAWK]: 5,
|
[Species.SAWK]: 4,
|
||||||
[Species.SEWADDLE]: 3,
|
[Species.SEWADDLE]: 2,
|
||||||
[Species.VENIPEDE]: 3,
|
[Species.VENIPEDE]: 3,
|
||||||
[Species.COTTONEE]: 3,
|
[Species.COTTONEE]: 3,
|
||||||
[Species.PETILIL]: 3,
|
[Species.PETILIL]: 3,
|
||||||
[Species.BASCULIN]: 4,
|
[Species.BASCULIN]: 4,
|
||||||
[Species.SANDILE]: 3,
|
[Species.SANDILE]: 4,
|
||||||
[Species.DARUMAKA]: 4,
|
[Species.DARUMAKA]: 4,
|
||||||
[Species.MARACTUS]: 4,
|
[Species.MARACTUS]: 2,
|
||||||
[Species.DWEBBLE]: 3,
|
[Species.DWEBBLE]: 2,
|
||||||
[Species.SCRAGGY]: 3,
|
[Species.SCRAGGY]: 3,
|
||||||
[Species.SIGILYPH]: 5,
|
[Species.SIGILYPH]: 4,
|
||||||
[Species.YAMASK]: 3,
|
[Species.YAMASK]: 3,
|
||||||
[Species.TIRTOUGA]: 4,
|
[Species.TIRTOUGA]: 3,
|
||||||
[Species.ARCHEN]: 4,
|
[Species.ARCHEN]: 3,
|
||||||
[Species.TRUBBISH]: 3,
|
[Species.TRUBBISH]: 2,
|
||||||
[Species.ZORUA]: 3,
|
[Species.ZORUA]: 3,
|
||||||
[Species.MINCCINO]: 3,
|
[Species.MINCCINO]: 3,
|
||||||
[Species.GOTHITA]: 3,
|
[Species.GOTHITA]: 3,
|
||||||
[Species.SOLOSIS]: 3,
|
[Species.SOLOSIS]: 3,
|
||||||
[Species.DUCKLETT]: 3,
|
[Species.DUCKLETT]: 2,
|
||||||
[Species.VANILLITE]: 3,
|
[Species.VANILLITE]: 3,
|
||||||
[Species.DEERLING]: 3,
|
[Species.DEERLING]: 2,
|
||||||
[Species.EMOLGA]: 3,
|
[Species.EMOLGA]: 2,
|
||||||
[Species.KARRABLAST]: 3,
|
[Species.KARRABLAST]: 3,
|
||||||
[Species.FOONGUS]: 3,
|
[Species.FOONGUS]: 2,
|
||||||
[Species.FRILLISH]: 3,
|
[Species.FRILLISH]: 3,
|
||||||
[Species.ALOMOMOLA]: 4,
|
[Species.ALOMOMOLA]: 4,
|
||||||
[Species.JOLTIK]: 3,
|
[Species.JOLTIK]: 3,
|
||||||
[Species.FERROSEED]: 3,
|
[Species.FERROSEED]: 3,
|
||||||
[Species.KLINK]: 3,
|
[Species.KLINK]: 3,
|
||||||
[Species.TYNAMO]: 3,
|
[Species.TYNAMO]: 2,
|
||||||
[Species.ELGYEM]: 3,
|
[Species.ELGYEM]: 3,
|
||||||
[Species.LITWICK]: 3,
|
[Species.LITWICK]: 3,
|
||||||
[Species.AXEW]: 4,
|
[Species.AXEW]: 4,
|
||||||
[Species.CUBCHOO]: 3,
|
[Species.CUBCHOO]: 2,
|
||||||
[Species.CRYOGONAL]: 5,
|
[Species.CRYOGONAL]: 4,
|
||||||
[Species.SHELMET]: 3,
|
[Species.SHELMET]: 2,
|
||||||
[Species.STUNFISK]: 4,
|
[Species.STUNFISK]: 3,
|
||||||
[Species.MIENFOO]: 3,
|
[Species.MIENFOO]: 3,
|
||||||
[Species.DRUDDIGON]: 5,
|
[Species.DRUDDIGON]: 4,
|
||||||
[Species.GOLETT]: 3,
|
[Species.GOLETT]: 3,
|
||||||
[Species.PAWNIARD]: 4,
|
[Species.PAWNIARD]: 4,
|
||||||
[Species.BOUFFALANT]: 5,
|
[Species.BOUFFALANT]: 4,
|
||||||
[Species.RUFFLET]: 3,
|
[Species.RUFFLET]: 3,
|
||||||
[Species.VULLABY]: 3,
|
[Species.VULLABY]: 3,
|
||||||
[Species.HEATMOR]: 5,
|
[Species.HEATMOR]: 3,
|
||||||
[Species.DURANT]: 5,
|
[Species.DURANT]: 4,
|
||||||
[Species.DEINO]: 4,
|
[Species.DEINO]: 4,
|
||||||
[Species.LARVESTA]: 4,
|
[Species.LARVESTA]: 4,
|
||||||
[Species.COBALION]: 6,
|
[Species.COBALION]: 6,
|
||||||
@ -3032,77 +3032,77 @@ export const speciesStarters = {
|
|||||||
|
|
||||||
[Species.CHESPIN]: 3,
|
[Species.CHESPIN]: 3,
|
||||||
[Species.FENNEKIN]: 3,
|
[Species.FENNEKIN]: 3,
|
||||||
[Species.FROAKIE]: 3,
|
[Species.FROAKIE]: 4,
|
||||||
[Species.BUNNELBY]: 2,
|
[Species.BUNNELBY]: 3,
|
||||||
[Species.FLETCHLING]: 3,
|
[Species.FLETCHLING]: 3,
|
||||||
[Species.SCATTERBUG]: 1,
|
[Species.SCATTERBUG]: 2,
|
||||||
[Species.LITLEO]: 3,
|
[Species.LITLEO]: 2,
|
||||||
[Species.FLABEBE]: 3,
|
[Species.FLABEBE]: 3,
|
||||||
[Species.SKIDDO]: 3,
|
[Species.SKIDDO]: 2,
|
||||||
[Species.PANCHAM]: 3,
|
[Species.PANCHAM]: 3,
|
||||||
[Species.FURFROU]: 4,
|
[Species.FURFROU]: 3,
|
||||||
[Species.ESPURR]: 3,
|
[Species.ESPURR]: 2,
|
||||||
[Species.HONEDGE]: 4,
|
[Species.HONEDGE]: 4,
|
||||||
[Species.SPRITZEE]: 3,
|
[Species.SPRITZEE]: 2,
|
||||||
[Species.SWIRLIX]: 3,
|
[Species.SWIRLIX]: 3,
|
||||||
[Species.INKAY]: 3,
|
[Species.INKAY]: 3,
|
||||||
[Species.BINACLE]: 3,
|
[Species.BINACLE]: 3,
|
||||||
[Species.SKRELP]: 3,
|
[Species.SKRELP]: 2,
|
||||||
[Species.CLAUNCHER]: 3,
|
[Species.CLAUNCHER]: 3,
|
||||||
[Species.HELIOPTILE]: 3,
|
[Species.HELIOPTILE]: 3,
|
||||||
[Species.TYRUNT]: 3,
|
[Species.TYRUNT]: 3,
|
||||||
[Species.AMAURA]: 3,
|
[Species.AMAURA]: 3,
|
||||||
[Species.HAWLUCHA]: 4,
|
[Species.HAWLUCHA]: 4,
|
||||||
[Species.DEDENNE]: 4,
|
[Species.DEDENNE]: 2,
|
||||||
[Species.CARBINK]: 4,
|
[Species.CARBINK]: 2,
|
||||||
[Species.GOOMY]: 4,
|
[Species.GOOMY]: 4,
|
||||||
[Species.KLEFKI]: 4,
|
[Species.KLEFKI]: 3,
|
||||||
[Species.PHANTUMP]: 3,
|
[Species.PHANTUMP]: 2,
|
||||||
[Species.PUMPKABOO]: 3,
|
[Species.PUMPKABOO]: 2,
|
||||||
[Species.BERGMITE]: 3,
|
[Species.BERGMITE]: 3,
|
||||||
[Species.NOIBAT]: 4,
|
[Species.NOIBAT]: 3,
|
||||||
[Species.XERNEAS]: 8,
|
[Species.XERNEAS]: 8,
|
||||||
[Species.YVELTAL]: 8,
|
[Species.YVELTAL]: 8,
|
||||||
[Species.ZYGARDE]: 8,
|
[Species.ZYGARDE]: 8,
|
||||||
[Species.DIANCIE]: 7,
|
[Species.DIANCIE]: 7,
|
||||||
[Species.HOOPA]: 7,
|
[Species.HOOPA]: 7,
|
||||||
[Species.VOLCANION]: 6,
|
[Species.VOLCANION]: 6,
|
||||||
[Species.ETERNAL_FLOETTE]: 5,
|
[Species.ETERNAL_FLOETTE]: 4,
|
||||||
|
|
||||||
[Species.ROWLET]: 3,
|
[Species.ROWLET]: 3,
|
||||||
[Species.LITTEN]: 3,
|
[Species.LITTEN]: 3,
|
||||||
[Species.POPPLIO]: 3,
|
[Species.POPPLIO]: 4,
|
||||||
[Species.PIKIPEK]: 3,
|
[Species.PIKIPEK]: 2,
|
||||||
[Species.YUNGOOS]: 2,
|
[Species.YUNGOOS]: 2,
|
||||||
[Species.GRUBBIN]: 2,
|
[Species.GRUBBIN]: 3,
|
||||||
[Species.CRABRAWLER]: 4,
|
[Species.CRABRAWLER]: 3,
|
||||||
[Species.ORICORIO]: 3,
|
[Species.ORICORIO]: 3,
|
||||||
[Species.CUTIEFLY]: 3,
|
[Species.CUTIEFLY]: 3,
|
||||||
[Species.ROCKRUFF]: 3,
|
[Species.ROCKRUFF]: 3,
|
||||||
[Species.WISHIWASHI]: 3,
|
[Species.WISHIWASHI]: 2,
|
||||||
[Species.MAREANIE]: 3,
|
[Species.MAREANIE]: 2,
|
||||||
[Species.MUDBRAY]: 3,
|
[Species.MUDBRAY]: 3,
|
||||||
[Species.DEWPIDER]: 3,
|
[Species.DEWPIDER]: 3,
|
||||||
[Species.FOMANTIS]: 3,
|
[Species.FOMANTIS]: 2,
|
||||||
[Species.MORELULL]: 3,
|
[Species.MORELULL]: 2,
|
||||||
[Species.SALANDIT]: 3,
|
[Species.SALANDIT]: 3,
|
||||||
[Species.STUFFUL]: 3,
|
[Species.STUFFUL]: 3,
|
||||||
[Species.BOUNSWEET]: 3,
|
[Species.BOUNSWEET]: 3,
|
||||||
[Species.COMFEY]: 4,
|
[Species.COMFEY]: 4,
|
||||||
[Species.ORANGURU]: 5,
|
[Species.ORANGURU]: 4,
|
||||||
[Species.PASSIMIAN]: 5,
|
[Species.PASSIMIAN]: 4,
|
||||||
[Species.WIMPOD]: 3,
|
[Species.WIMPOD]: 3,
|
||||||
[Species.SANDYGAST]: 3,
|
[Species.SANDYGAST]: 3,
|
||||||
[Species.PYUKUMUKU]: 3,
|
[Species.PYUKUMUKU]: 2,
|
||||||
[Species.TYPE_NULL]: 5,
|
[Species.TYPE_NULL]: 5,
|
||||||
[Species.MINIOR]: 5,
|
[Species.MINIOR]: 4,
|
||||||
[Species.KOMALA]: 5,
|
[Species.KOMALA]: 3,
|
||||||
[Species.TURTONATOR]: 5,
|
[Species.TURTONATOR]: 4,
|
||||||
[Species.TOGEDEMARU]: 4,
|
[Species.TOGEDEMARU]: 3,
|
||||||
[Species.MIMIKYU]: 5,
|
[Species.MIMIKYU]: 4,
|
||||||
[Species.BRUXISH]: 5,
|
[Species.BRUXISH]: 4,
|
||||||
[Species.DRAMPA]: 5,
|
[Species.DRAMPA]: 4,
|
||||||
[Species.DHELMISE]: 5,
|
[Species.DHELMISE]: 4,
|
||||||
[Species.JANGMO_O]: 4,
|
[Species.JANGMO_O]: 4,
|
||||||
[Species.TAPU_KOKO]: 6,
|
[Species.TAPU_KOKO]: 6,
|
||||||
[Species.TAPU_LELE]: 6,
|
[Species.TAPU_LELE]: 6,
|
||||||
@ -3124,49 +3124,49 @@ export const speciesStarters = {
|
|||||||
[Species.BLACEPHALON]: 7,
|
[Species.BLACEPHALON]: 7,
|
||||||
[Species.ZERAORA]: 6,
|
[Species.ZERAORA]: 6,
|
||||||
[Species.MELTAN]: 6,
|
[Species.MELTAN]: 6,
|
||||||
[Species.ALOLA_RATTATA]: 2,
|
[Species.ALOLA_RATTATA]: 1,
|
||||||
[Species.ALOLA_SANDSHREW]: 4,
|
[Species.ALOLA_SANDSHREW]: 2,
|
||||||
[Species.ALOLA_VULPIX]: 4,
|
[Species.ALOLA_VULPIX]: 3,
|
||||||
[Species.ALOLA_DIGLETT]: 3,
|
[Species.ALOLA_DIGLETT]: 2,
|
||||||
[Species.ALOLA_MEOWTH]: 4,
|
[Species.ALOLA_MEOWTH]: 3,
|
||||||
[Species.ALOLA_GEODUDE]: 3,
|
[Species.ALOLA_GEODUDE]: 3,
|
||||||
[Species.ALOLA_GRIMER]: 3,
|
[Species.ALOLA_GRIMER]: 3,
|
||||||
|
|
||||||
[Species.GROOKEY]: 3,
|
[Species.GROOKEY]: 4,
|
||||||
[Species.SCORBUNNY]: 3,
|
[Species.SCORBUNNY]: 4,
|
||||||
[Species.SOBBLE]: 3,
|
[Species.SOBBLE]: 4,
|
||||||
[Species.SKWOVET]: 2,
|
[Species.SKWOVET]: 2,
|
||||||
[Species.ROOKIDEE]: 4,
|
[Species.ROOKIDEE]: 3,
|
||||||
[Species.BLIPBUG]: 2,
|
[Species.BLIPBUG]: 2,
|
||||||
[Species.NICKIT]: 3,
|
[Species.NICKIT]: 1,
|
||||||
[Species.GOSSIFLEUR]: 3,
|
[Species.GOSSIFLEUR]: 2,
|
||||||
[Species.WOOLOO]: 3,
|
[Species.WOOLOO]: 2,
|
||||||
[Species.CHEWTLE]: 3,
|
[Species.CHEWTLE]: 3,
|
||||||
[Species.YAMPER]: 3,
|
[Species.YAMPER]: 2,
|
||||||
[Species.ROLYCOLY]: 3,
|
[Species.ROLYCOLY]: 3,
|
||||||
[Species.APPLIN]: 4,
|
[Species.APPLIN]: 3,
|
||||||
[Species.SILICOBRA]: 3,
|
[Species.SILICOBRA]: 3,
|
||||||
[Species.CRAMORANT]: 3,
|
[Species.CRAMORANT]: 3,
|
||||||
[Species.ARROKUDA]: 3,
|
[Species.ARROKUDA]: 3,
|
||||||
[Species.TOXEL]: 3,
|
[Species.TOXEL]: 3,
|
||||||
[Species.SIZZLIPEDE]: 3,
|
[Species.SIZZLIPEDE]: 3,
|
||||||
[Species.CLOBBOPUS]: 3,
|
[Species.CLOBBOPUS]: 2,
|
||||||
[Species.SINISTEA]: 3,
|
[Species.SINISTEA]: 3,
|
||||||
[Species.HATENNA]: 4,
|
[Species.HATENNA]: 3,
|
||||||
[Species.IMPIDIMP]: 3,
|
[Species.IMPIDIMP]: 3,
|
||||||
[Species.MILCERY]: 3,
|
[Species.MILCERY]: 3,
|
||||||
[Species.FALINKS]: 4,
|
[Species.FALINKS]: 4,
|
||||||
[Species.PINCURCHIN]: 3,
|
[Species.PINCURCHIN]: 3,
|
||||||
[Species.SNOM]: 3,
|
[Species.SNOM]: 3,
|
||||||
[Species.STONJOURNER]: 4,
|
[Species.STONJOURNER]: 3,
|
||||||
[Species.EISCUE]: 4,
|
[Species.EISCUE]: 3,
|
||||||
[Species.INDEEDEE]: 3,
|
[Species.INDEEDEE]: 4,
|
||||||
[Species.MORPEKO]: 3,
|
[Species.MORPEKO]: 3,
|
||||||
[Species.CUFANT]: 4,
|
[Species.CUFANT]: 3,
|
||||||
[Species.DRACOZOLT]: 5,
|
[Species.DRACOZOLT]: 5,
|
||||||
[Species.ARCTOZOLT]: 5,
|
[Species.ARCTOZOLT]: 4,
|
||||||
[Species.DRACOVISH]: 5,
|
[Species.DRACOVISH]: 5,
|
||||||
[Species.ARCTOVISH]: 5,
|
[Species.ARCTOVISH]: 4,
|
||||||
[Species.DURALUDON]: 5,
|
[Species.DURALUDON]: 5,
|
||||||
[Species.DREEPY]: 4,
|
[Species.DREEPY]: 4,
|
||||||
[Species.ZACIAN]: 9,
|
[Species.ZACIAN]: 9,
|
||||||
@ -3179,67 +3179,67 @@ export const speciesStarters = {
|
|||||||
[Species.GLASTRIER]: 6,
|
[Species.GLASTRIER]: 6,
|
||||||
[Species.SPECTRIER]: 7,
|
[Species.SPECTRIER]: 7,
|
||||||
[Species.CALYREX]: 8,
|
[Species.CALYREX]: 8,
|
||||||
[Species.GALAR_MEOWTH]: 4,
|
[Species.GALAR_MEOWTH]: 3,
|
||||||
[Species.GALAR_PONYTA]: 4,
|
[Species.GALAR_PONYTA]: 2,
|
||||||
[Species.GALAR_SLOWPOKE]: 3,
|
[Species.GALAR_SLOWPOKE]: 3,
|
||||||
[Species.GALAR_FARFETCHD]: 5,
|
[Species.GALAR_FARFETCHD]: 3,
|
||||||
[Species.GALAR_CORSOLA]: 4,
|
[Species.GALAR_CORSOLA]: 3,
|
||||||
[Species.GALAR_ZIGZAGOON]: 3,
|
[Species.GALAR_ZIGZAGOON]: 3,
|
||||||
[Species.GALAR_DARUMAKA]: 4,
|
[Species.GALAR_DARUMAKA]: 4,
|
||||||
[Species.GALAR_YAMASK]: 3,
|
[Species.GALAR_YAMASK]: 3,
|
||||||
[Species.GALAR_STUNFISK]: 4,
|
[Species.GALAR_STUNFISK]: 2,
|
||||||
[Species.GALAR_MR_MIME]: 5,
|
[Species.GALAR_MR_MIME]: 3,
|
||||||
[Species.GALAR_ARTICUNO]: 6,
|
[Species.GALAR_ARTICUNO]: 6,
|
||||||
[Species.GALAR_ZAPDOS]: 6,
|
[Species.GALAR_ZAPDOS]: 6,
|
||||||
[Species.GALAR_MOLTRES]: 6,
|
[Species.GALAR_MOLTRES]: 6,
|
||||||
[Species.HISUI_GROWLITHE]: 4,
|
[Species.HISUI_GROWLITHE]: 4,
|
||||||
[Species.HISUI_VOLTORB]: 3,
|
[Species.HISUI_VOLTORB]: 3,
|
||||||
[Species.HISUI_QWILFISH]: 4,
|
[Species.HISUI_QWILFISH]: 4,
|
||||||
[Species.HISUI_SNEASEL]: 4,
|
[Species.HISUI_SNEASEL]: 5,
|
||||||
[Species.HISUI_ZORUA]: 4,
|
[Species.HISUI_ZORUA]: 3,
|
||||||
[Species.ENAMORUS]: 7,
|
[Species.ENAMORUS]: 7,
|
||||||
|
|
||||||
[Species.SPRIGATITO]: 3,
|
[Species.SPRIGATITO]: 4,
|
||||||
[Species.FUECOCO]: 3,
|
[Species.FUECOCO]: 4,
|
||||||
[Species.QUAXLY]: 3,
|
[Species.QUAXLY]: 4,
|
||||||
[Species.LECHONK]: 2,
|
[Species.LECHONK]: 2,
|
||||||
[Species.TAROUNTULA]: 1,
|
[Species.TAROUNTULA]: 1,
|
||||||
[Species.NYMBLE]: 3,
|
[Species.NYMBLE]: 3,
|
||||||
[Species.PAWMI]: 3,
|
[Species.PAWMI]: 3,
|
||||||
[Species.TANDEMAUS]: 4,
|
[Species.TANDEMAUS]: 4,
|
||||||
[Species.FIDOUGH]: 3,
|
[Species.FIDOUGH]: 2,
|
||||||
[Species.SMOLIV]: 3,
|
[Species.SMOLIV]: 3,
|
||||||
[Species.SQUAWKABILLY]: 3,
|
[Species.SQUAWKABILLY]: 2,
|
||||||
[Species.NACLI]: 4,
|
[Species.NACLI]: 4,
|
||||||
[Species.CHARCADET]: 4,
|
[Species.CHARCADET]: 4,
|
||||||
[Species.TADBULB]: 3,
|
[Species.TADBULB]: 3,
|
||||||
[Species.WATTREL]: 3,
|
[Species.WATTREL]: 3,
|
||||||
[Species.MASCHIFF]: 3,
|
[Species.MASCHIFF]: 3,
|
||||||
[Species.SHROODLE]: 3,
|
[Species.SHROODLE]: 2,
|
||||||
[Species.BRAMBLIN]: 3,
|
[Species.BRAMBLIN]: 3,
|
||||||
[Species.TOEDSCOOL]: 3,
|
[Species.TOEDSCOOL]: 3,
|
||||||
[Species.KLAWF]: 4,
|
[Species.KLAWF]: 3,
|
||||||
[Species.CAPSAKID]: 3,
|
[Species.CAPSAKID]: 3,
|
||||||
[Species.RELLOR]: 3,
|
[Species.RELLOR]: 2,
|
||||||
[Species.FLITTLE]: 3,
|
[Species.FLITTLE]: 3,
|
||||||
[Species.TINKATINK]: 4,
|
[Species.TINKATINK]: 4,
|
||||||
[Species.WIGLETT]: 3,
|
[Species.WIGLETT]: 2,
|
||||||
[Species.BOMBIRDIER]: 3,
|
[Species.BOMBIRDIER]: 3,
|
||||||
[Species.FINIZEN]: 4,
|
[Species.FINIZEN]: 3,
|
||||||
[Species.VAROOM]: 4,
|
[Species.VAROOM]: 4,
|
||||||
[Species.CYCLIZAR]: 5,
|
[Species.CYCLIZAR]: 4,
|
||||||
[Species.ORTHWORM]: 4,
|
[Species.ORTHWORM]: 4,
|
||||||
[Species.GLIMMET]: 4,
|
[Species.GLIMMET]: 4,
|
||||||
[Species.GREAVARD]: 4,
|
[Species.GREAVARD]: 3,
|
||||||
[Species.FLAMIGO]: 4,
|
[Species.FLAMIGO]: 4,
|
||||||
[Species.CETODDLE]: 4,
|
[Species.CETODDLE]: 3,
|
||||||
[Species.VELUZA]: 4,
|
[Species.VELUZA]: 4,
|
||||||
[Species.DONDOZO]: 5,
|
[Species.DONDOZO]: 4,
|
||||||
[Species.TATSUGIRI]: 5,
|
[Species.TATSUGIRI]: 4,
|
||||||
[Species.GREAT_TUSK]: 6,
|
[Species.GREAT_TUSK]: 6,
|
||||||
[Species.SCREAM_TAIL]: 6,
|
[Species.SCREAM_TAIL]: 6,
|
||||||
[Species.BRUTE_BONNET]: 6,
|
[Species.BRUTE_BONNET]: 6,
|
||||||
[Species.FLUTTER_MANE]: 6,
|
[Species.FLUTTER_MANE]: 7,
|
||||||
[Species.SLITHER_WING]: 6,
|
[Species.SLITHER_WING]: 6,
|
||||||
[Species.SANDY_SHOCKS]: 6,
|
[Species.SANDY_SHOCKS]: 6,
|
||||||
[Species.IRON_TREADS]: 6,
|
[Species.IRON_TREADS]: 6,
|
||||||
@ -3273,7 +3273,7 @@ export const speciesStarters = {
|
|||||||
[Species.PECHARUNT]: 6,
|
[Species.PECHARUNT]: 6,
|
||||||
[Species.PALDEA_TAUROS]: 5,
|
[Species.PALDEA_TAUROS]: 5,
|
||||||
[Species.PALDEA_WOOPER]: 3,
|
[Species.PALDEA_WOOPER]: 3,
|
||||||
[Species.BLOODMOON_URSALUNA]: 7,
|
[Species.BLOODMOON_URSALUNA]: 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const noStarterFormKeys: string[] = [
|
export const noStarterFormKeys: string[] = [
|
||||||
|
@ -556,7 +556,7 @@ export class TrainerConfig {
|
|||||||
const nameForCall = this.name.toLowerCase().replace(/\s/g, "_");
|
const nameForCall = this.name.toLowerCase().replace(/\s/g, "_");
|
||||||
this.name = i18next.t(`trainerNames:${nameForCall}`);
|
this.name = i18next.t(`trainerNames:${nameForCall}`);
|
||||||
this.setTitle(title);
|
this.setTitle(title);
|
||||||
this.setMoneyMultiplier(2.25);
|
this.setMoneyMultiplier(2.5);
|
||||||
this.setBoss();
|
this.setBoss();
|
||||||
this.setStaticParty();
|
this.setStaticParty();
|
||||||
this.setBattleBgm("battle_plasma_boss");
|
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.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]
|
[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))
|
[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({
|
.setSpeciesPools({
|
||||||
[TrainerPoolTier.COMMON]: [Species.SLUGMA, Species.POOCHYENA, Species.NUMEL, Species.ZIGZAGOON, Species.DIGLETT, Species.MAGBY, Species.TORKOAL, Species.BALTOY, Species.BARBOACH],
|
[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.RARE]: [Species.TRAPINCH, Species.HEATMOR],
|
||||||
[TrainerPoolTier.SUPER_RARE]: [Species.TURTONATOR, Species.CHARCADET]
|
[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))
|
[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({
|
.setSpeciesPools({
|
||||||
[TrainerPoolTier.COMMON]: [ Species.CARVANHA, Species.WAILMER, Species.ZIGZAGOON, Species.LOTAD, Species.CORPHISH, Species.SPHEAL ],
|
[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.RARE]: [Species.MANTINE, Species.BASCULEGION, Species.REMORAID, Species.ARROKUDA],
|
||||||
[TrainerPoolTier.SUPER_RARE]: [Species.DONDOZO]
|
[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))
|
[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({
|
.setSpeciesPools({
|
||||||
[TrainerPoolTier.COMMON]: [ Species.GLAMEOW, Species.STUNKY, Species.CROAGUNK, Species.SHINX, Species.WURMPLE, Species.BRONZOR, Species.DRIFLOON, Species.BURMY],
|
[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.RARE]: [Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.HISUI_SNEASEL],
|
||||||
[TrainerPoolTier.SUPER_RARE]: [Species.HISUI_ZORUA, Species.HISUI_SLIGGOO]
|
[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))
|
[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({
|
.setSpeciesPools({
|
||||||
[TrainerPoolTier.COMMON]: [ Species.PATRAT, Species.LILLIPUP, Species.PURRLOIN, Species.SCRAFTY, Species.WOOBAT, Species.VANILLITE, Species.SANDILE, Species.TRUBBISH],
|
[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.RARE]: [Species.PAWNIARD, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.KLINK],
|
||||||
[TrainerPoolTier.SUPER_RARE]: [Species.DRUDDIGON, Species.BOUFFALANT, Species.AXEW, Species.DEINO, Species.DURANT]
|
[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))
|
[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({
|
.setSpeciesPools({
|
||||||
[TrainerPoolTier.COMMON]: [ Species.FLETCHLING, Species.LITLEO, Species.PONYTA, Species.INKAY, Species.HOUNDOUR, Species.SKORUPI, Species.SCRAFTY, Species.CROAGUNK],
|
[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.RARE]: [Species.LITWICK, Species.SNEASEL, Species.PANCHAM, Species.PAWNIARD],
|
||||||
[TrainerPoolTier.SUPER_RARE]: [Species.NOIVERN, Species.DRUDDIGON]
|
[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.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.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"),
|
[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.generateAndPopulateMoveset();
|
||||||
p.generateName();
|
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 => {
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SKARMORY], TrainerSlot.TRAINER, true, p => {
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
}))
|
}))
|
||||||
@ -1377,7 +1413,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
p.generateName();
|
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 => {
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PELIPPER], TrainerSlot.TRAINER, true, p => {
|
||||||
p.abilityIndex = 1; // Drizzle
|
p.abilityIndex = 1; // Drizzle
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
|
@ -53,11 +53,17 @@ export enum TrainerType {
|
|||||||
WORKER,
|
WORKER,
|
||||||
YOUNGSTER,
|
YOUNGSTER,
|
||||||
ROCKET_GRUNT,
|
ROCKET_GRUNT,
|
||||||
|
ROCKET_ADMIN,
|
||||||
MAGMA_GRUNT,
|
MAGMA_GRUNT,
|
||||||
|
MAGMA_ADMIN,
|
||||||
AQUA_GRUNT,
|
AQUA_GRUNT,
|
||||||
|
AQUA_ADMIN,
|
||||||
GALACTIC_GRUNT,
|
GALACTIC_GRUNT,
|
||||||
|
GALACTIC_ADMIN,
|
||||||
PLASMA_GRUNT,
|
PLASMA_GRUNT,
|
||||||
|
PLASMA_SAGE,
|
||||||
FLARE_GRUNT,
|
FLARE_GRUNT,
|
||||||
|
FLARE_ADMIN,
|
||||||
ROCKET_BOSS_GIOVANNI_1,
|
ROCKET_BOSS_GIOVANNI_1,
|
||||||
ROCKET_BOSS_GIOVANNI_2,
|
ROCKET_BOSS_GIOVANNI_2,
|
||||||
MAXIE,
|
MAXIE,
|
||||||
|
@ -639,9 +639,13 @@ 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 {
|
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.trySetTerrain(TerrainType.NONE, false, true);
|
||||||
this.removeAllTags();
|
this.removeAllTags();
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
public friendship: integer;
|
public friendship: integer;
|
||||||
public metLevel: integer;
|
public metLevel: integer;
|
||||||
public metBiome: Biome | -1;
|
public metBiome: Biome | -1;
|
||||||
|
public metSpecies: Species;
|
||||||
public luck: integer;
|
public luck: integer;
|
||||||
public pauseEvolutions: boolean;
|
public pauseEvolutions: boolean;
|
||||||
public pokerus: boolean;
|
public pokerus: boolean;
|
||||||
@ -174,6 +175,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
this.metLevel = dataSource.metLevel || 5;
|
this.metLevel = dataSource.metLevel || 5;
|
||||||
this.luck = dataSource.luck;
|
this.luck = dataSource.luck;
|
||||||
this.metBiome = dataSource.metBiome;
|
this.metBiome = dataSource.metBiome;
|
||||||
|
this.metSpecies = dataSource.metSpecies ?? (this.metBiome !== -1 ? this.species.speciesId : this.species.getRootSpeciesId(true));
|
||||||
this.pauseEvolutions = dataSource.pauseEvolutions;
|
this.pauseEvolutions = dataSource.pauseEvolutions;
|
||||||
this.pokerus = !!dataSource.pokerus;
|
this.pokerus = !!dataSource.pokerus;
|
||||||
this.fusionSpecies = dataSource.fusionSpecies instanceof PokemonSpecies ? dataSource.fusionSpecies : getPokemonSpecies(dataSource.fusionSpecies);
|
this.fusionSpecies = dataSource.fusionSpecies instanceof PokemonSpecies ? dataSource.fusionSpecies : getPokemonSpecies(dataSource.fusionSpecies);
|
||||||
@ -214,6 +216,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
this.friendship = species.baseFriendship;
|
this.friendship = species.baseFriendship;
|
||||||
this.metLevel = level;
|
this.metLevel = level;
|
||||||
this.metBiome = scene.currentBattle ? scene.arena.biomeType : -1;
|
this.metBiome = scene.currentBattle ? scene.arena.biomeType : -1;
|
||||||
|
this.metSpecies = species.speciesId;
|
||||||
this.pokerus = false;
|
this.pokerus = false;
|
||||||
|
|
||||||
if (level > 1) {
|
if (level > 1) {
|
||||||
@ -944,11 +947,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.
|
* Checks which egg moves have been unlocked for the {@linkcode Pokemon} based
|
||||||
* @returns {Moves[]} The valid moves
|
* 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[] {
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1310,19 +1342,39 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return multiplier;
|
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 types = this.getTypes(true);
|
||||||
const enemyTypes = pokemon.getTypes(true, true);
|
const enemyTypes = opponent.getTypes(true, true);
|
||||||
const outspeed = (this.isActive(true) ? this.getBattleStat(Stat.SPD, pokemon) : this.getStat(Stat.SPD)) <= pokemon.getBattleStat(Stat.SPD, this);
|
/** Is this Pokemon faster than the opponent? */
|
||||||
let atkScore = pokemon.getAttackTypeEffectiveness(types[0], this) * (outspeed ? 1.25 : 1);
|
const outspeed = (this.isActive(true) ? this.getBattleStat(Stat.SPD, opponent) : this.getStat(Stat.SPD)) >= opponent.getBattleStat(Stat.SPD, this);
|
||||||
let defScore = 1 / Math.max(this.getAttackTypeEffectiveness(enemyTypes[0], pokemon), 0.25);
|
/**
|
||||||
|
* 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) {
|
if (types.length > 1) {
|
||||||
atkScore *= pokemon.getAttackTypeEffectiveness(types[1], this);
|
atkScore *= opponent.getAttackTypeEffectiveness(types[1], this);
|
||||||
}
|
}
|
||||||
if (enemyTypes.length > 1) {
|
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) {
|
if (outspeed) {
|
||||||
hpDiffRatio = Math.min(hpDiffRatio * 1.5, 1);
|
hpDiffRatio = Math.min(hpDiffRatio * 1.5, 1);
|
||||||
}
|
}
|
||||||
@ -1448,8 +1500,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rand1 = Utils.binToDec(Utils.decToBin(this.id).substring(0, 16));
|
const rand1 = (this.id & 0xFFFF0000) >>> 16;
|
||||||
const rand2 = Utils.binToDec(Utils.decToBin(this.id).substring(16, 32));
|
const rand2 = (this.id & 0x0000FFFF);
|
||||||
|
|
||||||
const E = this.scene.gameData.trainerId ^ this.scene.gameData.secretId;
|
const E = this.scene.gameData.trainerId ^ this.scene.gameData.secretId;
|
||||||
const F = rand1 ^ rand2;
|
const F = rand1 ^ rand2;
|
||||||
@ -3185,6 +3237,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return this.randSeedInt((max - min) + 1, min);
|
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.resetSprite();
|
||||||
|
this.scene.field.remove(this);
|
||||||
|
this.scene.triggerPokemonFormChange(this, SpeciesFormChangeActiveTrigger, true);
|
||||||
|
}
|
||||||
|
|
||||||
destroy(): void {
|
destroy(): void {
|
||||||
this.battleInfo?.destroy();
|
this.battleInfo?.destroy();
|
||||||
super.destroy();
|
super.destroy();
|
||||||
@ -3229,7 +3298,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!dataSource) {
|
if (!dataSource) {
|
||||||
this.generateAndPopulateMoveset();
|
this.moveset = [];
|
||||||
}
|
}
|
||||||
this.generateCompatibleTms();
|
this.generateCompatibleTms();
|
||||||
}
|
}
|
||||||
@ -3296,25 +3365,21 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switchOut(batonPass: boolean, removeFromField: boolean = false): Promise<void> {
|
/**
|
||||||
|
* 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<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
this.resetTurnData();
|
this.leaveField(!batonPass);
|
||||||
if (!batonPass) {
|
|
||||||
this.resetSummonData();
|
|
||||||
}
|
|
||||||
this.hideInfo();
|
|
||||||
this.setVisible(false);
|
|
||||||
|
|
||||||
this.scene.ui.setMode(Mode.PARTY, PartyUiMode.FAINT_SWITCH, this.getFieldIndex(), (slotIndex: integer, option: PartyOption) => {
|
this.scene.ui.setMode(Mode.PARTY, PartyUiMode.FAINT_SWITCH, this.getFieldIndex(), (slotIndex: integer, option: PartyOption) => {
|
||||||
if (slotIndex >= this.scene.currentBattle.getBattlerCount() && slotIndex < 6) {
|
if (slotIndex >= this.scene.currentBattle.getBattlerCount() && slotIndex < 6) {
|
||||||
this.scene.prependToPhase(new SwitchSummonPhase(this.scene, this.getFieldIndex(), slotIndex, false, batonPass), MoveEndPhase);
|
this.scene.prependToPhase(new SwitchSummonPhase(this.scene, this.getFieldIndex(), slotIndex, false, batonPass), MoveEndPhase);
|
||||||
}
|
}
|
||||||
if (removeFromField) {
|
this.scene.ui.setMode(Mode.MESSAGE).then(resolve);
|
||||||
this.setVisible(false);
|
|
||||||
this.scene.field.remove(this);
|
|
||||||
this.scene.triggerPokemonFormChange(this, SpeciesFormChangeActiveTrigger, true);
|
|
||||||
}
|
|
||||||
this.scene.ui.setMode(Mode.MESSAGE).then(() => resolve());
|
|
||||||
}, PartyUiHandler.FilterNonFainted);
|
}, PartyUiHandler.FilterNonFainted);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -3741,7 +3806,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 {
|
getNextMove(): QueuedMove {
|
||||||
|
// If this Pokemon has a move already queued, return it.
|
||||||
const queuedMove = this.getMoveQueue().length
|
const queuedMove = this.getMoveQueue().length
|
||||||
? this.getMoveset().find(m => m.moveId === this.getMoveQueue()[0].move)
|
? this.getMoveset().find(m => m.moveId === this.getMoveQueue()[0].move)
|
||||||
: null;
|
: null;
|
||||||
@ -3754,11 +3825,15 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter out any moves this Pokemon cannot use
|
||||||
const movePool = this.getMoveset().filter(m => m.isUsable(this));
|
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 (movePool.length) {
|
||||||
|
// If there's only 1 move in the move pool, use it.
|
||||||
if (movePool.length === 1) {
|
if (movePool.length === 1) {
|
||||||
return { move: movePool[0].moveId, targets: this.getNextTargets(movePool[0].moveId) };
|
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;
|
const encoreTag = this.getTag(EncoreTag) as EncoreTag;
|
||||||
if (encoreTag) {
|
if (encoreTag) {
|
||||||
const encoreMove = movePool.find(m => m.moveId === encoreTag.moveId);
|
const encoreMove = movePool.find(m => m.moveId === encoreTag.moveId);
|
||||||
@ -3767,11 +3842,16 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (this.aiType) {
|
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;
|
const moveId = movePool[this.scene.randBattleSeedInt(movePool.length)].moveId;
|
||||||
return { move: moveId, targets: this.getNextTargets(moveId) };
|
return { move: moveId, targets: this.getNextTargets(moveId) };
|
||||||
case AiType.SMART_RANDOM:
|
case AiType.SMART_RANDOM:
|
||||||
case AiType.SMART:
|
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 moveScores = movePool.map(() => 0);
|
||||||
const moveTargets = Object.fromEntries(movePool.map(m => [ m.moveId, this.getNextTargets(m.moveId) ]));
|
const moveTargets = Object.fromEntries(movePool.map(m => [ m.moveId, this.getNextTargets(m.moveId) ]));
|
||||||
for (const m in movePool) {
|
for (const m in movePool) {
|
||||||
@ -3788,14 +3868,26 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const target = this.scene.getField()[mt];
|
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);
|
let targetScore = move.getUserBenefitScore(this, target, move) + move.getTargetBenefitScore(this, target, move) * (mt < BattlerIndex.ENEMY === this.isPlayer() ? 1 : -1);
|
||||||
if (Number.isNaN(targetScore)) {
|
if (Number.isNaN(targetScore)) {
|
||||||
console.error(`Move ${move.name} returned score of NaN`);
|
console.error(`Move ${move.name} returned score of NaN`);
|
||||||
targetScore = 0;
|
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)) {
|
if ((move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && ![Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id)) {
|
||||||
targetScore = -20;
|
targetScore = -20;
|
||||||
} else if (move instanceof AttackMove) {
|
} 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);
|
const effectiveness = target.getAttackMoveEffectiveness(this, pokemonMove);
|
||||||
if (target.isPlayer() !== this.isPlayer()) {
|
if (target.isPlayer() !== this.isPlayer()) {
|
||||||
targetScore *= effectiveness;
|
targetScore *= effectiveness;
|
||||||
@ -3808,13 +3900,14 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
targetScore /= 1.5;
|
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) {
|
if (!targetScore) {
|
||||||
targetScore = -20;
|
targetScore = -20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targetScores.push(targetScore);
|
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);
|
moveScore += Math.max(...targetScores);
|
||||||
|
|
||||||
// could make smarter by checking opponent def/spdef
|
// could make smarter by checking opponent def/spdef
|
||||||
@ -3823,6 +3916,7 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
|
|
||||||
console.log(moveScores);
|
console.log(moveScores);
|
||||||
|
|
||||||
|
// Sort the move pool in decreasing order of move score
|
||||||
const sortedMovePool = movePool.slice(0);
|
const sortedMovePool = movePool.slice(0);
|
||||||
sortedMovePool.sort((a, b) => {
|
sortedMovePool.sort((a, b) => {
|
||||||
const scoreA = moveScores[movePool.indexOf(a)];
|
const scoreA = moveScores[movePool.indexOf(a)];
|
||||||
@ -3831,10 +3925,12 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
});
|
});
|
||||||
let r = 0;
|
let r = 0;
|
||||||
if (this.aiType === AiType.SMART_RANDOM) {
|
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) {
|
while (r < sortedMovePool.length - 1 && this.scene.randBattleSeedInt(8) >= 5) {
|
||||||
r++;
|
r++;
|
||||||
}
|
}
|
||||||
} else if (this.aiType === AiType.SMART) {
|
} 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
|
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)) {
|
&& this.scene.randBattleSeedInt(100) < Math.round((moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) * 50)) {
|
||||||
r++;
|
r++;
|
||||||
@ -3848,15 +3944,25 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
return { move: Moves.STRUGGLE, targets: this.getNextTargets(Moves.STRUGGLE) };
|
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[] {
|
getNextTargets(moveId: Moves): BattlerIndex[] {
|
||||||
const moveTargets = getMoveTargets(this, moveId);
|
const moveTargets = getMoveTargets(this, moveId);
|
||||||
const targets = this.scene.getField(true).filter(p => moveTargets.targets.indexOf(p.getBattlerIndex()) > -1);
|
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) {
|
if (moveTargets.multiple) {
|
||||||
return targets.map(p => p.getBattlerIndex());
|
return targets.map(p => p.getBattlerIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
const move = allMoves[moveId];
|
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
|
const benefitScores = targets
|
||||||
.map(p => [ p.getBattlerIndex(), move.getTargetBenefitScore(this, p, move) * (p.isPlayer() === this.isPlayer() ? 1 : -1) ]);
|
.map(p => [ p.getBattlerIndex(), move.getTargetBenefitScore(this, p, move) * (p.isPlayer() === this.isPlayer() ? 1 : -1) ]);
|
||||||
|
|
||||||
@ -3880,12 +3986,14 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
let targetWeights = sortedBenefitScores.map(s => s[1]);
|
let targetWeights = sortedBenefitScores.map(s => s[1]);
|
||||||
const lowestWeight = targetWeights[targetWeights.length - 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) {
|
if (lowestWeight < 1) {
|
||||||
for (let w = 0; w < targetWeights.length; w++) {
|
for (let w = 0; w < targetWeights.length; w++) {
|
||||||
targetWeights[w] += Math.abs(lowestWeight - 1);
|
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);
|
const benefitCutoffIndex = targetWeights.findIndex(s => s < targetWeights[0] / 2);
|
||||||
if (benefitCutoffIndex > -1) {
|
if (benefitCutoffIndex > -1) {
|
||||||
targetWeights = targetWeights.slice(0, benefitCutoffIndex);
|
targetWeights = targetWeights.slice(0, benefitCutoffIndex);
|
||||||
@ -3900,6 +4008,11 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
return total;
|
return total;
|
||||||
}, 0);
|
}, 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);
|
const randValue = this.scene.randBattleSeedInt(totalWeight);
|
||||||
let targetIndex: integer;
|
let targetIndex: integer;
|
||||||
|
|
||||||
@ -4083,6 +4196,7 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
this.pokeball = pokeballType;
|
this.pokeball = pokeballType;
|
||||||
this.metLevel = this.level;
|
this.metLevel = this.level;
|
||||||
this.metBiome = this.scene.arena.biomeType;
|
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);
|
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);
|
party.push(newPokemon);
|
||||||
ret = newPokemon;
|
ret = newPokemon;
|
||||||
|
@ -121,8 +121,8 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
// Determine the title to include based on the configuration and includeTitle flag.
|
// Determine the title to include based on the configuration and includeTitle flag.
|
||||||
let title = includeTitle && this.config.title ? this.config.title : null;
|
let title = includeTitle && this.config.title ? this.config.title : null;
|
||||||
|
const evilTeamTitles = ["grunt", "admin", "sage"];
|
||||||
if (this.name === "" && name.toLowerCase().includes("grunt")) {
|
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
|
// 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, "_")}`);
|
title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, "_")}`);
|
||||||
console.log("Localized grunt name: " + title);
|
console.log("Localized grunt name: " + title);
|
||||||
|
@ -35,12 +35,12 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
|||||||
"battlerTagImmunity": "{{abilityName}} von {{pokemonNameWithAffix}} verhindert {{battlerTagName}}!",
|
"battlerTagImmunity": "{{abilityName}} von {{pokemonNameWithAffix}} verhindert {{battlerTagName}}!",
|
||||||
"forewarn": "Vorwarnung von {{pokemonNameWithAffix}}: Konzentraion auf {{moveName}}!",
|
"forewarn": "Vorwarnung von {{pokemonNameWithAffix}}: Konzentraion auf {{moveName}}!",
|
||||||
"frisk": "{{pokemonNameWithAffix}} hat die Fähigkeit {{opponentAbilityName}} von {{opponentName}} erschnüffelt!",
|
"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!",
|
"postWeatherLapseDamage": "{{pokemonNameWithAffix}} wurde durch {{abilityName}} verletzt!",
|
||||||
"postTurnLootCreateEatenBerry": "{{pokemonNameWithAffix}} hat {{berryName}} geerntet!",
|
"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!",
|
"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!",
|
"arenaTrap": "{{abilityName}} von {{pokemonNameWithAffix}} verhindert den Tausch!",
|
||||||
"postBattleLoot": "{{pokemonNameWithAffix}} hebt {{itemName}} auf!",
|
"postBattleLoot": "{{pokemonNameWithAffix}} hebt {{itemName}} auf!",
|
||||||
"postFaintContactDamage": "{{abilityName}} von {{pokemonNameWithAffix}} schadet seinem Angreifer!",
|
"postFaintContactDamage": "{{abilityName}} von {{pokemonNameWithAffix}} schadet seinem Angreifer!",
|
||||||
|
@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = {
|
|||||||
"missing_entries" : "{{name}}",
|
"missing_entries" : "{{name}}",
|
||||||
"battle_kanto_champion": "S2W2 Vs. Kanto Champion",
|
"battle_kanto_champion": "S2W2 Vs. Kanto Champion",
|
||||||
"battle_johto_champion": "S2W2 Vs. Johto 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_sinnoh_champion": "S2W2 Vs. Champion Cynthia",
|
||||||
"battle_champion_alder": "SW Vs. Champion Lauro",
|
"battle_champion_alder": "SW Vs. Champion Lauro",
|
||||||
"battle_champion_iris": "S2W2 Vs. Champion Lilia",
|
"battle_champion_iris": "S2W2 Vs. Champion Lilia",
|
||||||
|
@ -36,7 +36,7 @@ import { move } from "./move";
|
|||||||
import { nature } from "./nature";
|
import { nature } from "./nature";
|
||||||
import { pokeball } from "./pokeball";
|
import { pokeball } from "./pokeball";
|
||||||
import { pokemon } from "./pokemon";
|
import { pokemon } from "./pokemon";
|
||||||
import { pokemonForm } from "./pokemon-form";
|
import { pokemonForm, battlePokemonForm } from "./pokemon-form";
|
||||||
import { pokemonInfo } from "./pokemon-info";
|
import { pokemonInfo } from "./pokemon-info";
|
||||||
import { pokemonInfoContainer } from "./pokemon-info-container";
|
import { pokemonInfoContainer } from "./pokemon-info-container";
|
||||||
import { pokemonSummary } from "./pokemon-summary";
|
import { pokemonSummary } from "./pokemon-summary";
|
||||||
@ -62,6 +62,7 @@ export const deConfig = {
|
|||||||
battle: battle,
|
battle: battle,
|
||||||
battleInfo: battleInfo,
|
battleInfo: battleInfo,
|
||||||
battleMessageUiHandler: battleMessageUiHandler,
|
battleMessageUiHandler: battleMessageUiHandler,
|
||||||
|
battlePokemonForm: battlePokemonForm,
|
||||||
battlerTags: battlerTags,
|
battlerTags: battlerTags,
|
||||||
berry: berry,
|
berry: berry,
|
||||||
bgmName: bgmName,
|
bgmName: bgmName,
|
||||||
|
@ -378,6 +378,19 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "Das war mal wieder ein Schuss in den Ofen!"
|
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": {
|
"firebreather": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "Meine Flammen werden dich verschlingen!",
|
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…"
|
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": {
|
"aqua_grunt": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "Du willst dich also mit Team Aqua anlegen? Du traust dich ja was… Dich werfe ich über Bord!",
|
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…",
|
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": {
|
"galactic_grunt": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "Team Galaktik wird die Welt in eine bessere Welt verwandeln! Und du wirst uns nicht aufhalten!"
|
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…"
|
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": {
|
"plasma_grunt": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "Pokémon sollten frei sein! Team Plasma wird sie befreien!"
|
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…"
|
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": {
|
"flare_grunt": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Ich bin ein Mitglied von Team Flare! Das sieht man mir doch an. Mein Stil ist unverkennbar!
|
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…"
|
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": {
|
"rocket_boss_giovanni_1": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: `Ich bin beeindruckt, du hast es bis hierher geschafft!
|
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!`
|
$Wir brauchen mehr Landmassen um zu leben! Team Magma wird dieses Ziel mit aller Macht erreichen!`
|
||||||
},
|
},
|
||||||
"victory": {
|
"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": {
|
"defeat": {
|
||||||
1: "Team Magma wird weiterhin die Welt verbessern!"
|
1: "Team Magma wird weiterhin die Welt verbessern!"
|
||||||
@ -542,7 +619,7 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
},
|
},
|
||||||
"plasma_boss_ghetsis_1": {
|
"plasma_boss_ghetsis_1": {
|
||||||
"encounter": {
|
"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": {
|
"victory": {
|
||||||
1: "Wie kann das sein? Ich bin der Schöpfer von Team Plasma! Ich bin perfekt!"
|
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
|
// 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 = {
|
export const PGMmiscDialogue: SimpleTranslationEntries = {
|
||||||
"ending":
|
"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.
|
$Aber, du bist jetzt zurück.
|
||||||
$@c{smile}Es ist vorbei.@d{64} Du hast die Schleife beendet.
|
$@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.
|
$@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?
|
$@c{serious_smile_fists}Vielleicht können wir, wenn wir zurück sind, noch einen Kampf haben?
|
||||||
$Wenn du dazu bereit bist.`,
|
$Wenn du dazu bereit bist.`,
|
||||||
"ending_female":
|
"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_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_eclosed}Natürlich… ich hatte immer dieses Gefühl.
|
||||||
$@c{smile}Es ist jetzt vorbei, richtig? Du hast die Schleife beendet.
|
$@c{smile}Es ist jetzt vorbei, richtig? Du hast die Schleife beendet.
|
||||||
|
@ -3,16 +3,28 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales";
|
|||||||
export const filterBar: SimpleTranslationEntries = {
|
export const filterBar: SimpleTranslationEntries = {
|
||||||
"genFilter": "Gen.",
|
"genFilter": "Gen.",
|
||||||
"typeFilter": "Typ",
|
"typeFilter": "Typ",
|
||||||
|
"caughtFilter": "Gefangen",
|
||||||
"unlocksFilter": "Freisch.",
|
"unlocksFilter": "Freisch.",
|
||||||
"winFilter": "Abschluss",
|
"miscFilter": "Sonst.",
|
||||||
"sortFilter": "Sort.",
|
"sortFilter": "Sort.",
|
||||||
"all": "Alle",
|
"all": "Alle",
|
||||||
"normal": "Normal",
|
"normal": "Normal",
|
||||||
"uncaught": "Nicht gefangen",
|
"uncaught": "Nicht gefangen",
|
||||||
|
"passive": "Passive",
|
||||||
"passiveUnlocked": "Passive freigeschaltet",
|
"passiveUnlocked": "Passive freigeschaltet",
|
||||||
"passiveLocked": "Passive gesperrt",
|
"passiveLocked": "Passive gesperrt",
|
||||||
|
"costReduction": "Cost Reduction",
|
||||||
|
"costReductionUnlocked": "Cost Reduction Unlocked",
|
||||||
|
"costReductionLocked": "Cost Reduction Locked",
|
||||||
|
"ribbon": "Band",
|
||||||
"hasWon": "Hat Klassik-Modus gewonnen",
|
"hasWon": "Hat Klassik-Modus gewonnen",
|
||||||
"hasNotWon": "Hat Klassik-Modus nicht 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",
|
"sortByNumber": "Pokédex-Nummer",
|
||||||
"sortByCost": "Kosten",
|
"sortByCost": "Kosten",
|
||||||
"sortByCandies": "Anzahl Bonbons",
|
"sortByCandies": "Anzahl Bonbons",
|
||||||
|
@ -4,8 +4,8 @@ export const moveTriggers: SimpleTranslationEntries = {
|
|||||||
"hitWithRecoil" : "{{pokemonName}} erleidet Schaden durch Rückstoß!",
|
"hitWithRecoil" : "{{pokemonName}} erleidet Schaden durch Rückstoß!",
|
||||||
"cutHpPowerUpMove": "{{pokemonName}} nutzt seine KP um seine Attacke zu verstärken!",
|
"cutHpPowerUpMove": "{{pokemonName}} nutzt seine KP um seine Attacke zu verstärken!",
|
||||||
"absorbedElectricity": "{{pokemonName}} absorbiert elektrische Energie!",
|
"absorbedElectricity": "{{pokemonName}} absorbiert elektrische Energie!",
|
||||||
"switchedStatChanges": "{{pokemonName}}tauschte die Statuswerteveränderungen mit dem Ziel!",
|
"switchedStatChanges": "{{pokemonName}} tauschte die Statuswerteveränderungen mit dem Ziel!",
|
||||||
"goingAllOutForAttack": "{{pokemonName}}legt sich ins Zeug!",
|
"goingAllOutForAttack": "{{pokemonName}} legt sich ins Zeug!",
|
||||||
"regainedHealth": "{{pokemonName}} erholt sich!",
|
"regainedHealth": "{{pokemonName}} erholt sich!",
|
||||||
"keptGoingAndCrashed": "{{pokemonName}} springt daneben und verletzt sich!",
|
"keptGoingAndCrashed": "{{pokemonName}} springt daneben und verletzt sich!",
|
||||||
"fled": "{{pokemonName}} ist geflüchtet!",
|
"fled": "{{pokemonName}} ist geflüchtet!",
|
||||||
@ -35,7 +35,7 @@ export const moveTriggers: SimpleTranslationEntries = {
|
|||||||
"isOverflowingWithSpacePower": "Kosmische Kräfte strömen aus {{pokemonName}}!",
|
"isOverflowingWithSpacePower": "Kosmische Kräfte strömen aus {{pokemonName}}!",
|
||||||
"usedUpAllElectricity": "{{pokemonName}} braucht seinen Strom komplett auf!",
|
"usedUpAllElectricity": "{{pokemonName}} braucht seinen Strom komplett auf!",
|
||||||
"stoleItem": "{{pokemonName}} hat {{targetName}} das Item {{itemName}} geklaut!",
|
"stoleItem": "{{pokemonName}} hat {{targetName}} das Item {{itemName}} geklaut!",
|
||||||
"incineratedItem": "{{itemName}} von {{targetName}} ist verbrannt und somit nutzlos geworden!",
|
"incineratedItem": "{{pokemonName}} hat {{itemName}} von {{targetName}} verbrannt. Es ist somit nutzlos geworden!",
|
||||||
"knockedOffItem": "{{pokemonName}} schlägt das Item {{itemName}} von {{targetName}} weg!",
|
"knockedOffItem": "{{pokemonName}} schlägt das Item {{itemName}} von {{targetName}} weg!",
|
||||||
"tookMoveAttack": "{{pokemonName}} wurde von {{moveName}} getroffen!",
|
"tookMoveAttack": "{{pokemonName}} wurde von {{moveName}} getroffen!",
|
||||||
"cutOwnHpAndMaximizedStat": "{{pokemonName}} nutzt seine KP und maximiert dadurch seinen {{statName}}-Wert!",
|
"cutOwnHpAndMaximizedStat": "{{pokemonName}} nutzt seine KP und maximiert dadurch seinen {{statName}}-Wert!",
|
||||||
@ -50,5 +50,13 @@ export const moveTriggers: SimpleTranslationEntries = {
|
|||||||
"transformedIntoTarget": "{{pokemonName}} verwandelt sich in {{targetName}}!",
|
"transformedIntoTarget": "{{pokemonName}} verwandelt sich in {{targetName}}!",
|
||||||
"tryingToTakeFoeDown": "{{pokemonName}} versucht, den Angreifer mit sich zu nehmen!",
|
"tryingToTakeFoeDown": "{{pokemonName}} versucht, den Angreifer mit sich zu nehmen!",
|
||||||
"addType": "{{pokemonName}} nimmt zusätzlich den Typ {{typeName}} an!",
|
"addType": "{{pokemonName}} nimmt zusätzlich den Typ {{typeName}} an!",
|
||||||
"cannotUseMove": "{{pokemonName}} kann {{moveName}} nicht einsetzen!"
|
"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;
|
} as const;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { SimpleTranslationEntries } from "#app/interfaces/locales";
|
import { SimpleTranslationEntries } from "#app/interfaces/locales";
|
||||||
|
|
||||||
export const pokemonForm: SimpleTranslationEntries = {
|
export const battlePokemonForm: SimpleTranslationEntries = {
|
||||||
// Battle forms
|
// Battle forms
|
||||||
"mega": "Mega-{{pokemonName}}",
|
"mega": "Mega-{{pokemonName}}",
|
||||||
"mega-x": "Mega-{{pokemonName}} X",
|
"mega-x": "Mega-{{pokemonName}} X",
|
||||||
@ -9,6 +9,14 @@ export const pokemonForm: SimpleTranslationEntries = {
|
|||||||
"gigantamax": "G-Dyna-{{pokemonName}}",
|
"gigantamax": "G-Dyna-{{pokemonName}}",
|
||||||
"eternamax": "U-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
|
// Starters forms
|
||||||
// 1G
|
// 1G
|
||||||
"pikachuCosplay": "Cosplay",
|
"pikachuCosplay": "Cosplay",
|
||||||
|
@ -7,6 +7,7 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales";
|
|||||||
*/
|
*/
|
||||||
export const starterSelectUiHandler: SimpleTranslationEntries = {
|
export const starterSelectUiHandler: SimpleTranslationEntries = {
|
||||||
"confirmStartTeam": "Mit diesen Pokémon losziehen?",
|
"confirmStartTeam": "Mit diesen Pokémon losziehen?",
|
||||||
|
"confirmExit": "Do you want to exit?",
|
||||||
"invalidParty": "Das ist kein gültiges Team!",
|
"invalidParty": "Das ist kein gültiges Team!",
|
||||||
"gen1": "I",
|
"gen1": "I",
|
||||||
"gen2": "II",
|
"gen2": "II",
|
||||||
|
@ -33,7 +33,7 @@ export const statusEffect: StatusEffectTranslationEntries = {
|
|||||||
description: "Paralyse",
|
description: "Paralyse",
|
||||||
obtain: "{{pokemonNameWithAffix}} wurde paralysiert!\nEs kann eventuell nicht handeln!",
|
obtain: "{{pokemonNameWithAffix}} wurde paralysiert!\nEs kann eventuell nicht handeln!",
|
||||||
obtainSource: "{{pokemonNameWithAffix}} wurde durch {{sourceText}} 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!",
|
overlap: "{{pokemonNameWithAffix}} ist bereits paralysiert!",
|
||||||
heal: "Die Paralyse von {{pokemonNameWithAffix}} wurde aufgehoben!"
|
heal: "Die Paralyse von {{pokemonNameWithAffix}} wurde aufgehoben!"
|
||||||
},
|
},
|
||||||
|
@ -128,21 +128,32 @@ export const trainerClasses: SimpleTranslationEntries = {
|
|||||||
"rocket_grunt": "Rüpel von Team Rocket",
|
"rocket_grunt": "Rüpel von Team Rocket",
|
||||||
"rocket_grunt_female": "Rüpel von Team Rocket",
|
"rocket_grunt_female": "Rüpel von Team Rocket",
|
||||||
"rocket_grunts": "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": "Rüpel von Team Magma",
|
||||||
"magma_grunt_female": "Rüpel von Team Magma",
|
"magma_grunt_female": "Rüpel von Team Magma",
|
||||||
"magma_grunts": "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": "Rüpel von Team Aqua",
|
||||||
"aqua_grunt_female": "Rüpel von Team Aqua",
|
"aqua_grunt_female": "Rüpel von Team Aqua",
|
||||||
"aqua_grunts": "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": "Rüpel von Team Galaktik",
|
||||||
"galactic_grunt_female": "Rüpel von Team Galaktik",
|
"galactic_grunt_female": "Rüpel von Team Galaktik",
|
||||||
"galactic_grunts": "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": "Rüpel von Team Plasma",
|
||||||
"plasma_grunt_female": "Rüpel von Team Plasma",
|
"plasma_grunt_female": "Rüpel von Team Plasma",
|
||||||
"plasma_grunts": "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": "Rüpel von Team Flare",
|
||||||
"flare_grunt_female": "Rüpel von Team Flare",
|
"flare_grunt_female": "Rüpel von Team Flare",
|
||||||
"flare_grunts": "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;
|
} as const;
|
||||||
|
|
||||||
// Names of special trainers like gym leaders, elite four, and the champion
|
// Names of special trainers like gym leaders, elite four, and the champion
|
||||||
|
@ -5,7 +5,8 @@ export const bgmName: SimpleTranslationEntries = {
|
|||||||
"missing_entries" : "{{name}}",
|
"missing_entries" : "{{name}}",
|
||||||
"battle_kanto_champion": "B2W2 Kanto Champion Battle",
|
"battle_kanto_champion": "B2W2 Kanto Champion Battle",
|
||||||
"battle_johto_champion": "B2W2 Johto 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_sinnoh_champion": "B2W2 Sinnoh Champion Battle",
|
||||||
"battle_champion_alder": "BW Unova Champion Battle",
|
"battle_champion_alder": "BW Unova Champion Battle",
|
||||||
"battle_champion_iris": "B2W2 Unova Champion Battle",
|
"battle_champion_iris": "B2W2 Unova Champion Battle",
|
||||||
|
@ -39,7 +39,7 @@ import { nature } from "./nature";
|
|||||||
import { partyUiHandler } from "./party-ui-handler";
|
import { partyUiHandler } from "./party-ui-handler";
|
||||||
import { pokeball } from "./pokeball";
|
import { pokeball } from "./pokeball";
|
||||||
import { pokemon } from "./pokemon";
|
import { pokemon } from "./pokemon";
|
||||||
import { pokemonForm } from "./pokemon-form";
|
import { pokemonForm, battlePokemonForm } from "./pokemon-form";
|
||||||
import { pokemonInfo } from "./pokemon-info";
|
import { pokemonInfo } from "./pokemon-info";
|
||||||
import { pokemonInfoContainer } from "./pokemon-info-container";
|
import { pokemonInfoContainer } from "./pokemon-info-container";
|
||||||
import { pokemonSummary } from "./pokemon-summary";
|
import { pokemonSummary } from "./pokemon-summary";
|
||||||
@ -62,6 +62,7 @@ export const enConfig = {
|
|||||||
battle: battle,
|
battle: battle,
|
||||||
battleInfo: battleInfo,
|
battleInfo: battleInfo,
|
||||||
battleMessageUiHandler: battleMessageUiHandler,
|
battleMessageUiHandler: battleMessageUiHandler,
|
||||||
|
battlePokemonForm: battlePokemonForm,
|
||||||
battlerTags: battlerTags,
|
battlerTags: battlerTags,
|
||||||
berry: berry,
|
berry: berry,
|
||||||
bgmName: bgmName,
|
bgmName: bgmName,
|
||||||
|
@ -391,6 +391,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "Team Rocket blasting off again!"
|
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": {
|
"magma_grunt": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: " If you get in the way of Team Magma, don’t expect any mercy!"
|
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?!"
|
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": {
|
"aqua_grunt": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "No one who crosses Team Aqua gets any mercy, not even kids!"
|
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!"
|
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": {
|
"galactic_grunt": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "Don't mess with Team Galactic!"
|
1: "Don't mess with Team Galactic!"
|
||||||
@ -415,6 +451,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "Shut down..."
|
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": {
|
"plasma_grunt": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "We won't tolerate people who have different ideas!"
|
1: "We won't tolerate people who have different ideas!"
|
||||||
@ -423,6 +471,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "Plasmaaaaaaaaa!"
|
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": {
|
"flare_grunt": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "Fashion is most important to us!"
|
1: "Fashion is most important to us!"
|
||||||
@ -431,6 +491,18 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
|||||||
1: "The future doesn't look bright for me."
|
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": {
|
"rocket_boss_giovanni_1": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "So! I must say, I am impressed you got here!"
|
1: "So! I must say, I am impressed you got here!"
|
||||||
|
@ -3,16 +3,28 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales";
|
|||||||
export const filterBar: SimpleTranslationEntries = {
|
export const filterBar: SimpleTranslationEntries = {
|
||||||
"genFilter": "Gen",
|
"genFilter": "Gen",
|
||||||
"typeFilter": "Type",
|
"typeFilter": "Type",
|
||||||
|
"caughtFilter": "Caught",
|
||||||
"unlocksFilter": "Unlocks",
|
"unlocksFilter": "Unlocks",
|
||||||
"winFilter": "Win",
|
"miscFilter": "Misc",
|
||||||
"sortFilter": "Sort",
|
"sortFilter": "Sort",
|
||||||
"all": "All",
|
"all": "All",
|
||||||
"normal": "Normal",
|
"normal": "Normal",
|
||||||
"uncaught": "Uncaught",
|
"uncaught": "Uncaught",
|
||||||
|
"passive": "Passive",
|
||||||
"passiveUnlocked": "Passive Unlocked",
|
"passiveUnlocked": "Passive Unlocked",
|
||||||
"passiveLocked": "Passive Locked",
|
"passiveLocked": "Passive Locked",
|
||||||
"hasWon": "Yes",
|
"costReduction": "Cost Reduction",
|
||||||
"hasNotWon": "No",
|
"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.",
|
"sortByNumber": "No.",
|
||||||
"sortByCost": "Cost",
|
"sortByCost": "Cost",
|
||||||
"sortByCandies": "Candy Count",
|
"sortByCandies": "Candy Count",
|
||||||
|
@ -50,5 +50,13 @@ export const moveTriggers: SimpleTranslationEntries = {
|
|||||||
"transformedIntoTarget": "{{pokemonName}} transformed\ninto {{targetName}}!",
|
"transformedIntoTarget": "{{pokemonName}} transformed\ninto {{targetName}}!",
|
||||||
"tryingToTakeFoeDown": "{{pokemonName}} is hoping to take its attacker down with it!",
|
"tryingToTakeFoeDown": "{{pokemonName}} is hoping to take its attacker down with it!",
|
||||||
"addType": "{{typeName}} was added to\n{{pokemonName}}!",
|
"addType": "{{typeName}} was added to\n{{pokemonName}}!",
|
||||||
"cannotUseMove": "{{pokemonName}} cannot use {{moveName}}!"
|
"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;
|
} as const;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { SimpleTranslationEntries } from "#app/interfaces/locales";
|
import { SimpleTranslationEntries } from "#app/interfaces/locales";
|
||||||
|
|
||||||
export const pokemonForm: SimpleTranslationEntries = {
|
export const battlePokemonForm: SimpleTranslationEntries = {
|
||||||
// Battle forms
|
|
||||||
"mega": "Mega {{pokemonName}}",
|
"mega": "Mega {{pokemonName}}",
|
||||||
"mega-x": "Mega {{pokemonName}} X",
|
"mega-x": "Mega {{pokemonName}} X",
|
||||||
"mega-y": "Mega {{pokemonName}} Y",
|
"mega-y": "Mega {{pokemonName}} Y",
|
||||||
@ -9,6 +8,14 @@ export const pokemonForm: SimpleTranslationEntries = {
|
|||||||
"gigantamax": "G-Max {{pokemonName}}",
|
"gigantamax": "G-Max {{pokemonName}}",
|
||||||
"eternamax": "E-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
|
// Starters forms
|
||||||
// 1G
|
// 1G
|
||||||
"pikachuCosplay": "Cosplay",
|
"pikachuCosplay": "Cosplay",
|
||||||
|