Port Headbutt and Rock Smash encounters
Facing a Headbutt tree asks to HEADBUTT it, and HEADBUTT from the party menu skips the question. ShakeHeadbuttTree shakes the tree as a sprite over grass, then TreeMonEncounter scores the facing tile against the trainer ID and draws from the map's common or rare tree table. A Pokémon that falls fights as BATTLETYPE_TREE: "fell out of the tree!", and the time of day's AsleepTreeMons species start asleep. Smashable rocks run SmashRockScript, and ROCK SMASH from the party menu acts on the facing rock; after the rock breaks, RockMonEncounter gives the map's rock set a 40% chance of a wild battle. Closes #26 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ee55d344af
commit
f259163da9
18 files changed
+789
-36
No files matched your search
+53
-11
@@ -9,10 +9,21 @@ import { generatePartyMon } from "../src/game/party/pokemon";
|
||||
* Pokégear, its map and phone cards, and Mom's and Elm's numbers). "mom"
|
||||
* faces Mom in the living room after the Mystery Egg, with her bank open
|
||||
* and ¥2300 saved. "fly" stands outdoors with a Pidgeot that knows Fly,
|
||||
* the Storm Badge, and New Bark Town and Cherrygrove City visited. */
|
||||
* the Storm Badge, and New Bark Town and Cherrygrove City visited.
|
||||
* "headbutt" faces Route 29's first reachable Headbutt tree from below
|
||||
* with a Pokémon that knows Headbutt; Random always returning 0 drops a
|
||||
* sleeping Hoothoot. */
|
||||
export function foundationFixture(
|
||||
assets: CrystalAssets,
|
||||
room: boolean | "poster" | "center" | "candy" | "pokegear" | "mom" | "fly",
|
||||
room:
|
||||
| boolean
|
||||
| "poster"
|
||||
| "center"
|
||||
| "candy"
|
||||
| "pokegear"
|
||||
| "mom"
|
||||
| "fly"
|
||||
| "headbutt",
|
||||
) {
|
||||
const world = new GameWorld(
|
||||
assets,
|
||||
@@ -73,6 +84,21 @@ export function foundationFixture(
|
||||
world.state.flags.add(assets.spawnEngineFlag(spawn)!);
|
||||
for (let event = 0; event < 8; event++) world.state.events.delete(event);
|
||||
}
|
||||
if (room === "headbutt") {
|
||||
const mon = generatePartyMon(assets.pokemon, {
|
||||
species: 158, // TOTODILE
|
||||
level: 30,
|
||||
item: 0,
|
||||
otId: world.playerId,
|
||||
ot: "CHRIS",
|
||||
dvs: 0x9abc,
|
||||
caughtData: 0,
|
||||
});
|
||||
mon.moves = [OW.HEADBUTT, 33, 0, 0]; // TACKLE
|
||||
mon.pp = [15, 35, 0, 0];
|
||||
world.state.party = [mon];
|
||||
for (let event = 0; event < 8; event++) world.state.events.delete(event);
|
||||
}
|
||||
if (room === "mom") {
|
||||
// EVENT_GOT_MYSTERY_EGG_FROM_MR_POKEMON, EVENT_GAVE_MYSTERY_EGG_TO_ELM
|
||||
// and EVENT_TALKED_TO_MOM_AFTER_MYSTERY_EGG_QUEST.
|
||||
@@ -83,15 +109,17 @@ export function foundationFixture(
|
||||
}
|
||||
const save = world.save();
|
||||
const [map, x, y] =
|
||||
room === "center" || room === "candy"
|
||||
? ["26:5", 9, 2]
|
||||
: room === "poster"
|
||||
? ["24:7", 6, 1]
|
||||
: room === "mom"
|
||||
? ["24:6", 7, 3]
|
||||
: room && room !== "pokegear" && room !== "fly"
|
||||
? ["24:7", 2, 2]
|
||||
: ["24:4", 9, 6];
|
||||
room === "headbutt"
|
||||
? headbuttSpot(assets)
|
||||
: room === "center" || room === "candy"
|
||||
? ["26:5", 9, 2]
|
||||
: room === "poster"
|
||||
? ["24:7", 6, 1]
|
||||
: room === "mom"
|
||||
? ["24:6", 7, 3]
|
||||
: room && room !== "pokegear" && room !== "fly"
|
||||
? ["24:7", 2, 2]
|
||||
: ["24:4", 9, 6];
|
||||
world.restore({
|
||||
...save,
|
||||
map,
|
||||
@@ -102,3 +130,17 @@ export function foundationFixture(
|
||||
});
|
||||
return world;
|
||||
}
|
||||
|
||||
/** Below Route 29's first Headbutt tree with walkable ground under it. */
|
||||
function headbuttSpot(assets: CrystalAssets): [string, number, number] {
|
||||
const map = assets.map("24:3");
|
||||
for (let y = 1; y < map.height - 1; y++)
|
||||
for (let x = 0; x < map.width; x++)
|
||||
if (
|
||||
assets.collision(map, x, y) === OW.COLL_HEADBUTT_TREE &&
|
||||
assets.permission(assets.collision(map, x, y + 1)) === 0 &&
|
||||
!map.objects.some((o) => o.x === x && o.y <= y + 1 && o.y >= y)
|
||||
)
|
||||
return ["24:3", x, y + 1];
|
||||
throw new Error("No reachable Headbutt tree.");
|
||||
}
|
||||
Reference in new issue
Block a user