From a612ef12a0a647fe0614f8003ce39448d46b02ef Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Mon, 18 Dec 2017 19:35:50 +0100 Subject: [PATCH] start working on trainer see --- asm/trainer_see.s | 161 ++++------------------------ data/trainer_see.s | 83 --------------- include/field_map_obj.h | 1 + include/pokenav.h | 1 + include/trainer_see.h | 2 +- ld_script.txt | 2 +- src/egg_hatch.c | 2 +- src/trainer_see.c | 228 +++++++++++++++++++++++++++++++++++++++- 8 files changed, 252 insertions(+), 228 deletions(-) delete mode 100644 data/trainer_see.s diff --git a/asm/trainer_see.s b/asm/trainer_see.s index 16398f9a4e..82e5f89cb0 100644 --- a/asm/trainer_see.s +++ b/asm/trainer_see.s @@ -5,127 +5,10 @@ .text - thumb_func_start CheckIfTrainerWantsBattle -@ u8 CheckIfTrainerWantsBattle(u8 trainerFieldObjectId) -CheckIfTrainerWantsBattle: @ 80B3D00 - push {r4-r7,lr} - mov r7, r9 - mov r6, r8 - push {r6,r7} - lsls r0, 24 - lsrs r5, r0, 24 - movs r0, 0x1 - mov r9, r0 - bl InTrainerHill - cmp r0, 0x1 - bne _080B3D1E - bl sub_81D62AC - b _080B3D24 -_080B3D1E: - adds r0, r5, 0 - bl GetFieldObjectScriptPointerByFieldObjectId -_080B3D24: - adds r7, r0, 0 - bl InBattlePyramid - lsls r0, 24 - cmp r0, 0 - beq _080B3D3E - adds r0, r5, 0 - bl GetBattlePyramidTrainerFlag -_080B3D36: - lsls r0, 24 -_080B3D38: - cmp r0, 0 - beq _080B3D56 - b _080B3DE0 -_080B3D3E: - bl InTrainerHill - cmp r0, 0x1 - bne _080B3D4E - adds r0, r5, 0 - bl GetTrainerHillTrainerFlag - b _080B3D36 -_080B3D4E: - adds r0, r7, 0 - bl GetTrainerFlagFromScriptPointer - b _080B3D38 -_080B3D56: - lsls r4, r5, 3 - adds r0, r4, r5 - lsls r0, 2 - ldr r1, =gMapObjects - adds r0, r1 - bl CheckIfTrainerCanApproachPlayer - lsls r0, 24 - lsrs r6, r0, 24 - mov r8, r4 - cmp r6, 0 - beq _080B3DE0 - ldrb r0, [r7, 0x1] - cmp r0, 0x4 - beq _080B3D7C - cmp r0, 0x7 - beq _080B3D7C - cmp r0, 0x6 - bne _080B3D8A -_080B3D7C: - bl GetMonsStateToDoubles_2 - lsls r0, 24 - cmp r0, 0 - bne _080B3DE0 - movs r1, 0x2 - mov r9, r1 -_080B3D8A: - ldr r2, =gApproachingTrainers - ldr r4, =gNoOfApproachingTrainers - ldrb r1, [r4] - lsls r0, r1, 1 - adds r0, r1 - lsls r0, 2 - adds r0, r2 - strb r5, [r0] - ldrb r1, [r4] - lsls r0, r1, 1 - adds r0, r1 - lsls r0, 2 - adds r1, r2, 0x4 - adds r0, r1 - str r7, [r0] - ldrb r1, [r4] - lsls r0, r1, 1 - adds r0, r1 - lsls r0, 2 - adds r0, r2 - strb r6, [r0, 0x1] - mov r1, r8 - adds r0, r1, r5 - lsls r0, 2 - ldr r1, =gMapObjects - adds r0, r1 - subs r1, r6, 0x1 - lsls r1, 24 - lsrs r1, 24 - bl TrainerApproachPlayer - ldrb r0, [r4] - adds r0, 0x1 - strb r0, [r4] - mov r0, r9 - b _080B3DE2 - .pool -_080B3DE0: - movs r0, 0 -_080B3DE2: - pop {r3,r4} - mov r8, r3 - mov r9, r4 - pop {r4-r7} - pop {r1} - bx r1 - thumb_func_end CheckIfTrainerWantsBattle - thumb_func_start CheckIfTrainerCanApproachPlayer -@ u8 CheckIfTrainerCanApproachPlayer(struct npc_state *trainerFieldObject) -CheckIfTrainerCanApproachPlayer: @ 80B3DF0 + thumb_func_start GetTrainerApproachDistance +@ u8 GetTrainerApproachDistance(struct npc_state *trainerFieldObject) +GetTrainerApproachDistance: @ 80B3DF0 push {r4-r7,lr} mov r7, r8 push {r7} @@ -140,7 +23,7 @@ CheckIfTrainerCanApproachPlayer: @ 80B3DF0 mov r8, r4 cmp r0, 0x1 bne _080B3E50 - ldr r1, =gIsTrainerInRange + ldr r1, =sDirectionalApproachDistanceFuncs ldrb r0, [r7, 0x18] lsls r0, 28 lsrs r0, 26 @@ -173,7 +56,7 @@ _080B3E4C: _080B3E50: movs r5, 0 _080B3E52: - ldr r0, =gIsTrainerInRange + ldr r0, =sDirectionalApproachDistanceFuncs lsls r4, r5, 2 adds r4, r0 ldrb r1, [r7, 0x1D] @@ -210,11 +93,11 @@ _080B3E90: pop {r1} bx r1 .pool - thumb_func_end CheckIfTrainerCanApproachPlayer + thumb_func_end GetTrainerApproachDistance - thumb_func_start IsTrainerInRangeSouth -@ u8 IsTrainerInRangeSouth(struct npc_state *trainerFieldObject, u16 sightRange, u16 playerX, u16 playerY) -IsTrainerInRangeSouth: @ 80B3EA0 + thumb_func_start GetTrainerApproachDistanceSouth +@ u8 GetTrainerApproachDistanceSouth(struct npc_state *trainerFieldObject, u16 sightRange, u16 playerX, u16 playerY) +GetTrainerApproachDistanceSouth: @ 80B3EA0 push {r4-r6,lr} adds r4, r0, 0 lsls r1, 16 @@ -250,11 +133,11 @@ _080B3EDC: pop {r4-r6} pop {r1} bx r1 - thumb_func_end IsTrainerInRangeSouth + thumb_func_end GetTrainerApproachDistanceSouth - thumb_func_start IsTrainerInRangeNorth -@ u8 IsTrainerInRangeNorth(struct npc_state *trainerFieldObject, u16 sightRange, u16 playerX, u16 playerY) -IsTrainerInRangeNorth: @ 80B3EE4 + thumb_func_start GetTrainerApproachDistanceNorth +@ u8 GetTrainerApproachDistanceNorth(struct npc_state *trainerFieldObject, u16 sightRange, u16 playerX, u16 playerY) +GetTrainerApproachDistanceNorth: @ 80B3EE4 push {r4-r6,lr} adds r4, r0, 0 lsls r1, 16 @@ -290,11 +173,11 @@ _080B3F20: pop {r4-r6} pop {r1} bx r1 - thumb_func_end IsTrainerInRangeNorth + thumb_func_end GetTrainerApproachDistanceNorth - thumb_func_start IsTrainerInRangeWest -@ u8 IsTrainerInRangeWest(struct npc_state *trainerFieldObject, u16 sightRange, u16 playerX, u16 playerY) -IsTrainerInRangeWest: @ 80B3F28 + thumb_func_start GetTrainerApproachDistanceWest +@ u8 GetTrainerApproachDistanceWest(struct npc_state *trainerFieldObject, u16 sightRange, u16 playerX, u16 playerY) +GetTrainerApproachDistanceWest: @ 80B3F28 push {r4-r6,lr} adds r4, r0, 0 lsls r1, 16 @@ -330,11 +213,11 @@ _080B3F64: pop {r4-r6} pop {r1} bx r1 - thumb_func_end IsTrainerInRangeWest + thumb_func_end GetTrainerApproachDistanceWest - thumb_func_start IsTrainerInRangeEast -@ u8 IsTrainerInRangeEast(struct npc_state *trainerFieldObject, u16 sightRange, u16 playerX, u16 playerY) -IsTrainerInRangeEast: @ 80B3F6C + thumb_func_start GetTrainerApproachDistanceEast +@ u8 GetTrainerApproachDistanceEast(struct npc_state *trainerFieldObject, u16 sightRange, u16 playerX, u16 playerY) +GetTrainerApproachDistanceEast: @ 80B3F6C push {r4-r6,lr} adds r4, r0, 0 lsls r1, 16 @@ -370,7 +253,7 @@ _080B3FA8: pop {r4-r6} pop {r1} bx r1 - thumb_func_end IsTrainerInRangeEast + thumb_func_end GetTrainerApproachDistanceEast thumb_func_start CheckPathBetweenTrainerAndPlayer @ u8 CheckPathBetweenTrainerAndPlayer(struct npc_state *fieldObject, u8 a2, u8 direction) diff --git a/data/trainer_see.s b/data/trainer_see.s deleted file mode 100644 index bff3004a78..0000000000 --- a/data/trainer_see.s +++ /dev/null @@ -1,83 +0,0 @@ - .include "asm/macros.inc" - .include "constants/constants.inc" - - .section .rodata - - .align 2 -gEmotion_ExclamationMarkGfx:: @ 85505AC - .incbin "graphics/misc/emotion_exclamation.4bpp" - - .align 2 -gEmotion_QuestionMarkGfx:: @ 855062C - .incbin "graphics/misc/emotion_question.4bpp" - - .align 2 -gEmotion_HeartGfx:: @ 85506AC - .incbin "graphics/misc/emotion_heart.4bpp" - - .align 2 -gIsTrainerInRange:: @ 855072C - .4byte IsTrainerInRangeSouth - .4byte IsTrainerInRangeNorth - .4byte IsTrainerInRangeWest - .4byte IsTrainerInRangeEast - - .align 2 -gTrainerSeeFuncList:: @ 855073C - .4byte sub_80B4178 - .4byte sub_80B417C - .4byte sub_80B41C0 - .4byte sub_80B4200 - .4byte sub_80B425C - .4byte sub_80B4318 - .4byte sub_80B435C - .4byte sub_80B4390 - .4byte sub_80B43AC - .4byte sub_80B43E0 - .4byte sub_80B4438 - .4byte sub_80B44AC - - .align 2 -gTrainerSeeFuncList2:: @ 855076C - .4byte sub_80B43AC - .4byte sub_80B43E0 - .4byte sub_80B4438 - .4byte sub_80B44AC - - .align 2 -gOamData_855077C:: @ 855077C - .2byte 0x0000 - .2byte 0x4000 - .2byte 0x0400 - - .align 2 -gSpriteImageTable_8550784:: @ 8550784 - obj_frame_tiles gEmotion_ExclamationMarkGfx, 0x0080 - obj_frame_tiles gEmotion_QuestionMarkGfx, 0x0080 - - .align 2 -gSpriteImageTable_8550794:: @ 8550794 - obj_frame_tiles gEmotion_HeartGfx, 0x0080 - - .align 2 -gSpriteAnim_855079C:: @ 855079C - obj_image_anim_frame 0, 60 - obj_image_anim_end - - .align 2 -gSpriteAnim_85507A4:: @ 85507A4 - obj_image_anim_frame 1, 60 - obj_image_anim_end - - .align 2 -gSpriteAnimTable_85507AC:: @ 85507AC - .4byte gSpriteAnim_855079C - .4byte gSpriteAnim_85507A4 - - .align 2 -gSpriteTemplate_85507B4:: @ 85507B4 - spr_template 0xffff, 0xffff, gOamData_855077C, gSpriteAnimTable_85507AC, gSpriteImageTable_8550784, gDummySpriteAffineAnimTable, objc_exclamation_mark_probably - - .align 2 -gSpriteTemplate_85507CC:: @ 85507CC - spr_template 0xffff, 0x1004, gOamData_855077C, gSpriteAnimTable_85507AC, gSpriteImageTable_8550794, gDummySpriteAffineAnimTable, objc_exclamation_mark_probably diff --git a/include/field_map_obj.h b/include/field_map_obj.h index 696d1c2e28..56ff1dba10 100755 --- a/include/field_map_obj.h +++ b/include/field_map_obj.h @@ -78,6 +78,7 @@ u8 FieldObjectClearAnimIfSpecialAnimFinished(struct MapObject *); u8 GetFieldObjectIdByXYZ(u16 x, u16 y, u8 z); void npc_set_running_behaviour_etc(struct MapObject *mapObject, u8 animPattern); u8 npc_running_behaviour_by_direction(u8 direction); +const u8 *GetFieldObjectScriptPointerByFieldObjectId(u8 mapObjectId); // Exported data declarations diff --git a/include/pokenav.h b/include/pokenav.h index 06676610a4..4335923c8e 100644 --- a/include/pokenav.h +++ b/include/pokenav.h @@ -2,5 +2,6 @@ #define GUARD_POKENAV_H bool8 sub_81D5C18(void); +const u8 *sub_81D62AC(void); #endif //GUARD_POKENAV_H diff --git a/include/trainer_see.h b/include/trainer_see.h index 5da50cfa13..0749e168a6 100644 --- a/include/trainer_see.h +++ b/include/trainer_see.h @@ -4,7 +4,7 @@ struct ApproachingTrainer { u8 mapObjectId; - u8 radius; + u8 radius; // plus 1 u8 field_2; u8 field_3; const u8 *trainerScriptPtr; diff --git a/ld_script.txt b/ld_script.txt index 4015c51fa0..07bce16a20 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -379,7 +379,7 @@ SECTIONS { data/field_screen.o(.rodata); src/battle_setup.o(.rodata); data/cable_club.o(.rodata); - data/trainer_see.o(.rodata); + src/trainer_see.o(.rodata); data/wild_encounter.o(.rodata); data/field_effect.o(.rodata); data/option_menu.o(.rodata); diff --git a/src/egg_hatch.c b/src/egg_hatch.c index a31eb0520e..9e9a192de7 100644 --- a/src/egg_hatch.c +++ b/src/egg_hatch.c @@ -91,7 +91,7 @@ static void CreateRandomEggShardSprite(void); static void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex); // IWRAM bss -static IWRAM_DATA struct EggHatchData* sEggHatchData; +static IWRAM_DATA struct EggHatchData *sEggHatchData; // rom data static const u16 sEggPalette[] = INCBIN_U16("graphics/pokemon/palettes/egg_palette.gbapal"); diff --git a/src/trainer_see.c b/src/trainer_see.c index b30f273478..b396d26e75 100644 --- a/src/trainer_see.c +++ b/src/trainer_see.c @@ -1,15 +1,158 @@ #include "global.h" #include "trainer_see.h" #include "battle_setup.h" +#include "pokemon.h" +#include "sprite.h" +#include "field_map_obj.h" +#include "pokenav.h" +#include "task.h" extern u8 gApproachingTrainerId; extern u8 gNoOfApproachingTrainers; extern u8 gUnknown_030060AC; extern u16 gUnknown_03006080; -// this file's functions -u8 CheckIfTrainerWantsBattle(u8 mapObjectId); +extern bool8 InBattlePyramid(void); +extern bool32 InTrainerHill(void); +extern bool8 GetBattlePyramidTrainerFlag(u8 mapObjectId); +extern bool8 GetTrainerHillTrainerFlag(u8 mapObjectId); +// this file's functions +static u8 CheckTrainer(u8 mapObjectId); +u8 GetTrainerApproachDistance(struct MapObject *trainerObj); +void TrainerApproachPlayer(struct MapObject *trainerObj, u8 radius); + +u8 GetTrainerApproachDistanceSouth(struct MapObject *trainerObj, s16 range, s16 x, s16 y); +u8 GetTrainerApproachDistanceNorth(struct MapObject *trainerObj, s16 range, s16 x, s16 y); +u8 GetTrainerApproachDistanceWest(struct MapObject *trainerObj, s16 range, s16 x, s16 y); +u8 GetTrainerApproachDistanceEast(struct MapObject *trainerObj, s16 range, s16 x, s16 y); + +bool8 sub_80B4178(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B417C(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B41C0(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B4200(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B425C(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B4318(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B435C(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B4390(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B43AC(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B43E0(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B4438(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B44AC(u8 taskId, struct Task *task, struct MapObject *trainerObj); + +bool8 sub_80B43AC(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B43E0(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B4438(u8 taskId, struct Task *task, struct MapObject *trainerObj); +bool8 sub_80B44AC(u8 taskId, struct Task *task, struct MapObject *trainerObj); + +void objc_exclamation_mark_probably(struct Sprite *sprite); + +// const rom data +const u8 gEmotion_ExclamationMarkGfx[] = INCBIN_U8("graphics/misc/emotion_exclamation.4bpp"); +const u8 gEmotion_QuestionMarkGfx[] = INCBIN_U8("graphics/misc/emotion_question.4bpp"); +const u8 gEmotion_HeartGfx[] = INCBIN_U8("graphics/misc/emotion_heart.4bpp"); + +u8 (*const sDirectionalApproachDistanceFuncs[])(struct MapObject *trainerObj, s16 range, s16 x, s16 y) = +{ + GetTrainerApproachDistanceSouth, + GetTrainerApproachDistanceNorth, + GetTrainerApproachDistanceWest, + GetTrainerApproachDistanceEast, +}; + +bool8 (*const gTrainerSeeFuncList[])(u8 taskId, struct Task *task, struct MapObject *trainerObj) = +{ + sub_80B4178, + sub_80B417C, + sub_80B41C0, + sub_80B4200, + sub_80B425C, + sub_80B4318, + sub_80B435C, + sub_80B4390, + sub_80B43AC, + sub_80B43E0, + sub_80B4438, + sub_80B44AC +}; + +bool8 (*const gTrainerSeeFuncList2[])(u8 taskId, struct Task *task, struct MapObject *trainerObj) = +{ + sub_80B43AC, + sub_80B43E0, + sub_80B4438, + sub_80B44AC, +}; + +const struct OamData gOamData_855077C = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 1, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +const struct SpriteFrameImage gSpriteImageTable_8550784[] = +{ + {gEmotion_ExclamationMarkGfx, 0x80}, + {gEmotion_QuestionMarkGfx, 0x80} +}; + +const struct SpriteFrameImage gSpriteImageTable_8550794[] = +{ + {gEmotion_HeartGfx, 0x80} +}; + +const union AnimCmd gSpriteAnim_855079C[] = +{ + ANIMCMD_FRAME(0, 60), + ANIMCMD_END +}; + +const union AnimCmd gSpriteAnim_85507A4[] = +{ + ANIMCMD_FRAME(1, 60), + ANIMCMD_END +}; + +const union AnimCmd *const gSpriteAnimTable_85507AC[] = +{ + gSpriteAnim_855079C, + gSpriteAnim_85507A4 +}; + +const struct SpriteTemplate gSpriteTemplate_85507B4 = +{ + .tileTag = 0xffff, + .paletteTag = 0xffff, + .oam = &gOamData_855077C, + .anims = gSpriteAnimTable_85507AC, + .images = gSpriteImageTable_8550784, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = objc_exclamation_mark_probably +}; + +const struct SpriteTemplate gSpriteTemplate_85507CC = +{ + .tileTag = 0xffff, + .paletteTag = 0x1004, + .oam = &gOamData_855077C, + .anims = gSpriteAnimTable_85507AC, + .images = gSpriteImageTable_8550794, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = objc_exclamation_mark_probably +}; + +// code bool8 CheckForTrainersWantingBattle(void) { u8 i; @@ -26,7 +169,7 @@ bool8 CheckForTrainersWantingBattle(void) if (gMapObjects[i].trainerType != 1 && gMapObjects[i].trainerType != 3) continue; - retVal = CheckIfTrainerWantsBattle(i); + retVal = CheckTrainer(i); if (retVal == 2) break; // two trainers have been found @@ -66,3 +209,82 @@ bool8 CheckForTrainersWantingBattle(void) return FALSE; } } + +static u8 CheckTrainer(u8 mapObjectId) +{ + const u8 *scriptPtr; + u8 ret = 1; + u8 approachDistance; + + if (InTrainerHill() == TRUE) + scriptPtr = sub_81D62AC(); + else + scriptPtr = GetFieldObjectScriptPointerByFieldObjectId(mapObjectId); + + if (InBattlePyramid()) + { + if (GetBattlePyramidTrainerFlag(mapObjectId)) + return 0; + } + else if (InTrainerHill() == TRUE) + { + if (GetTrainerHillTrainerFlag(mapObjectId)) + return 0; + } + else + { + if (GetTrainerFlagFromScriptPointer(scriptPtr)) + return 0; + } + + approachDistance = GetTrainerApproachDistance(&gMapObjects[mapObjectId]); + + if (approachDistance != 0) + { + if (scriptPtr[1] == TRAINER_BATTLE_DOUBLE + || scriptPtr[1] == TRAINER_BATTLE_REMATCH_DOUBLE + || scriptPtr[1] == TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE) + { + if (GetMonsStateToDoubles_2() != 0) + return 0; + + ret = 2; + } + + gApproachingTrainers[gNoOfApproachingTrainers].mapObjectId = mapObjectId; + gApproachingTrainers[gNoOfApproachingTrainers].trainerScriptPtr = scriptPtr; + gApproachingTrainers[gNoOfApproachingTrainers].radius = approachDistance; + TrainerApproachPlayer(&gMapObjects[mapObjectId], approachDistance - 1); + gNoOfApproachingTrainers++; + + return ret; + } + + return 0; +} + +/* +u8 GetTrainerApproachDistance(struct MapObject *trainerObj) +{ + s16 x, y; + u8 i; + u8 approachDistance; + + PlayerGetDestCoords(&x, &y); + if (trainerObj->trainerType == 1) // can only see in one direction + { + approachDistance = sDirectionalApproachDistanceFuncs[trainerObj->mapobj_unk_18 - 1](trainerObj, trainerObj->trainerRange_berryTreeId, x, y); + return CheckPathBetweenTrainerAndPlayer((struct MapObject2 *)trainerObj, approachDistance, trainerObj->mapobj_unk_18); + } + else // can see in all directions + { + for (i = 0; i < 4; i++) + { + approachDistance = sDirectionalApproachDistanceFuncs[i](trainerObj, trainerObj->trainerRange_berryTreeId, x, y); + if (CheckPathBetweenTrainerAndPlayer((struct MapObject2 *)trainerObj, approachDistance, i + 1)) // directions are 1-4 instead of 0-3. south north west east + return approachDistance; + } + } + return 0; +} +*/