Port the fishing rods and wild Magikarp
The Old, Good and Super Rods run FishFunction facing water: the map's fish group and Fish pick no fish, no bite, or a Pokémon from FishGroups and the time of day's TimeFishGroups. The player casts and jiggles with the fishing frames drawn from LoadFishingGFX's tiles, shows "!" on a bite, and the hooked Pokémon attacks as BATTLETYPE_FISH. Facing pieces now use signed offsets, which the rod above and left of the player needs. Wild Magikarp no longer stop a battle: LoadEnemyMon redraws their DVs through CalcMagikarpLength and its filters, as the original does. The length routine matches the original in the reference emulator. Part of #27 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4cb4676c7d
commit
397dcef44c
20 files changed
+681
-47
No files matched your search
@@ -14,6 +14,11 @@ import {
|
||||
* Headbutt tree back: HideHeadbuttTree's WaitBGMap and the 32 shaking
|
||||
* frames. */
|
||||
const HEADBUTT_HIDDEN_FRAMES = 36;
|
||||
/** FACING_FISH_DOWN, followed by the up, left and right fishing frames. */
|
||||
const FACING_FISH_DOWN = 0x10;
|
||||
/** A FACING_* piece's ABSOLUTE_TILE_ID flag: the tile ignores the
|
||||
* object's first tile. */
|
||||
const ABSOLUTE_TILE_ID = 0x04;
|
||||
|
||||
export class WorldRenderer {
|
||||
width: number = BASE_VIEWPORT.width;
|
||||
@@ -161,7 +166,13 @@ export class WorldRenderer {
|
||||
{ transparent: true, flipX },
|
||||
);
|
||||
}
|
||||
for (const pose of [...poses].sort((a, b) => a.y - b.y))
|
||||
for (const pose of [...poses].sort((a, b) => a.y - b.y)) {
|
||||
// The player's fishing frames use LoadFishingGFX's tiles.
|
||||
const fishing =
|
||||
pose.id === 0 &&
|
||||
pose.facing !== undefined &&
|
||||
pose.facing >= FACING_FISH_DOWN &&
|
||||
pose.facing <= FACING_FISH_DOWN + 3;
|
||||
this.actor(
|
||||
pose.sprite,
|
||||
pose.x - cameraX,
|
||||
@@ -172,7 +183,9 @@ export class WorldRenderer {
|
||||
pose.palette,
|
||||
pose.facing,
|
||||
pose.inGrass,
|
||||
fishing ? world.avatar : undefined,
|
||||
);
|
||||
}
|
||||
const emote =
|
||||
world.emote && poses.find((pose) => pose.id === world.emote!.object);
|
||||
if (emote) {
|
||||
@@ -251,9 +264,13 @@ export class WorldRenderer {
|
||||
paletteIndex?: number,
|
||||
facing?: number,
|
||||
inGrass = false,
|
||||
fishing?: "chris" | "kris",
|
||||
) {
|
||||
const sprite = this.assets.sprite(id);
|
||||
if (!sprite) return;
|
||||
const graphics = fishing
|
||||
? this.assets.fishingSprite(sprite.graphics, fishing === "kris")
|
||||
: sprite.graphics;
|
||||
const palette = this.assets.objectPalette(
|
||||
paletteIndex ?? sprite.palette,
|
||||
time,
|
||||
@@ -263,12 +280,17 @@ export class WorldRenderer {
|
||||
? this.assets.facingTiles(facing)
|
||||
: this.assets.facing(direction, sprite.walking ? frame : 0);
|
||||
for (const piece of pieces) {
|
||||
const tile = piece.tile >= 0x80 ? piece.tile - 0x80 + 12 : piece.tile;
|
||||
const tile =
|
||||
fishing && piece.attributes & ABSOLUTE_TILE_ID
|
||||
? 24 + piece.tile - 0xfc
|
||||
: piece.tile >= 0x80
|
||||
? piece.tile - 0x80 + 12
|
||||
: piece.tile;
|
||||
drawTile(
|
||||
this.image.data,
|
||||
this.width,
|
||||
this.height,
|
||||
sprite.graphics,
|
||||
graphics,
|
||||
tile,
|
||||
x + piece.x,
|
||||
y + piece.y,
|
||||
|
||||
Reference in new issue
Block a user