Entry 162
"Dun Loireag's Grunties and the Grunty foods: ccPGuso, ccGimFood and menus 43, 45 and 46"
Documented in Dun Loireag - ROOTTOWN02, its clouds, lens flare and water.
Filescrates/piney-world/src/grunty.rscrates/piney-world/src/lib.rscrates/piney-world/src/body.rscrates/piney-world/examples/grunty_probe.rscrates/piney-battle/src/gimmick.rscrates/piney-battle/src/entry.rscrates/piney-effect/src/pg.rscrates/piney-fieldui/src/menus/inu.rscrates/piney-fieldui/src/menus/objects.rscrates/piney-audio/src/driver.rscrates/piney-game/src/world.rscrates/piney-game/src/area.rscrates/piney-game/src/session/tests/dun_loireag.rscrates/piney-game/src/session/tests/shrine.rstools/test_grunty_rs.pytools/test_fieldui_talk_rs.pytools/test_battle_spawn_rs.pydocs/engine/town02.mddocs/engine/field-ui.md
A GAPS item. Dun Loireag keeps a Grunty record per town in the save. From
it, ccSetChibiGuso places the young Grunty that walks the town and the
grown ones at the pens. Kite feeds the young one foods found in the
dungeons, and it grows up through four stages into a grown kind. The
port's town had none of this: no Grunties, menus 45 and 46 unported, and
the dungeons' foods lying there invisible, with menu 43 unported.
The Grunties
- Placement.
ccSetChibiGusoplaces a grown one atDMY_cdog0-2for each kind the record has. A record at level 4 with a kind free starts over; then the young one (rows 154-157, by level) goes to its route's first dummy. The grown ones are made before the record is cleared and read it as it was, so the port constructs them from a copy of the save taken before the reset. - The class.
ccPGuso(pgbreed.cpp, 0x330 bytes) is ported whole inpiney_world::grunty:- the walk;
- sitting and sitting up for the menus;
- eating, and
paramCalc's record, next food and level; - the three growing-up acts (the stretch, the cross-fade to the next
body,
effEvolvePG); - growing into a grown kind (
adultSetup,evoActAdult: its line, the run-off of a kind the town has,effGrowPG); - the placed grown ones'
adultMain; - the three affect functions;
moveCam's fixed camera and the smoke, sounds and voices.
pgPtr.inuCheckNoteacts onpgPtr, the last Grunty made, whichever Grunty's anm passed the note. The port keeps that.- The world.
Worldlists the Grunties after the dogs, asccEntryEventMngmakes them, under the row each was made from (its base changes as it grows). Affects reach the class at once. The camera writes and Kite's placing are carried out after the list. - The effects. piney-effect's new
pgholdseffEvolvePG(the -7 controller: generators 126 and 127 at count 12, 128 at 30, following the Grunty half its height up, fromposT) andeffGrowPG(generator 129). - Drawing. The main anm is drawn through
ccChar::Draw's shadow. - The Grunty files. Their first
CMP_trallis an animation's, whose nodes are ExtObj copies of the model's objects.Body::ofnow follows a node's ExtObj copy to its target (asccMatchIndexdoes). Without that the Grunty drew nothing. Bodies whose nodes are their own objects are unchanged: the world, shadow, foe and town harnesses still match.
Menus 45 and 46
- The menus.
OtonainuMenu(45),InuMenu(46) andInuMenuDispare ported inmenus/inu.rs: the fade to the fixed camera, the STATUS window, Talk, and Give Food intoBreedingMenu. - The Grunty's line. The affect functions change the Grunty's
msgNumat once, and the game's menus read it straight after. The port's menus see the world's Grunty as the frame began, soafter_affectmakes the same change to their copy. - The runtime. piney-game hands the menus the Grunty (
World::grunty) and carries out their requests: Feed (affect 19),growthNum,foodModeandchatFlag. It also turns the Grunties' events into sounds, effects, voices (a grown kind's throughccCheckVoiceGrp) and chat lines.
The foods and menu 43
- The food. Gimmick rows 22-37 (
FOOD_00-0F, key items 26-41; 22 the Golden Egg) areccGimFood.SetItemBoxputs them in the dungeons' box slots. The port made them as inert gimmicks that drew nothing.gimmick::food_newandfood_mainport it:- it wobbles and rolls, turns to Kite and calls out within 1000
(
ccVoicePgFood); - FoodMenu's affect 11 takes it (sound 179 on note 70), then it bursts
(
effOpenBox, sound 77, the bounce and fade); - it is drawn at
SetMatrix_PosRotZYXScale. Its act and count areccGimmick's ownactNumandactCnt.
- it wobbles and rolls, turns to Kite and calls out within 1000
(
- The menu.
FoodMenu(43) is VirusMenu's shape. The item is0xf0000 | (base->id + 4), andfoodCount(+0x7446) goes up. - The voice.
ccVoicePgFoodsets its own request fromvoiceFoodTbl(E)andFOOD.BIN. The tables (generated) carry it asEvVoice::food. The runtime asks for it as event -100, whichAudio::voiceroutes toDriver::food_voice_request. The driver'svoice_requeststill plays nothing for -100, asccVoiceRequestdoes. - The riding Grunty. The flute that calls one (key item 49) is given
by
BreedingMenuwhen a new grown kind appears. So Infection reaches the ride. It is not ported here: it is the next task.
Checks
tools/test_grunty_rs.py. Runs the game'sccSetChibiGuso,ccPGuso's constructor andmainin eemu over town02, besidegrunty_probe, in 15 scenarios: the walk, talk, eating, each growing up (0 to 1, 1 to 2, 2 to 3, 1 to 3), a new kind, a kind the town has, one far from a kind, the chat lines, a fresh one fed to a grown kind over five meals, and grown rows 145-147. It compares every member, the anms, notes and draws, and the events each frame. The events now carry the height the effects read. All match.tools/test_fieldui_talk_rs.py.GruntyPagescovers 45 and 46. All 33 tests match.tools/test_fieldui_rs.py.test_foodopens 43 on bases 22, 29 and 37. All 51 tests match.tools/test_battle_spawn_rs.py. The harness now runs the constructors ofccGimFoodandccGimSymbolnatively (sizes 0x240, 0x710), and reads their members.item_boxcompares the foods and symbolsSetItemBoxmakes, andgim_framecompares food frames (main,actRolling) near and far, taken and not.- Before this, the harness stubbed the symbol's constructor while the
probe ran the port's (worklog 0149). So
dungeon_mc(the lakes' row 18) anditem_box(kind 4) failed. - All six tests now pass, and the symbol's constructor is checked against the game for the first time.
- Before this, the harness stubbed the symbol's constructor while the
probe ran the port's (worklog 0149). So
tools/test_effect_misc_rs.py.GruntyAgainstGamerunseffEvolvePGandeffGrowPGon moving characters: 30 cases, 141 generators, every slot each frame. It first caughtposT.- Sessions.
the_grunty_eats_and_grows: the young Grunty walks.InuMenuopens on it under the fixed camera and it sits. Three foods make it Little Grunty (row 155, size 6, its voice). Talk gives its line. Leaving brings the field camera and its walk back.the_grown_grunty_talks: row 145 from a record with kind 0, which starts over;OtonainuMenuopens, Talk and back.a_grunty_food_is_picked_up: a Golden Egg in area 26's dungeon calls out, FoodMenu takes it, it bursts, and key item 26 andfoodCountgo up.
- Shots.
grunty_shotssaves the walk, the menu, the change and the grown Little Grunty.grunty_food_shotssaves three foods lying there and one taken. - The rest. The workspace's tests pass, as do the world, town02, shadow, foe, sound, effect and field-UI harnesses.
The ride (ccPgAdultCheck, ccPuccigusoStart, ccPucciguso, pgRideFlag) is not ported. A field's WORLD_MAN::EntryGimmick (SetFood, and its magic portals and special objects) does not run in the port, so only the dungeons' foods appear. The Grunties' camera writes land after the entry control's list, a frame's NPCs later than the game's. runAway's one frame of checkHitResultAttlibute is not compared (the harness does not model the collision's last result). The growing-up particles and the foods' look are not compared with the console's pictures. ccGimSymbol's main is still not run in eemu.