Added changes to markdown files, reworked test boilerplate code + comment fixes

This commit is contained in:
Bertie690 2025-04-19 00:07:54 -04:00
parent a6e87c8438
commit 4a96e9f7d0
6 changed files with 77 additions and 30 deletions

2
.gitignore vendored
View File

@ -13,7 +13,7 @@ dist-ssr
*.local
# Editor directories and files
.vscode/*
.vscode
.idea
.DS_Store
*.suo

View File

@ -72,14 +72,16 @@ async function runInteractive() {
const type = typeAnswer.selectedOption.toLowerCase();
// Convert fileName from kebab-case or camelCase to snake_case
// Ex: "Cud Chew/Cud-Chew" --> "cud_chew"
const fileName = fileNameAnswer.userInput
.replace(/-+/g, "_") // Convert kebab-case (dashes) to underscores
.replace(/([a-z])([A-Z])/g, "$1_$2") // Convert camelCase to snake_case
.replace(/\s+/g, "_") // Replace spaces with underscores
.toLowerCase(); // Ensure all lowercase
// Format the description for the test case
// Get proper english name for test names and data name for abilities/moves
const formattedName = fileName.replace(/_/g, " ").replace(/\b\w/g, char => char.toUpperCase());
const attrName = fileName.toUpperCase(); // Used for move/ability tests to override with ability/move being tested
// Determine the directory based on the type
let dir;
let description;
@ -130,8 +132,8 @@ describe("${description}", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([ Moves.SPLASH ])
.ability(Abilities.BALL_FETCH)
.moveset(Moves.${type === "move" ? attrName : "SPLASH"})
.ability(Abilities.${type === "ability" ? attrName : "BALL_FETCH"})
.battleType("single")
.disableCrits()
.enemySpecies(Species.MAGIKARP)

View File

@ -9,14 +9,14 @@
- The best example of this is JSDoc-style comments as seen below:
- When formatted this way, the comment gets shown by intellisense in VS Code or similar IDEs just by hovering over the text!
- Functions also show each the comment for parameter as you type them, making keeping track of what each one does in lengthy functions much more clear
```js
```ts
/**
* Changes the type-based weather modifier if this move's power would be reduced by it
* @param user {@linkcode Pokemon} using this move
* @param target {@linkcode Pokemon} target of this move
* @param move {@linkcode Move} being used
* @param args [0] {@linkcode Utils.NumberHolder} for arenaAttackTypeMultiplier
* @returns true if the function succeeds
* @param user The {@linkcode Pokemon} using this move
* @param target The {@linkcode Pokemon} being targeted by this move
* @param move The {@linkcode Move} being used
* @param args `[0]` {@linkcode Utils.NumberHolder} for arenaAttackTypeMultiplier
* @returns `true` if the function succeeds
*/
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
}
@ -46,7 +46,7 @@ If you're interested in going more in depth, you can find a reference guide for
While other classes should be fully documented, Abilities and Moves heavily incoperate inheritance (i.e. the `extends` keyword). Because of this, much of the functionality in these classes is duplicated or only slightly changed between classes.
### With this in mind, there's a few more things to keep in mind for these:
- Do not document any parameters if the function mirrors the one they extend.
- Keep this in mind for functions that are not the `apply` function as they are usually sparce and mostly reused
- Keep this in mind for functions that are not the `apply` function as they are usually sparse and mostly reused
- The class itself must be documented
- This must include the `@extends BaseClass` and `@see {@linkcode apply}` tags
- Class member variables must be documented

View File

@ -75,7 +75,13 @@ In `getNextMove()`, the enemy Pokémon chooses a move to use in the following st
As part of the move selection process, the enemy Pokémon must compute a **target score (TS)** for each legal target for each move in its move pool. The base target score for all moves is a combination of the move's **user benefit score (UBS)** and **target benefit score (TBS)**.
![equation](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BTS%7D=%5Ctext%7BUBS%7D+%5Ctext%7BTBS%7D%5Ctimes%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D-1&%5Ctext%7Bif%20target%20is%20an%20opponent%7D%5C%5C1&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.)
$$
\text{TS} = \text{UBS} + \text{TBS} \times
\begin{cases}
-1 & \text{if target is an opponent} \\
1 & \text{otherwise}
\end{cases}
$$
A move's UBS and TBS are computed with the respective functions in the `Move` class:
@ -98,14 +104,33 @@ In addition to the base score from `Move.getTargetBenefitScore()`, attack moves
More specifically, the following steps are taken to compute the move's `attackScore`:
1. Compute a multiplier based on the move's type effectiveness:
![typeMultEqn](https://latex.codecogs.com/png.image?%5Cdpi%7B110%7D%5Cbg%7Bwhite%7D%5Ctext%7BtypeMult%7D=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D2&&%5Ctext%7Bif%20move%20is%20super%20effective(or%20better)%7D%5C%5C-2&&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.)
$$
\text{typeMult} =
\begin{cases}
2 & \text{if move is super effective (or better)} \\
-2 & \text{otherwise}
\end{cases}
$$
2. Compute a multiplier based on the move's category and the user's offensive stats:
1. Compute the user's offensive stat ratio:
![statRatioEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BstatRatio%7D=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D%5Cfrac%7B%5Ctext%7BuserSpAtk%7D%7D%7B%5Ctext%7BuserAtk%7D%7D&%5Ctext%7Bif%20move%20is%20physical%7D%5C%5C%5Cfrac%7B%5Ctext%7BuserAtk%7D%7D%7B%5Ctext%7BuserSpAtk%7D%7D&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.)
$$
\text{statRatio} =
\begin{cases}
\frac{\text{userSpAtk}}{\text{userAtk}} & \text{if move is physical} \\
\frac{\text{userAtk}}{\text{userSpAtk}} & \text{otherwise}
\end{cases}
$$
2. Compute the stat-based multiplier:
![statMultEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BstatMult%7D=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D2&%5Ctext%7Bif%20statRatio%7D%5Cle%200.75%5C%5C1.5&%5Ctext%7Bif%5C;%7D0.75%5Cle%5Ctext%7BstatRatio%7D%5Cle%200.875%5C%5C1&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.)
$$
\text{statMult} =
\begin{cases}
2 & \text{if statRatio} \leq 0.75 \\
1.5 & \text{if } 0.75 \leq \text{statRatio} \leq 0.875 \\
1 & \text{otherwise}
\end{cases}
$$
3. Calculate the move's `attackScore`:
$\text{attackScore} = (\text{typeMult}\times \text{statMult})+\lfloor \frac{\text{power}}{5} \rfloor$
@ -125,13 +150,26 @@ The final step to calculate an attack move's target score (TS) is to multiply th
The enemy's target selection for single-target moves works in a very similar way to its move selection. Each potential target is given a **target selection score (TSS)** which is based on the move's [target benefit score](#calculating-move-and-target-scores) for that target:
![TSSEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7D%5Ctext%7BTSS%7D=%5Ctext%7BTBS%7D%5Ctimes%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D-1&%5Ctext%7Bif%20target%20is%20an%20opponent%7D%5C%5C1&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.)
$$
\text{TSS} = \text{TBS} \times
\begin{cases}
-1 & \text{if target is an opponent} \\
1 & \text{otherwise}
\end{cases}
$$
Once the TSS is calculated for each target, the target is selected as follows:
1. Sort the targets (indexes) in decreasing order of their target selection scores (or weights). Let $t_i$ be the index of the *i*-th target in the sorted list, and let $w_i$ be that target's corresponding TSS.
2. Normalize the weights. Let $w_n$ be the lowest-weighted target in the sorted list, then:
![normWeightEqn](https://latex.codecogs.com/png.image?%5Cinline%20%5Cdpi%7B100%7D%5Cbg%7Bwhite%7DW_i=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7Dw_i+%7Cw_n%7C&%5Ctext%7Bif%5C;%7Dw_n%5C;%5Ctext%7Bis%20negative%7D%5C%5Cw_i&%5Ctext%7Botherwise%7D%5C%5C%5Cend%7Bmatrix%7D%5Cright.)
$$
W_i =
\begin{cases}
w_i + |w_n| & \text{if } w_n \text{ is negative} \\
w_i & \text{otherwise}
\end{cases}
$$
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)$,

View File

@ -594,7 +594,7 @@ export function getLocalizedSpriteKey(baseKey: string) {
* @returns `true` if number is **inclusive** between min and max
*/
export function isBetween(num: number, min: number, max: number): boolean {
return num >= min && num <= max;
return min <= num && num <= max;
}
/**

View File

@ -347,7 +347,10 @@ export default class GameManager {
}
}
/** Emulate selecting a modifier (item) */
/**
* Emulate selecting a modifier (item) the next time the {@linkcode SelectModifierPhase} occurs.
* Does not actually take anything (in fact, it just skips grabbing an item).
*/
doSelectModifier() {
this.onNextPrompt(
"SelectModifierPhase",
@ -421,7 +424,9 @@ export default class GameManager {
await this.phaseInterceptor.to(CommandPhase);
}
/** Emulate selecting a modifier (item) and transition to the next upcoming {@linkcode CommandPhase} */
/**
* Emulate selecting a modifier (item) and transition to the next upcoming {@linkcode CommandPhase}.
*/
async toNextWave() {
this.doSelectModifier();
@ -512,8 +517,9 @@ export default class GameManager {
}
/**
* Command an in-battle switch to another Pokemon via the main battle menu.
* @param pokemonIndex the index of the pokemon in your party to switch to
* Command an in-battle switch to another {@linkcode Pokemon} via the main battle menu.
* @param pokemonIndex the 0-indexed position of the party pokemon to switch to.
* Should generally never be called with 0 as that will just select your current active pokemon.
*/
doSwitchPokemon(pokemonIndex: number) {
this.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
@ -540,7 +546,7 @@ export default class GameManager {
* of the party UI, where you just need to navigate to a party slot and press
* Action twice - navigating any menus that come up after you select a party member
* is not supported.
* @param slot the index of the pokemon in your party to switch to
* @param slot the 0-indexed position of the pokemon in your party to switch to
* @param inPhase Which phase to expect the selection to occur in. Typically
* non-command switch actions happen in SwitchPhase.
*/
@ -575,7 +581,8 @@ export default class GameManager {
/**
* Intercepts `TurnStartPhase` and mocks {@linkcode TurnStartPhase.getSpeedOrder}'s return value.
* Used to manually modify Pokemon turn order.
* Note: This *DOES NOT* account for priority, only speed.
* Note: This *DOES NOT* account for priority.
* @param {BattlerIndex[]} order The turn order to set
* @example
* ```ts