Skip to content

Commit

Permalink
feat: add support for Pokémon Radical Red (#59)
Browse files Browse the repository at this point in the history
* Added a basic RadicalRed typescript sav reader (#43)

* Radical Red Save Compatibility (#46)

* Added a RadicalRed save file reader
* Changed how data from PC is saved to the boxes
* Tweaked OHPKM so it doesn't look for ribbons in PK3RR files
* Bug fixes
* Merged with main branch

---------

Co-authored-by: Andrew Benington <[email protected]>

* Integrated Moves.json into Movies since the compiler couldn't find Moves.json for whatever reason

* Added RR to README

* The PP stuff are having issues.

* Fixed import in util

* `run dev` for windows

* Works well enough

* Made general

* Modified Aestherics of Save Tile Menu
* Change icon to be consistent with `Open` icon on Left Hand Side
* Move Remove button to right hand side, this makes more sense to me

* Fixed pokemon sprite

* start centralizing collection of supported save types

* Added Radical Red sprites, and adjusted the OH to use said files.

* quick fix for transfer restrictions bug i introduced

* get game name from save type

* settings toggle functionality

* Tweaked it so that RadicalRed saves matching the save OTID set pokemon GoO to RadicalRed

* Changed PKMFile to PKMInterface

* Replaced Sprites

* Fixed RadRed Sprites

* moving radical red code from pokemon-files to OpenHome

* fix typing

* fix mistakes

* determine save logo from save type, fix radical red logo

* improve plugin detection + use moves from library

* update readme

* Prevent fakemon/fakeformes from being dragged/selected. Also grays them out.

* Fixed bug in `BoxCell`

* Replaced all sprites

* Added `isLocked` attr to `PKMInterface` since this attribute is OH specific rather than something useful to `pokemon-files`

* There may be some issues with PK3RR not being included in PKM

* fix 'K3RR' and rename confusing type

* more type fixes

* Fixed warning where SaveCard key was not being set.

* Fixed warning where key was not being set.

* Removed places where console information was being printed

* Replaced Move finder functions with Move map for quicker results

* Fixed move card to display unknown moves as well when mon has <4 moves

* Expanded number boxes read to 18.

* Added credits for the RR image--*some* people place a high importance getting recognition

* memoize move card

* hide saves when plugin not enabled

* move radical red code to folder + standardize formatting

* add hotfix for missing bloodmoon ursaluna rr sprite

* fix useCallback dependency

* move sprite script + remove rr sprites w/ backgrounds

* remove unused package

* hotfix: changed RR save to read first 18 boxes instead of 19

* hotfix: Radical Red GameOfOrigin

* Added (unimplemented) method of checking if save is a RR save or if its a regular G3 SAV

* add plugin name to PK3RR

* fix pluginOrigin field

* remove unnecessary types

* Implemented additional RR check

* PK3RR sets plugin origin when reading from bytes

* reflect radical red's support for regional formes

* better save detection

* fix game code

* hotfix: fixed moves in file select menu

* radical red ball fix

* Actual move hotfix

* Added Magearna will need to redo species mapping and maybe sprites.

* add support for magearna-original

* add support for ursaluna blood moon

* fix met location for radical red

* fix more PK3RR fields and add canGigantamax

* hidden ability support

* allow for the retention of OHPKM data

* Fixed Charizard Megastones

* Undid unnecessary logging

* improve plugin origin + rr ball logic

* radical red colors

* Fixed bug where OHPKM => PK3RR would translate null moves as unknown.

* Fixed RR Origin Display

Since the `pluginOrigin` was only in the OHPKM file it was incorrectly identifying the `getPublicImageUrl`. In fact I'm not entirely sure what the difference is between this `pluginOrigin` field and the `pluginIdentifier` and why its used here. But it works now so that's good 🤷.

* Fixed PK3RR MetInfo display

**PK3RR**

Divided the  `gameOfOrigin` & `metLocation` into a private and public. The private is what's written into the byte array. The public is what's exposed to OpenHome. Thus showing mons from future generations ingame as a Trade, while mons diplayed in OH show their actual met info.

**GetMonSaveLogo**

Fixed bug where `getPublicImageURL` was called twice

* fix save logo logic

* clarify comment

* npm audit fix

* OHPKM schema moved from pokemon-files

---------

Co-authored-by: Evan <[email protected]>
Co-authored-by: evanwporter <[email protected]>
  • Loading branch information
3 people authored Nov 24, 2024
1 parent 51c6782 commit 2500068
Show file tree
Hide file tree
Showing 1,486 changed files with 17,413 additions and 12,063 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ the future.
- Pokémon Sun/Moon
- Pokémon Ultra Sun/Ultra Moon

### Supported ROM Hack formats

- Pokémon Radical Red

## Alterations to transferred Pokémon

When moving Pokémon to an older game, some compromises have to be made. OpenHome will
Expand Down
4 changes: 4 additions & 0 deletions credits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Credits

* [Radical Red Team](https://www.pokecommunity.com/threads/pok%C3%A9mon-radical-red-version-4-1-released-gen-9-dlc-pokemon-character-customization-now-available.437688/): For the Radical Red image used for identifying RR saves

74 changes: 74 additions & 0 deletions generate/_rename_rr_sprites.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const fs = require('fs');
const path = require('path');
const sharp = require('sharp');

const sourceFolder = 'rr';
const destinationFolder = __dirname;

function extractSuffixFromFilename(filename) {
const match = filename.match(/gFrontSprite\d+(.*)\.png$/i); // Match the part after gFrontSprite### until .png
return match ? match[1] : null;
}

function formatSuffix(suffix) {
if (suffix.length === 0) return suffix;
return suffix[0].toUpperCase() + suffix.slice(1).toLowerCase(); // Capitalize first letter, lowercase the rest
}

function removeBackgroundBasedOnTopLeftPixel(sourcePath, destinationPath) {
sharp(sourcePath)
.ensureAlpha()
.toBuffer()
.then((data) => {
return sharp(data).raw().toBuffer({ resolveWithObject: true });
})
.then(({ data, info }) => {
const [r, g, b] = [data[0], data[1], data[2]];

for (let i = 0; i < data.length; i += 4) {
if (data[i] === r && data[i + 1] === g && data[i + 2] === b) {
data[i + 3] = 0;
}
}

return sharp(data, { raw: { width: info.width, height: info.height, channels: 4 } })
.png()
.toFile(destinationPath);
})
.then(() => {
console.log(`Processed and saved: ${destinationPath}`);
})
.catch(error => {
console.error(`Error processing ${sourcePath}:`, error);
});
}

function deleteExistingImages() {
const files = fs.readdirSync(destinationFolder);
files.forEach(file => {
const filePath = path.join(destinationFolder, file);
if (file.match(/\.(png|jpg|jpeg|gif)$/i) && fs.lstatSync(filePath).isFile()) {
fs.unlinkSync(filePath); // Delete the file
console.log(`Deleted existing image: ${filePath}`);
}
});
}

function processImages() {
deleteExistingImages();

const files = fs.readdirSync(sourceFolder);
files.forEach(file => {
const suffix = extractSuffixFromFilename(file);
if (suffix) {
const formattedSuffix = formatSuffix(suffix); // Format the suffix
const sourcePath = path.join(sourceFolder, file);
const destinationPath = path.join(destinationFolder, `${formattedSuffix}.png`);
removeBackgroundBasedOnTopLeftPixel(sourcePath, destinationPath);
} else {
console.log(`Skipped file (no suffix found): ${file}`);
}
});
}

processImages();
Loading

0 comments on commit 2500068

Please sign in to comment.