From 63dd0ea397ff01787753f182541ed8324f2d498b Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 6 Sep 2017 08:35:16 -0400 Subject: Spawn source files for Field Map Obj --- src/field_map_obj.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/field_map_obj.c (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c new file mode 100644 index 000000000..ec9a7c002 --- /dev/null +++ b/src/field_map_obj.c @@ -0,0 +1,16 @@ +// Includes + +#include "global.h" +#include "field_map_obj.h" + +// Static struct declarations + +// Static RAM declarations + +// Static ROM declarations + +// ROM data + +// Code + + -- cgit v1.2.3 From 83dbdc031856410b8b1b9154900cfcb5c069ec46 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 6 Sep 2017 08:46:47 -0400 Subject: npc_clear_ids_and_state --- src/field_map_obj.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index ec9a7c002..9451863b4 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -13,4 +13,11 @@ // Code - +void npc_clear_ids_and_state(struct MapObject *mapObject) +{ + memset(mapObject, 0, sizeof(struct MapObject)); + mapObject->localId = 0xFF; + mapObject->mapNum = -1; + mapObject->mapGroup = -1; + mapObject->mapobj_unk_1C = -1; +} -- cgit v1.2.3 From f677873d07dddd9eb43f1a9070bf9b2ac5f61749 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 09:25:16 -0400 Subject: npcs_clear_ids_and_state --- src/field_map_obj.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 9451863b4..193182775 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -21,3 +21,12 @@ void npc_clear_ids_and_state(struct MapObject *mapObject) mapObject->mapGroup = -1; mapObject->mapobj_unk_1C = -1; } + +void npcs_clear_ids_and_state(void) +{ + u8 i; + for (i = 0; i < ARRAY_COUNT(gUnknown_02037350); i ++) + { + npc_clear_ids_and_state(&gUnknown_02037350[i]); + } +} -- cgit v1.2.3 From a08f11cab32bf4e2557f33fd275ec8c7b4f165c9 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 09:29:59 -0400 Subject: sub_808D438 --- src/field_map_obj.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 193182775..fd4a19397 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1,6 +1,9 @@ // Includes #include "global.h" +#include "sprite.h" +#include "rom4.h" +#include "field_player_avatar.h" #include "field_map_obj.h" // Static struct declarations @@ -9,11 +12,13 @@ // Static ROM declarations +void sub_808D450(void); + // ROM data // Code -void npc_clear_ids_and_state(struct MapObject *mapObject) +/*static*/ void npc_clear_ids_and_state(struct MapObject *mapObject) { memset(mapObject, 0, sizeof(struct MapObject)); mapObject->localId = 0xFF; @@ -22,7 +27,7 @@ void npc_clear_ids_and_state(struct MapObject *mapObject) mapObject->mapobj_unk_1C = -1; } -void npcs_clear_ids_and_state(void) +static void npcs_clear_ids_and_state(void) { u8 i; for (i = 0; i < ARRAY_COUNT(gUnknown_02037350); i ++) @@ -30,3 +35,11 @@ void npcs_clear_ids_and_state(void) npc_clear_ids_and_state(&gUnknown_02037350[i]); } } + +void sub_808D438(void) +{ + strange_npc_table_clear(); + npcs_clear_ids_and_state(); + ClearPlayerAvatarInfo(); + sub_808D450(); +} -- cgit v1.2.3 From 368b0f9ee8500c5f15d511c827d8b59795fab82b Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 09:38:38 -0400 Subject: sub_808D450 --- src/field_map_obj.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index fd4a19397..7b5731e68 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -12,7 +12,7 @@ // Static ROM declarations -void sub_808D450(void); +/*static*/ void sub_808D450(void); // ROM data @@ -43,3 +43,20 @@ void sub_808D438(void) ClearPlayerAvatarInfo(); sub_808D450(); } + +/*static*/ void sub_808D450(void) +{ + u8 spriteIdx; + + spriteIdx = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[21], 0, 0, 31); + gSprites[spriteIdx].oam.affineMode = 1; + InitSpriteAffineAnim(&gSprites[spriteIdx]); + StartSpriteAffineAnim(&gSprites[spriteIdx], 0); + gSprites[spriteIdx].invisible = TRUE; + + spriteIdx = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[21], 0, 0, 31); + gSprites[spriteIdx].oam.affineMode = 1; + InitSpriteAffineAnim(&gSprites[spriteIdx]); + StartSpriteAffineAnim(&gSprites[spriteIdx], 1); + gSprites[spriteIdx].invisible = TRUE; +} -- cgit v1.2.3 From f3f8c5ec2c476aa6db557f30dc830d6b4f9bc741 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 09:42:10 -0400 Subject: sub_808D4F4 --- src/field_map_obj.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 7b5731e68..46cc0585c 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -30,6 +30,7 @@ static void npcs_clear_ids_and_state(void) { u8 i; + for (i = 0; i < ARRAY_COUNT(gUnknown_02037350); i ++) { npc_clear_ids_and_state(&gUnknown_02037350[i]); @@ -60,3 +61,17 @@ void sub_808D438(void) StartSpriteAffineAnim(&gSprites[spriteIdx], 1); gSprites[spriteIdx].invisible = TRUE; } + +u8 sub_808D4F4(void) +{ + u8 i; + + for (i = 0; i < ARRAY_COUNT(gUnknown_02037350); i ++) + { + if (!gUnknown_02037350[i].active) + { + break; + } + } + return i; +} -- cgit v1.2.3 From ea9dabdfab6d2a28d9119c2c23db43903ad4ecae Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 09:49:51 -0400 Subject: TryGetFieldObjectIdByLocalIdAndMap --- src/field_map_obj.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 46cc0585c..61b915878 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -13,6 +13,8 @@ // Static ROM declarations /*static*/ void sub_808D450(void); +/*static*/ u8 GetFieldObjectIdByLocalId(u8); +/*static*/ u8 GetFieldObjectIdByLocalIdAndMapInternal(u8, u8, u8); // ROM data @@ -75,3 +77,22 @@ u8 sub_808D4F4(void) } return i; } + +u8 GetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapId, u8 mapGroupId) +{ + if (localId < 0xff) + { + return GetFieldObjectIdByLocalIdAndMapInternal(localId, mapId, mapGroupId); + } + return GetFieldObjectIdByLocalId(localId); +} + +bool8 TryGetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapId, u8 mapGroupId, u8 *fieldObjectId) +{ + *fieldObjectId = GetFieldObjectIdByLocalIdAndMap(localId, mapId, mapGroupId); + if (*fieldObjectId == 16) + { + return TRUE; + } + return FALSE; +} -- cgit v1.2.3 From f15191bfc28effef4155b26186bd4236182b88aa Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 09:52:31 -0400 Subject: GetFieldObjectIdByXY --- src/field_map_obj.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 61b915878..88b9d7eab 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -90,9 +90,22 @@ u8 GetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapId, u8 mapGroupId) bool8 TryGetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapId, u8 mapGroupId, u8 *fieldObjectId) { *fieldObjectId = GetFieldObjectIdByLocalIdAndMap(localId, mapId, mapGroupId); - if (*fieldObjectId == 16) + if (*fieldObjectId == ARRAY_COUNT(gUnknown_02037350)) { return TRUE; } return FALSE; } + +u8 GetFieldObjectIdByXY(s16 x, s16 y) +{ + u8 i; + for (i = 0; i < ARRAY_COUNT(gUnknown_02037350); i ++) + { + if (gUnknown_02037350[i].active && gUnknown_02037350[i].coords2.x == x && gUnknown_02037350[i].coords2.y == y) + { + break; + } + } + return i; +} -- cgit v1.2.3 From 1087d1c8227fbcdb768bc96b96c969dd2c9cb598 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 10:48:51 -0400 Subject: GetFieldObjectIdByLocalIdAndMapInternal; rename gUnknown_02037350 to gMapObjects --- src/field_map_obj.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 88b9d7eab..1b4ba0b7f 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -33,9 +33,9 @@ static void npcs_clear_ids_and_state(void) { u8 i; - for (i = 0; i < ARRAY_COUNT(gUnknown_02037350); i ++) + for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) { - npc_clear_ids_and_state(&gUnknown_02037350[i]); + npc_clear_ids_and_state(&gMapObjects[i]); } } @@ -68,9 +68,9 @@ u8 sub_808D4F4(void) { u8 i; - for (i = 0; i < ARRAY_COUNT(gUnknown_02037350); i ++) + for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) { - if (!gUnknown_02037350[i].active) + if (!gMapObjects[i].active) { break; } @@ -90,7 +90,7 @@ u8 GetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapId, u8 mapGroupId) bool8 TryGetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapId, u8 mapGroupId, u8 *fieldObjectId) { *fieldObjectId = GetFieldObjectIdByLocalIdAndMap(localId, mapId, mapGroupId); - if (*fieldObjectId == ARRAY_COUNT(gUnknown_02037350)) + if (*fieldObjectId == ARRAY_COUNT(gMapObjects)) { return TRUE; } @@ -100,12 +100,27 @@ bool8 TryGetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapId, u8 mapGroupId, u8 u8 GetFieldObjectIdByXY(s16 x, s16 y) { u8 i; - for (i = 0; i < ARRAY_COUNT(gUnknown_02037350); i ++) + + for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) { - if (gUnknown_02037350[i].active && gUnknown_02037350[i].coords2.x == x && gUnknown_02037350[i].coords2.y == y) + if (gMapObjects[i].active && gMapObjects[i].coords2.x == x && gMapObjects[i].coords2.y == y) { break; } } return i; } + +u8 GetFieldObjectIdByLocalIdAndMapInternal(u8 localId, u8 mapId, u8 mapGroupId) +{ + u8 i; + + for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + { + if (gMapObjects[i].active && gMapObjects[i].localId == localId && gMapObjects[i].mapNum == mapId && gMapObjects[i].mapGroup == mapGroupId) + { + return i; + } + } + return ARRAY_COUNT(gMapObjects); +} -- cgit v1.2.3 From 9498dfa71c811b09f319bc9c9656c08f3182c9dc Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 14:25:17 -0400 Subject: InitFieldObjectStateFromTemplate (nonmatching, same as ruby) --- src/field_map_obj.c | 230 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 229 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 1b4ba0b7f..b97d5c0dc 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -15,14 +15,19 @@ /*static*/ void sub_808D450(void); /*static*/ u8 GetFieldObjectIdByLocalId(u8); /*static*/ u8 GetFieldObjectIdByLocalIdAndMapInternal(u8, u8, u8); +/*static*/ bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); +/*static*/ void FieldObjectHandleDynamicGraphicsId(struct MapObject *); // ROM data +const u8 gUnknown_085055CD[0x53]; +const u8 gUnknown_0850557C[0x51]; + // Code /*static*/ void npc_clear_ids_and_state(struct MapObject *mapObject) { - memset(mapObject, 0, sizeof(struct MapObject)); + *mapObject = (struct MapObject){}; mapObject->localId = 0xFF; mapObject->mapNum = -1; mapObject->mapGroup = -1; @@ -124,3 +129,226 @@ u8 GetFieldObjectIdByLocalIdAndMapInternal(u8 localId, u8 mapId, u8 mapGroupId) } return ARRAY_COUNT(gMapObjects); } + +u8 GetFieldObjectIdByLocalId(u8 localId) +{ + u8 i; + + for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + { + if (gMapObjects[i].active && gMapObjects[i].localId == localId) + { + return i; + } + } + return ARRAY_COUNT(gMapObjects); +} + +// This function has the same nonmatching quirk as in Ruby/Sapphire. +#ifdef NONMATCHING +u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) +{ + u8 slot; + struct MapObject *mapObject; + u16 x; + u16 y; + + if (GetAvailableFieldObjectSlot(template->localId, mapId, mapGroupId, &slot)) + { + return ARRAY_COUNT(gMapObjects); + } + mapObject = &gMapObjects[slot]; + npc_clear_ids_and_state(mapObject); + x = template->x + 7; + y = template->y + 7; + mapObject->active = TRUE; + mapObject->mapobj_bit_2 = TRUE; + mapObject->graphicsId = template->graphicsId; + mapObject->animPattern = template->movementType; + mapObject->localId = template->localId; + mapObject->mapNum = mapId; + mapObject->mapGroup = mapGroupId; + mapObject->coords1.x = x; + mapObject->coords1.y = y; + mapObject->coords2.x = x; + mapObject->coords2.y = y; + mapObject->coords3.x = x; + mapObject->coords3.y = y; + mapObject->mapobj_unk_0B_0 = template->elevation; + mapObject->elevation = template->elevation; + mapObject->mapobj_unk_19 = template->unkA_0; + mapObject->mapobj_unk_19b = template->unkA_4; + mapObject->trainerType = template->unkC; + mapObject->trainerRange_berryTreeId = template->unkE; + mapObject->mapobj_unk_20 = gUnknown_085055CD[template->movementType]; + FieldObjectSetDirection(mapObject, mapObject->mapobj_unk_20); + FieldObjectHandleDynamicGraphicsId(mapObject); + if (gUnknown_0850557C[mapObject->animPattern]) + { + if (mapObject->mapobj_unk_19 == 0) + { + mapObject->mapobj_unk_19 ++; + } + if (mapObject->mapobj_unk_19b == 0) + { + mapObject->mapobj_unk_19b ++; + } + } + return slot; +} +#else +__attribute__((naked)) u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tmov r7, r9\n" + "\tmov r6, r8\n" + "\tpush {r6,r7}\n" + "\tsub sp, 0x4\n" + "\tadds r5, r0, 0\n" + "\tlsls r1, 24\n" + "\tlsrs r6, r1, 24\n" + "\tlsls r2, 24\n" + "\tlsrs r7, r2, 24\n" + "\tldrb r0, [r5]\n" + "\tadds r1, r6, 0\n" + "\tadds r2, r7, 0\n" + "\tmov r3, sp\n" + "\tbl GetAvailableFieldObjectSlot\n" + "\tlsls r0, 24\n" + "\tcmp r0, 0\n" + "\tbeq _0808D66E\n" + "\tmovs r0, 0x10\n" + "\tb _0808D762\n" + "_0808D66E:\n" + "\tmov r0, sp\n" + "\tldrb r1, [r0]\n" + "\tlsls r0, r1, 3\n" + "\tadds r0, r1\n" + "\tlsls r0, 2\n" + "\tldr r1, =gMapObjects\n" + "\tadds r4, r0, r1\n" + "\tadds r0, r4, 0\n" + "\tbl npc_clear_ids_and_state\n" + "\tldrh r3, [r5, 0x4]\n" + "\tadds r3, 0x7\n" + "\tlsls r3, 16\n" + "\tlsrs r3, 16\n" + "\tldrh r2, [r5, 0x6]\n" + "\tadds r2, 0x7\n" + "\tlsls r2, 16\n" + "\tlsrs r2, 16\n" + "\tldrb r0, [r4]\n" + "\tmovs r1, 0x1\n" + "\torrs r0, r1\n" + "\tmovs r1, 0x4\n" + "\torrs r0, r1\n" + "\tstrb r0, [r4]\n" + "\tldrb r0, [r5, 0x1]\n" + "\tstrb r0, [r4, 0x5]\n" + "\tldrb r0, [r5, 0x9]\n" + "\tstrb r0, [r4, 0x6]\n" + "\tldrb r0, [r5]\n" + "\tstrb r0, [r4, 0x8]\n" + "\tstrb r6, [r4, 0x9]\n" + "\tstrb r7, [r4, 0xA]\n" + "\tstrh r3, [r4, 0xC]\n" + "\tstrh r2, [r4, 0xE]\n" + "\tstrh r3, [r4, 0x10]\n" + "\tstrh r2, [r4, 0x12]\n" + "\tstrh r3, [r4, 0x14]\n" + "\tstrh r2, [r4, 0x16]\n" + "\tldrb r0, [r5, 0x8]\n" + "\tmovs r7, 0xF\n" + "\tadds r1, r7, 0\n" + "\tands r1, r0\n" + "\tldrb r2, [r4, 0xB]\n" + "\tmovs r0, 0x10\n" + "\tnegs r0, r0\n" + "\tmov r8, r0\n" + "\tands r0, r2\n" + "\torrs r0, r1\n" + "\tstrb r0, [r4, 0xB]\n" + "\tldrb r1, [r5, 0x8]\n" + "\tlsls r1, 4\n" + "\tands r0, r7\n" + "\torrs r0, r1\n" + "\tstrb r0, [r4, 0xB]\n" + "\tldrb r1, [r5, 0xA]\n" + "\tlsls r1, 28\n" + "\tmovs r0, 0xF\n" + "\tmov r9, r0\n" + "\tlsrs r1, 28\n" + "\tldrb r2, [r4, 0x19]\n" + "\tmov r0, r8\n" + "\tands r0, r2\n" + "\torrs r0, r1\n" + "\tstrb r0, [r4, 0x19]\n" + "\tldrb r1, [r5, 0xA]\n" + "\tlsrs r1, 4\n" + "\tlsls r1, 4\n" + "\tands r0, r7\n" + "\torrs r0, r1\n" + "\tstrb r0, [r4, 0x19]\n" + "\tldrh r0, [r5, 0xC]\n" + "\tstrb r0, [r4, 0x7]\n" + "\tldrh r0, [r5, 0xE]\n" + "\tstrb r0, [r4, 0x1D]\n" + "\tldr r1, =gUnknown_085055CD\n" + "\tldrb r0, [r5, 0x9]\n" + "\tadds r0, r1\n" + "\tldrb r1, [r0]\n" + "\tadds r0, r4, 0\n" + "\tadds r0, 0x20\n" + "\tstrb r1, [r0]\n" + "\tldrb r1, [r0]\n" + "\tadds r0, r4, 0\n" + "\tbl FieldObjectSetDirection\n" + "\tadds r0, r4, 0\n" + "\tbl FieldObjectHandleDynamicGraphicsId\n" + "\tldr r1, =gUnknown_0850557C\n" + "\tldrb r0, [r4, 0x6]\n" + "\tadds r0, r1\n" + "\tldrb r0, [r0]\n" + "\tcmp r0, 0\n" + "\tbeq _0808D75E\n" + "\tldrb r2, [r4, 0x19]\n" + "\tadds r0, r7, 0\n" + "\tands r0, r2\n" + "\tcmp r0, 0\n" + "\tbne _0808D746\n" + "\tlsls r0, r2, 28\n" + "\tlsrs r0, 28\n" + "\tadds r0, 0x1\n" + "\tmov r1, r9\n" + "\tands r0, r1\n" + "\tmov r1, r8\n" + "\tands r1, r2\n" + "\torrs r1, r0\n" + "\tstrb r1, [r4, 0x19]\n" + "_0808D746:\n" + "\tldrb r2, [r4, 0x19]\n" + "\tmovs r0, 0xF0\n" + "\tands r0, r2\n" + "\tcmp r0, 0\n" + "\tbne _0808D75E\n" + "\tlsrs r1, r2, 4\n" + "\tadds r1, 0x1\n" + "\tlsls r1, 4\n" + "\tadds r0, r7, 0\n" + "\tands r0, r2\n" + "\torrs r0, r1\n" + "\tstrb r0, [r4, 0x19]\n" + "_0808D75E:\n" + "\tmov r0, sp\n" + "\tldrb r0, [r0]\n" + "_0808D762:\n" + "\tadd sp, 0x4\n" + "\tpop {r3,r4}\n" + "\tmov r8, r3\n" + "\tmov r9, r4\n" + "\tpop {r4-r7}\n" + "\tpop {r1}\n" + "\tbx r1\n" + ".pool"); +} +#endif -- cgit v1.2.3 From 6448563ede13d51682cbf1988a2072291f3b3df0 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 16:14:55 -0400 Subject: unref_sub_808D77C --- src/field_map_obj.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index b97d5c0dc..b33cf0669 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4,6 +4,9 @@ #include "sprite.h" #include "rom4.h" #include "field_player_avatar.h" +#include "event_data.h" +#include "rom_818CFC8.h" +#include "rom_81BE66C.h" #include "field_map_obj.h" // Static struct declarations @@ -352,3 +355,35 @@ __attribute__((naked)) u8 InitFieldObjectStateFromTemplate(struct MapObjectTempl ".pool"); } #endif + +u8 unref_sub_808D77C(u8 localId) +{ + u8 i; + u8 nObjects; + struct MapObjectTemplate *template; + + if (gMapHeader.events != NULL) + { + if (InBattlePyramid()) + { + nObjects = sub_81AAA40(); + } + else if (InTrainerHill()) + { + nObjects = 2; + } + else + { + nObjects = gMapHeader.events->mapObjectCount; + } + for (i = 0; i < nObjects; i ++) + { + template = &gSaveBlock1Ptr->mapObjectTemplates[i]; + if (template->localId == localId && !FlagGet(template->flagId)) + { + return InitFieldObjectStateFromTemplate(template, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); + } + } + } + return ARRAY_COUNT(gMapObjects); +} -- cgit v1.2.3 From e0601236483588158e08dd83da3d6cb8ee491420 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 17:25:20 -0400 Subject: GetAvailableFieldObjectSlot --- src/field_map_obj.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index b33cf0669..28f001b5d 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -387,3 +387,26 @@ u8 unref_sub_808D77C(u8 localId) } return ARRAY_COUNT(gMapObjects); } + +bool8 GetAvailableFieldObjectSlot(u16 localId, u8 mapNum, u8 mapGroup, u8 *result) +{ + u8 i = 0; + + for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + { + if (!gMapObjects[i].active) + break; + if (gMapObjects[i].localId == localId && gMapObjects[i].mapNum == mapNum && gMapObjects[i].mapGroup == mapGroup) + return TRUE; + } + if (i >= ARRAY_COUNT(gMapObjects)) + return TRUE; + *result = i; + do + { + if (gMapObjects[i].active && gMapObjects[i].localId == localId && gMapObjects[i].mapNum == mapNum && gMapObjects[i].mapGroup == mapGroup) + return TRUE; + i ++; + } while (i < ARRAY_COUNT(gMapObjects)); + return FALSE; +} -- cgit v1.2.3 From a6269f2f0f94d93b834aae8e15a3dea6789b30c0 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 17:29:13 -0400 Subject: Static --- src/field_map_obj.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 28f001b5d..0a2f6dbea 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -16,9 +16,9 @@ // Static ROM declarations /*static*/ void sub_808D450(void); -/*static*/ u8 GetFieldObjectIdByLocalId(u8); -/*static*/ u8 GetFieldObjectIdByLocalIdAndMapInternal(u8, u8, u8); -/*static*/ bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); +static u8 GetFieldObjectIdByLocalId(u8); +static u8 GetFieldObjectIdByLocalIdAndMapInternal(u8, u8, u8); +static bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); /*static*/ void FieldObjectHandleDynamicGraphicsId(struct MapObject *); // ROM data @@ -28,7 +28,7 @@ const u8 gUnknown_0850557C[0x51]; // Code -/*static*/ void npc_clear_ids_and_state(struct MapObject *mapObject) +static void npc_clear_ids_and_state(struct MapObject *mapObject) { *mapObject = (struct MapObject){}; mapObject->localId = 0xFF; @@ -119,7 +119,7 @@ u8 GetFieldObjectIdByXY(s16 x, s16 y) return i; } -u8 GetFieldObjectIdByLocalIdAndMapInternal(u8 localId, u8 mapId, u8 mapGroupId) +static u8 GetFieldObjectIdByLocalIdAndMapInternal(u8 localId, u8 mapId, u8 mapGroupId) { u8 i; @@ -388,7 +388,12 @@ u8 unref_sub_808D77C(u8 localId) return ARRAY_COUNT(gMapObjects); } -bool8 GetAvailableFieldObjectSlot(u16 localId, u8 mapNum, u8 mapGroup, u8 *result) +static bool8 GetAvailableFieldObjectSlot(u16 localId, u8 mapNum, u8 mapGroup, u8 *result) +// Looks for an empty slot. +// Returns FALSE and the location of the available slot +// in *result. +// If no slots are available, or if the object is already +// loaded, returns TRUE. { u8 i = 0; -- cgit v1.2.3 From 942400ddbf15ca8ac9d56279e971dd6f4e1c800d Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 17:55:36 -0400 Subject: RemoveFieldObject --- src/field_map_obj.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 0a2f6dbea..7420895ab 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -20,6 +20,7 @@ static u8 GetFieldObjectIdByLocalId(u8); static u8 GetFieldObjectIdByLocalIdAndMapInternal(u8, u8, u8); static bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); /*static*/ void FieldObjectHandleDynamicGraphicsId(struct MapObject *); +/*static*/ void RemoveFieldObjectInternal (struct MapObject *); // ROM data @@ -415,3 +416,9 @@ static bool8 GetAvailableFieldObjectSlot(u16 localId, u8 mapNum, u8 mapGroup, u8 } while (i < ARRAY_COUNT(gMapObjects)); return FALSE; } + +void RemoveFieldObject(struct MapObject *mapObject) +{ + mapObject->active = FALSE; + RemoveFieldObjectInternal(mapObject); +} -- cgit v1.2.3 From 398186d7c42b009218ff1fea17f7b474e1c6389e Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 18:12:44 -0400 Subject: RemoveFieldObjectInternal --- src/field_map_obj.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 7420895ab..52f798f9b 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -21,6 +21,8 @@ static u8 GetFieldObjectIdByLocalIdAndMapInternal(u8, u8, u8); static bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); /*static*/ void FieldObjectHandleDynamicGraphicsId(struct MapObject *); /*static*/ void RemoveFieldObjectInternal (struct MapObject *); +/*static*/ u16 GetFieldObjectFlagIdByFieldObjectId(u8); +/*static*/ struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8); // ROM data @@ -422,3 +424,21 @@ void RemoveFieldObject(struct MapObject *mapObject) mapObject->active = FALSE; RemoveFieldObjectInternal(mapObject); } + +void RemoveFieldObjectByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup) +{ + u8 index; + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &index)) + { + FlagSet(GetFieldObjectFlagIdByFieldObjectId(index)); + RemoveFieldObject(&gMapObjects[index]); + } +} + +void RemoveFieldObjectInternal(struct MapObject *mapObject) +{ + struct SpriteFrameImage image; + image.size = GetFieldObjectGraphicsInfo(mapObject->graphicsId)->size; + gSprites[mapObject->spriteId].images = ℑ + DestroySprite(&gSprites[mapObject->spriteId]); +} -- cgit v1.2.3 From e0216d60459fac28bf6759159a4c4cfa007bf6c2 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 6 Sep 2017 18:26:37 -0400 Subject: unref_sub_808D958 --- src/field_map_obj.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 52f798f9b..6e15d3e86 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -15,12 +15,12 @@ // Static ROM declarations -/*static*/ void sub_808D450(void); +void sub_808D450(void); static u8 GetFieldObjectIdByLocalId(u8); static u8 GetFieldObjectIdByLocalIdAndMapInternal(u8, u8, u8); static bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); /*static*/ void FieldObjectHandleDynamicGraphicsId(struct MapObject *); -/*static*/ void RemoveFieldObjectInternal (struct MapObject *); +static void RemoveFieldObjectInternal (struct MapObject *); /*static*/ u16 GetFieldObjectFlagIdByFieldObjectId(u8); /*static*/ struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8); @@ -136,7 +136,7 @@ static u8 GetFieldObjectIdByLocalIdAndMapInternal(u8 localId, u8 mapId, u8 mapGr return ARRAY_COUNT(gMapObjects); } -u8 GetFieldObjectIdByLocalId(u8 localId) +static u8 GetFieldObjectIdByLocalId(u8 localId) { u8 i; @@ -152,7 +152,7 @@ u8 GetFieldObjectIdByLocalId(u8 localId) // This function has the same nonmatching quirk as in Ruby/Sapphire. #ifdef NONMATCHING -u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) +/*static*/ u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) { u8 slot; struct MapObject *mapObject; @@ -203,7 +203,7 @@ u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId return slot; } #else -__attribute__((naked)) u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) +/*static*/ __attribute__((naked)) u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) { asm_unified("\tpush {r4-r7,lr}\n" "\tmov r7, r9\n" @@ -435,10 +435,23 @@ void RemoveFieldObjectByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup) } } -void RemoveFieldObjectInternal(struct MapObject *mapObject) +static void RemoveFieldObjectInternal(struct MapObject *mapObject) { struct SpriteFrameImage image; image.size = GetFieldObjectGraphicsInfo(mapObject->graphicsId)->size; gSprites[mapObject->spriteId].images = ℑ DestroySprite(&gSprites[mapObject->spriteId]); } + +void unref_sub_808D958(void) +{ + u8 i; + + for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + { + if (i != gPlayerAvatar.mapObjectId) + { + RemoveFieldObject(&gMapObjects[i]); + } + } +} -- cgit v1.2.3 From b79e3af0a8aaed5528e57c965101aa4c0b59bad1 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 6 Sep 2017 20:28:36 -0400 Subject: SpawnFieldObjectInternal --- src/field_map_obj.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 6e15d3e86..a3fb1a5d3 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -7,6 +7,7 @@ #include "event_data.h" #include "rom_818CFC8.h" #include "rom_81BE66C.h" +#include "field_ground_effect.h" #include "field_map_obj.h" // Static struct declarations @@ -23,6 +24,7 @@ static bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); static void RemoveFieldObjectInternal (struct MapObject *); /*static*/ u16 GetFieldObjectFlagIdByFieldObjectId(u8); /*static*/ struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8); +void sub_8096518(struct MapObject *, struct Sprite *); // ROM data @@ -455,3 +457,64 @@ void unref_sub_808D958(void) } } } + +u8 SpawnFieldObjectInternal(struct MapObjectTemplate *mapObjectTemplate, struct SpriteTemplate *spriteTemplate, u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY) +{ + struct MapObject *mapObject; + struct MapObjectGraphicsInfo *graphicsInfo; + struct Sprite *sprite; + u8 mapObjectId; + u8 paletteSlot; + u8 spriteId; + + mapObjectId = InitFieldObjectStateFromTemplate(mapObjectTemplate, mapNum, mapGroup); + if (mapObjectId == ARRAY_COUNT(gMapObjects)) + { + return ARRAY_COUNT(gMapObjects); + } + mapObject = &gMapObjects[mapObjectId]; + graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId); + paletteSlot = graphicsInfo->paletteSlot; + if (paletteSlot == 0) + { + npc_load_two_palettes__no_record(graphicsInfo->paletteTag1, 0); + } + else if (paletteSlot == 10) + { + npc_load_two_palettes__and_record(graphicsInfo->paletteTag1, 10); + } + else if (paletteSlot >= 16) + { + paletteSlot -= 16; + sub_808EAB0(graphicsInfo->paletteTag1, paletteSlot); + } + if (mapObject->animPattern == 0x4c) + { + mapObject->mapobj_bit_13 = TRUE; + } + *(u16 *)&spriteTemplate->paletteTag = 0xFFFF; + spriteId = CreateSprite(spriteTemplate, 0, 0, 0); + if (spriteId == MAX_SPRITES) + { + gMapObjects[mapObjectId].active = FALSE; + return ARRAY_COUNT(gMapObjects); + } + sprite = &gSprites[spriteId]; + sub_8092FF0(mapObject->coords2.x + cameraX, mapObject->coords2.y + cameraY, &sprite->pos1.x, &sprite->pos1.y); + sprite->centerToCornerVecX = -(graphicsInfo->width >> 1); + sprite->centerToCornerVecY = -(graphicsInfo->height >> 1); + sprite->pos1.x += 8; + sprite->pos1.y += 16 + sprite->centerToCornerVecY; + sprite->oam.paletteNum = paletteSlot; + sprite->coordOffsetEnabled = TRUE; + sprite->data0 = mapObjectId; + mapObject->spriteId = spriteId; + mapObject->mapobj_bit_12 = graphicsInfo->inanimate; + if (!mapObject->mapobj_bit_12) + { + StartSpriteAnim(sprite, FieldObjectDirectionToImageAnimId(mapObject->mapobj_unk_18)); + } + SetObjectSubpriorityByZCoord(mapObject->elevation, sprite, 1); + sub_8096518(mapObject, sprite); + return mapObjectId; +} -- cgit v1.2.3 From bd4b3c4c6da148415e8c5ebeb8c72455776a5f19 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 6 Sep 2017 21:46:53 -0400 Subject: SpawnFieldObject --- src/field_map_obj.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index a3fb1a5d3..8b78a54a1 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -23,8 +23,9 @@ static bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); /*static*/ void FieldObjectHandleDynamicGraphicsId(struct MapObject *); static void RemoveFieldObjectInternal (struct MapObject *); /*static*/ u16 GetFieldObjectFlagIdByFieldObjectId(u8); -/*static*/ struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8); +/*static*/ const struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8); void sub_8096518(struct MapObject *, struct Sprite *); +/*static*/ void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *, struct SpriteTemplate *, const struct SubspriteTable **); // ROM data @@ -461,7 +462,7 @@ void unref_sub_808D958(void) u8 SpawnFieldObjectInternal(struct MapObjectTemplate *mapObjectTemplate, struct SpriteTemplate *spriteTemplate, u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY) { struct MapObject *mapObject; - struct MapObjectGraphicsInfo *graphicsInfo; + const struct MapObjectGraphicsInfo *graphicsInfo; struct Sprite *sprite; u8 mapObjectId; u8 paletteSlot; @@ -518,3 +519,29 @@ u8 SpawnFieldObjectInternal(struct MapObjectTemplate *mapObjectTemplate, struct sub_8096518(mapObject, sprite); return mapObjectId; } + +u8 SpawnFieldObject(struct MapObjectTemplate *mapObjectTemplate, u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY) +{ + const struct MapObjectGraphicsInfo *graphicsInfo; + struct SpriteTemplate spriteTemplate; + const struct SubspriteTable *subspriteTable; + struct SpriteFrameImage spriteFrameImage; + u8 mapObjectId; + + subspriteTable = NULL; + graphicsInfo = GetFieldObjectGraphicsInfo(mapObjectTemplate->graphicsId); + MakeObjectTemplateFromFieldObjectTemplate(mapObjectTemplate, &spriteTemplate, &subspriteTable); + spriteFrameImage.size = graphicsInfo->size; + spriteTemplate.images = &spriteFrameImage; + mapObjectId = SpawnFieldObjectInternal(mapObjectTemplate, &spriteTemplate, mapNum, mapGroup, cameraX, cameraY); + if (mapObjectId == ARRAY_COUNT(gMapObjects)) + { + return ARRAY_COUNT(gMapObjects); + } + gSprites[gMapObjects[mapObjectId].spriteId].images = graphicsInfo->images; + if (subspriteTable != NULL) + { + SetSubspriteTables(&gSprites[gMapObjects[mapObjectId].spriteId], subspriteTable); + } + return mapObjectId; +} -- cgit v1.2.3 From 22c836795669b9c7d2d244dc4f0becaabfe6a198 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 6 Sep 2017 22:00:51 -0400 Subject: SpawnSpecialFieldObject --- src/field_map_obj.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 8b78a54a1..9c25e148a 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -26,6 +26,7 @@ static void RemoveFieldObjectInternal (struct MapObject *); /*static*/ const struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8); void sub_8096518(struct MapObject *, struct Sprite *); /*static*/ void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *, struct SpriteTemplate *, const struct SubspriteTable **); +/*static*/ void GetFieldObjectMovingCameraOffset(s16 *, s16 *); // ROM data @@ -545,3 +546,12 @@ u8 SpawnFieldObject(struct MapObjectTemplate *mapObjectTemplate, u8 mapNum, u8 m } return mapObjectId; } + +u8 SpawnSpecialFieldObject(struct MapObjectTemplate *mapObjectTemplate) +{ + s16 cameraX; + s16 cameraY; + + GetFieldObjectMovingCameraOffset(&cameraX, &cameraY); + return SpawnFieldObject(mapObjectTemplate, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, cameraX, cameraY); +} -- cgit v1.2.3 From 1f83a2885e540dbf473e3f5200e35f5fc6df96b3 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 6 Sep 2017 22:33:11 -0400 Subject: Through MakeObjectTemplateFromFieldObjectGraphicsInfo --- src/field_map_obj.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 9c25e148a..e6376d156 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -27,6 +27,7 @@ static void RemoveFieldObjectInternal (struct MapObject *); void sub_8096518(struct MapObject *, struct Sprite *); /*static*/ void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *, struct SpriteTemplate *, const struct SubspriteTable **); /*static*/ void GetFieldObjectMovingCameraOffset(s16 *, s16 *); +/*static*/ struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8, u8, u8); // ROM data @@ -525,13 +526,13 @@ u8 SpawnFieldObject(struct MapObjectTemplate *mapObjectTemplate, u8 mapNum, u8 m { const struct MapObjectGraphicsInfo *graphicsInfo; struct SpriteTemplate spriteTemplate; - const struct SubspriteTable *subspriteTable; + const struct SubspriteTable *subspriteTables; struct SpriteFrameImage spriteFrameImage; u8 mapObjectId; - subspriteTable = NULL; + subspriteTables = NULL; graphicsInfo = GetFieldObjectGraphicsInfo(mapObjectTemplate->graphicsId); - MakeObjectTemplateFromFieldObjectTemplate(mapObjectTemplate, &spriteTemplate, &subspriteTable); + MakeObjectTemplateFromFieldObjectTemplate(mapObjectTemplate, &spriteTemplate, &subspriteTables); spriteFrameImage.size = graphicsInfo->size; spriteTemplate.images = &spriteFrameImage; mapObjectId = SpawnFieldObjectInternal(mapObjectTemplate, &spriteTemplate, mapNum, mapGroup, cameraX, cameraY); @@ -540,9 +541,9 @@ u8 SpawnFieldObject(struct MapObjectTemplate *mapObjectTemplate, u8 mapNum, u8 m return ARRAY_COUNT(gMapObjects); } gSprites[gMapObjects[mapObjectId].spriteId].images = graphicsInfo->images; - if (subspriteTable != NULL) + if (subspriteTables != NULL) { - SetSubspriteTables(&gSprites[gMapObjects[mapObjectId].spriteId], subspriteTable); + SetSubspriteTables(&gSprites[gMapObjects[mapObjectId].spriteId], subspriteTables); } return mapObjectId; } @@ -555,3 +556,52 @@ u8 SpawnSpecialFieldObject(struct MapObjectTemplate *mapObjectTemplate) GetFieldObjectMovingCameraOffset(&cameraX, &cameraY); return SpawnFieldObject(mapObjectTemplate, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, cameraX, cameraY); } + +u8 SpawnSpecialFieldObjectParametrized(u8 graphicsId, u8 movementBehavior, u8 localId, s16 x, s16 y, u8 z) +{ + struct MapObjectTemplate mapObjectTemplate; + + x -= 7; + y -= 7; + mapObjectTemplate.localId = localId; + mapObjectTemplate.graphicsId = graphicsId; + mapObjectTemplate.unk2 = 0; + mapObjectTemplate.x = x; + mapObjectTemplate.y = y; + mapObjectTemplate.elevation = z; + mapObjectTemplate.movementType = movementBehavior; + mapObjectTemplate.unkA_0 = 0; + mapObjectTemplate.unkA_4 = 0; + mapObjectTemplate.unkC = 0; + mapObjectTemplate.unkE = 0; + return SpawnSpecialFieldObject(&mapObjectTemplate); +} + +u8 show_sprite(u8 localId, u8 mapNum, u8 mapGroup) +{ + struct MapObjectTemplate *mapObjectTemplate; + s16 cameraX; + s16 cameraY; + + mapObjectTemplate = GetFieldObjectTemplateByLocalIdAndMap(localId, mapNum, mapGroup); + if (mapObjectTemplate == NULL) + { + return ARRAY_COUNT(gMapObjects); + } + GetFieldObjectMovingCameraOffset(&cameraX, &cameraY); + return SpawnFieldObject(mapObjectTemplate, mapNum, mapGroup, cameraX, cameraY); +} + +void MakeObjectTemplateFromFieldObjectGraphicsInfo(u16 graphicsId, void (*callback)(struct Sprite *), struct SpriteTemplate *sprTemplate, const struct SubspriteTable **subspriteTables) +{ + const struct MapObjectGraphicsInfo *gfxInfo = GetFieldObjectGraphicsInfo(graphicsId); + + sprTemplate->tileTag = gfxInfo->tileTag; + sprTemplate->paletteTag = gfxInfo->paletteTag1; + sprTemplate->oam = gfxInfo->oam; + sprTemplate->anims = gfxInfo->anims; + sprTemplate->images = gfxInfo->images; + sprTemplate->affineAnims = gfxInfo->affineAnims; + sprTemplate->callback = callback; + *subspriteTables = gfxInfo->subspriteTables; +} -- cgit v1.2.3 From 112177b57f6f5ca95cd97bbe7a9a86924b341e5c Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 6 Sep 2017 22:46:44 -0400 Subject: Slight touching up of data3.s; denote boundaries of data/field_map_obj.s for future split --- src/field_map_obj.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index e6376d156..e3e0b7158 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -10,6 +10,8 @@ #include "field_ground_effect.h" #include "field_map_obj.h" +#define NUM_FIELD_MAP_OBJECT_TEMPLATES 0x51 + // Static struct declarations // Static RAM declarations @@ -31,8 +33,9 @@ void sub_8096518(struct MapObject *, struct Sprite *); // ROM data -const u8 gUnknown_085055CD[0x53]; -const u8 gUnknown_0850557C[0x51]; +void (*const gUnknown_08505438[NUM_FIELD_MAP_OBJECT_TEMPLATES])(struct Sprite *); +const u8 gUnknown_0850557C[NUM_FIELD_MAP_OBJECT_TEMPLATES]; +const u8 gUnknown_085055CD[NUM_FIELD_MAP_OBJECT_TEMPLATES]; // Code @@ -605,3 +608,8 @@ void MakeObjectTemplateFromFieldObjectGraphicsInfo(u16 graphicsId, void (*callba sprTemplate->callback = callback; *subspriteTables = gfxInfo->subspriteTables; } + +void MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(u16 graphicsId, u16 callbackIndex, struct SpriteTemplate *sprTemplate, const struct SubspriteTable **subspriteTables) +{ + MakeObjectTemplateFromFieldObjectGraphicsInfo(graphicsId, gUnknown_08505438[callbackIndex], sprTemplate, subspriteTables); +} -- cgit v1.2.3 From 12562aa2d42e1692aff319b091258d5c24a9e040 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 14:16:30 -0400 Subject: MakeObjectTemplateFromFieldObjectTemplate --- src/field_map_obj.c | 5 +++++ src/malloc.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index e3e0b7158..819721773 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -613,3 +613,8 @@ void MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(u16 graphics { MakeObjectTemplateFromFieldObjectGraphicsInfo(graphicsId, gUnknown_08505438[callbackIndex], sprTemplate, subspriteTables); } + +void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *mapObjectTemplate, struct SpriteTemplate *spriteTemplate, const struct SubspriteTable **subspriteTables) +{ + MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(mapObjectTemplate->graphicsId, mapObjectTemplate->movementType, spriteTemplate, subspriteTables); +} diff --git a/src/malloc.c b/src/malloc.c index 948303c6f..5317565dc 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -40,7 +40,7 @@ void PutMemBlockHeader(void *block, struct MemBlock *prev, struct MemBlock *next void PutFirstMemBlockHeader(void *block, u32 size) { - PutMemBlockHeader(block, (struct MemBlock *)block, (struct MemBlock *)block, size - 16); + PutMemBlockHeader(block, (struct MemBlock *)block, (struct MemBlock *)block, size - sizeof(struct MemBlock)); } void *AllocInternal(void *heapStart, u32 size) @@ -50,6 +50,7 @@ void *AllocInternal(void *heapStart, u32 size) struct MemBlock *splitBlock; u32 foundBlockSize; + // Alignment if (size & 3) size = 4 * ((size / 4) + 1); @@ -60,7 +61,7 @@ void *AllocInternal(void *heapStart, u32 size) foundBlockSize = pos->size; if (foundBlockSize >= size) { - if (foundBlockSize - size <= 31) { + if (foundBlockSize - size < 2 * sizeof(struct MemBlock)) { // The block isn't much bigger than the requested size, // so just use it. pos->flag = TRUE; -- cgit v1.2.3 From f7742a68ae57ffa9e7b965c6cc816f7977b9e467 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 14:31:23 -0400 Subject: AddPseudoFieldObject --- src/field_map_obj.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 819721773..c434ee7db 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1,6 +1,7 @@ // Includes #include "global.h" +#include "malloc.h" #include "sprite.h" #include "rom4.h" #include "field_player_avatar.h" @@ -30,6 +31,7 @@ void sub_8096518(struct MapObject *, struct Sprite *); /*static*/ void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *, struct SpriteTemplate *, const struct SubspriteTable **); /*static*/ void GetFieldObjectMovingCameraOffset(s16 *, s16 *); /*static*/ struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8, u8, u8); +/*static*/ void sub_808E894(u16); // ROM data @@ -618,3 +620,28 @@ void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *mapObje { MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(mapObjectTemplate->graphicsId, mapObjectTemplate->movementType, spriteTemplate, subspriteTables); } + +u8 AddPseudoFieldObject(u16 graphicsId, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority) +{ + struct SpriteTemplate *spriteTemplate; + const struct SubspriteTable *subspriteTables; + struct Sprite *sprite; + u8 spriteIdx; + + spriteTemplate = malloc(sizeof(struct SpriteTemplate)); + MakeObjectTemplateFromFieldObjectGraphicsInfo(graphicsId, callback, spriteTemplate, &subspriteTables); + if (spriteTemplate->paletteTag != 0xffff) + { + sub_808E894(spriteTemplate->paletteTag); + } + spriteIdx = CreateSprite(spriteTemplate, x, y, subpriority); + free(spriteTemplate); + + if (spriteIdx != MAX_SPRITES && subspriteTables != NULL) + { + sprite = &gSprites[spriteIdx]; + SetSubspriteTables(sprite, subspriteTables); + sprite->subspriteMode = 2; + } + return spriteIdx; +} -- cgit v1.2.3 From 64ebd9b4fb54fae34a8f7cebb14588b89693d4a3 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 15:50:49 -0400 Subject: sprite_new --- src/field_map_obj.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index c434ee7db..82e74747d 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -9,6 +9,7 @@ #include "rom_818CFC8.h" #include "rom_81BE66C.h" #include "field_ground_effect.h" +#include "map_obj_8097404.h" #include "field_map_obj.h" #define NUM_FIELD_MAP_OBJECT_TEMPLATES 0x51 @@ -645,3 +646,52 @@ u8 AddPseudoFieldObject(u16 graphicsId, void (*callback)(struct Sprite *), s16 x } return spriteIdx; } + +u8 sprite_new(u8 graphicsId, u8 a1, s16 x, s16 y, u8 z, u8 direction) +{ + const struct MapObjectGraphicsInfo *graphicsInfo; + struct SpriteTemplate spriteTemplate; + const struct SubspriteTable *subspriteTables; + u8 spriteId; + struct Sprite *sprite; + + graphicsInfo = GetFieldObjectGraphicsInfo(graphicsId); + MakeObjectTemplateFromFieldObjectGraphicsInfo(graphicsId, sub_8097AC8, &spriteTemplate, &subspriteTables); + *(u16 *)&spriteTemplate.paletteTag = 0xffff; + x += 7; + y += 7; + sub_80930E0(&x, &y, 8, 16); + spriteId = CreateSpriteAtEnd(&spriteTemplate, x, y, 0); + if (spriteId != MAX_SPRITES) + { + sprite = &gSprites[spriteId]; + sprite->centerToCornerVecX = -(graphicsInfo->width >> 1); + sprite->centerToCornerVecY = -(graphicsInfo->height >> 1); + sprite->pos1.y += sprite->centerToCornerVecY; + sprite->oam.paletteNum = graphicsInfo->paletteSlot; + if (sprite->oam.paletteNum >= 16) + { + sprite->oam.paletteNum -= 16; + } + sprite->coordOffsetEnabled = TRUE; + sprite->data0 = a1; + sprite->data1 = z; + if (graphicsInfo->paletteSlot == 10) + { + npc_load_two_palettes__and_record(graphicsInfo->paletteTag1, graphicsInfo->paletteSlot); + } + else if (graphicsInfo->paletteSlot >= 16) + { + sub_808EAB0(graphicsInfo->paletteTag1, graphicsInfo->paletteSlot | 0xf0); + } + if (subspriteTables != NULL) + { + SetSubspriteTables(sprite, subspriteTables); + sprite->subspriteMode = 2; + } + InitObjectPriorityByZCoord(sprite, z); + SetObjectSubpriorityByZCoord(z, sprite, 1); + StartSpriteAnim(sprite, FieldObjectDirectionToImageAnimId(direction)); + } + return spriteId; +} -- cgit v1.2.3 From f128e4c4f0e1214801178e643223a77d8ec904f8 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 15:58:38 -0400 Subject: SpawnFieldObjectsInView --- src/field_map_obj.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 82e74747d..b6a7f9c9a 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -695,3 +695,47 @@ u8 sprite_new(u8 graphicsId, u8 a1, s16 x, s16 y, u8 z, u8 direction) } return spriteId; } + +void SpawnFieldObjectsInView(s16 cameraX, s16 cameraY) +{ + u8 i; + s16 left; + s16 right; + s16 top; + s16 bottom; + u8 objectCount; + s16 npcX; + s16 npcY; + + if (gMapHeader.events != NULL) + { + left = gSaveBlock1Ptr->pos.x - 2; + right = gSaveBlock1Ptr->pos.x + 17; + top = gSaveBlock1Ptr->pos.y; + bottom = gSaveBlock1Ptr->pos.y + 16; + + if (InBattlePyramid()) + { + objectCount = sub_81AAA40(); + } + else if (InTrainerHill()) + { + objectCount = 2; + } + else + { + objectCount = gMapHeader.events->mapObjectCount; + } + + for (i = 0; i < objectCount; i++) + { + struct MapObjectTemplate *template = &gSaveBlock1Ptr->mapObjectTemplates[i]; + npcX = template->x + 7; + npcY = template->y + 7; + + if (top <= npcY && bottom >= npcY && left <= npcX && right >= npcX + && !FlagGet(template->flagId)) + SpawnFieldObject(template, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, cameraX, cameraY); + } + } +} -- cgit v1.2.3 From 341a4735bc3e702104574055b97f1d691668bc14 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 16:09:59 -0400 Subject: RemoveFieldObjectsOutsideView --- src/field_map_obj.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index b6a7f9c9a..0d04c4063 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -33,6 +33,7 @@ void sub_8096518(struct MapObject *, struct Sprite *); /*static*/ void GetFieldObjectMovingCameraOffset(s16 *, s16 *); /*static*/ struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8, u8, u8); /*static*/ void sub_808E894(u16); +/*static*/ void RemoveFieldObjectIfOutsideView(struct MapObject *mapObject); // ROM data @@ -739,3 +740,27 @@ void SpawnFieldObjectsInView(s16 cameraX, s16 cameraY) } } } + +void RemoveFieldObjectsOutsideView(void) +{ + u8 i; + u8 j; + bool8 isActiveLinkPlayer; + struct MapObject *mapObject; + + for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + { + for (j = 0, isActiveLinkPlayer = FALSE; j < ARRAY_COUNT(gLinkPlayerMapObjects); j ++) + { + if (gLinkPlayerMapObjects[j].active && i == gLinkPlayerMapObjects[j].mapObjId) + isActiveLinkPlayer = TRUE; + } + if (!isActiveLinkPlayer) + { + mapObject = &gMapObjects[i]; + + if (mapObject->active && !mapObject->mapobj_bit_16) + RemoveFieldObjectIfOutsideView(mapObject); + } + } +} -- cgit v1.2.3 From 44be18e1dfc9a0eb58159b219762b3397d89e449 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 17:41:56 -0400 Subject: RemoveFieldObjectIfOutsideView --- src/field_map_obj.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 0d04c4063..caf43ce6a 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -764,3 +764,24 @@ void RemoveFieldObjectsOutsideView(void) } } } + +void RemoveFieldObjectIfOutsideView(struct MapObject *mapObject) +{ + s16 left; + s16 right; + s16 top; + s16 bottom; + + left = gSaveBlock1Ptr->pos.x - 2; + right = gSaveBlock1Ptr->pos.x + 17; + top = gSaveBlock1Ptr->pos.y; + bottom = gSaveBlock1Ptr->pos.y + 16; + + if (mapObject->coords2.x >= left && mapObject->coords2.x <= right + && mapObject->coords2.y >= top && mapObject->coords2.y <= bottom) + return; + if (mapObject->coords1.x >= left && mapObject->coords1.x <= right + && mapObject->coords1.y >= top && mapObject->coords1.y <= bottom) + return; + RemoveFieldObject(mapObject); +} -- cgit v1.2.3 From 113482a7cc748d80526de6b981887c5eca30f6b5 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 18:54:51 -0400 Subject: sub_808E16C --- src/field_map_obj.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index caf43ce6a..3e3f22a45 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -34,6 +34,7 @@ void sub_8096518(struct MapObject *, struct Sprite *); /*static*/ struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8, u8, u8); /*static*/ void sub_808E894(u16); /*static*/ void RemoveFieldObjectIfOutsideView(struct MapObject *mapObject); +/*static*/ void sub_808E1B8(u8, s16, s16); // ROM data @@ -785,3 +786,18 @@ void RemoveFieldObjectIfOutsideView(struct MapObject *mapObject) return; RemoveFieldObject(mapObject); } + +void sub_808E16C(s16 x, s16 y) +{ + u8 i; + + ClearPlayerAvatarInfo(); + for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + { + if (gMapObjects[i].active) + { + sub_808E1B8(i, x, y); + } + } + sub_808D450(); +} -- cgit v1.2.3 From de8ef5e12599098abd71c97f654192f6a8cbe900 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 19:28:46 -0400 Subject: sub_808E1B8 --- src/field_map_obj.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 3e3f22a45..69aa2b8f8 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -10,6 +10,7 @@ #include "rom_81BE66C.h" #include "field_ground_effect.h" #include "map_obj_8097404.h" +#include "field_effect_helpers.h" #include "field_map_obj.h" #define NUM_FIELD_MAP_OBJECT_TEMPLATES 0x51 @@ -33,8 +34,10 @@ void sub_8096518(struct MapObject *, struct Sprite *); /*static*/ void GetFieldObjectMovingCameraOffset(s16 *, s16 *); /*static*/ struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8, u8, u8); /*static*/ void sub_808E894(u16); -/*static*/ void RemoveFieldObjectIfOutsideView(struct MapObject *mapObject); -/*static*/ void sub_808E1B8(u8, s16, s16); +/*static*/ void RemoveFieldObjectIfOutsideView(struct MapObject *); +static void sub_808E1B8(u8, s16, s16); +/*static*/ void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8); +/*static*/ void sub_808E38C(struct MapObject *); // ROM data @@ -801,3 +804,78 @@ void sub_808E16C(s16 x, s16 y) } sub_808D450(); } + +static void sub_808E1B8(u8 mapObjectId, s16 x, s16 y) +{ + u8 spriteId; + u8 paletteSlot; + struct MapObject *mapObject; + const struct SubspriteTable *subspriteTables; + const struct MapObjectGraphicsInfo *graphicsInfo; + struct SpriteFrameImage spriteFrameImage; + struct SpriteTemplate spriteTemplate; + struct Sprite *sprite; + +#define i spriteId + for (i = 0; i < ARRAY_COUNT(gLinkPlayerMapObjects); i ++) + { + if (gLinkPlayerMapObjects[i].active && mapObjectId == gLinkPlayerMapObjects[i].mapObjId) + { + return; + } + } +#undef i + + mapObject = &gMapObjects[mapObjectId]; + subspriteTables = NULL; + graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId); + spriteFrameImage.size = graphicsInfo->size; + MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(mapObject->graphicsId, mapObject->animPattern, &spriteTemplate, &subspriteTables); + spriteTemplate.images = &spriteFrameImage; + *(u16 *)&spriteTemplate.paletteTag = 0xffff; + paletteSlot = graphicsInfo->paletteSlot; + if (paletteSlot == 0) + { + npc_load_two_palettes__no_record(graphicsInfo->paletteTag1, graphicsInfo->paletteSlot); + } + else if (paletteSlot == 10) + { + npc_load_two_palettes__and_record(graphicsInfo->paletteTag1, graphicsInfo->paletteSlot); + } + else if (paletteSlot >= 16) + { + paletteSlot -= 16; + sub_808EAB0(graphicsInfo->paletteTag1, paletteSlot); + } + *(u16 *)&spriteTemplate.paletteTag = 0xffff; + spriteId = CreateSprite(&spriteTemplate, 0, 0, 0); + if (spriteId != MAX_SPRITES) + { + sprite = &gSprites[spriteId]; + sub_8092FF0(x + mapObject->coords2.x, y + mapObject->coords2.y, &sprite->pos1.x, &sprite->pos1.y); + sprite->centerToCornerVecX = -(graphicsInfo->width >> 1); + sprite->centerToCornerVecY = -(graphicsInfo->height >> 1); + sprite->pos1.x += 8; + sprite->pos1.y += 16 + sprite->centerToCornerVecY; + sprite->images = graphicsInfo->images; + if (mapObject->animPattern == 0x0b) + { + SetPlayerAvatarFieldObjectIdAndObjectId(mapObjectId, spriteId); + mapObject->mapobj_unk_1B = sub_8154228(); + } + if (subspriteTables != NULL) + { + SetSubspriteTables(sprite, subspriteTables); + } + sprite->oam.paletteNum = paletteSlot; + sprite->coordOffsetEnabled = TRUE; + sprite->data0 = mapObjectId; + mapObject->spriteId = spriteId; + if (!mapObject->mapobj_bit_12 && mapObject->animPattern != 0x0b) + { + StartSpriteAnim(sprite, FieldObjectDirectionToImageAnimId(mapObject->mapobj_unk_18)); + } + sub_808E38C(mapObject); + SetObjectSubpriorityByZCoord(mapObject->elevation, sprite, 1); + } +} -- cgit v1.2.3 From 11786cc325937ce4c0a37b3db40df26dcd785018 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 19:45:30 -0400 Subject: sub_808E38C --- src/field_map_obj.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 69aa2b8f8..469993068 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -21,7 +21,7 @@ // Static ROM declarations -void sub_808D450(void); +static void sub_808D450(void); static u8 GetFieldObjectIdByLocalId(u8); static u8 GetFieldObjectIdByLocalIdAndMapInternal(u8, u8, u8); static bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); @@ -30,11 +30,11 @@ static void RemoveFieldObjectInternal (struct MapObject *); /*static*/ u16 GetFieldObjectFlagIdByFieldObjectId(u8); /*static*/ const struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8); void sub_8096518(struct MapObject *, struct Sprite *); -/*static*/ void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *, struct SpriteTemplate *, const struct SubspriteTable **); +static void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *, struct SpriteTemplate *, const struct SubspriteTable **); /*static*/ void GetFieldObjectMovingCameraOffset(s16 *, s16 *); /*static*/ struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8, u8, u8); /*static*/ void sub_808E894(u16); -/*static*/ void RemoveFieldObjectIfOutsideView(struct MapObject *); +static void RemoveFieldObjectIfOutsideView(struct MapObject *); static void sub_808E1B8(u8, s16, s16); /*static*/ void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8); /*static*/ void sub_808E38C(struct MapObject *); @@ -74,7 +74,7 @@ void sub_808D438(void) sub_808D450(); } -/*static*/ void sub_808D450(void) +static void sub_808D450(void) { u8 spriteIdx; @@ -168,7 +168,7 @@ static u8 GetFieldObjectIdByLocalId(u8 localId) // This function has the same nonmatching quirk as in Ruby/Sapphire. #ifdef NONMATCHING -/*static*/ u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) +static u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) { u8 slot; struct MapObject *mapObject; @@ -219,7 +219,7 @@ static u8 GetFieldObjectIdByLocalId(u8 localId) return slot; } #else -/*static*/ __attribute__((naked)) u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) +static __attribute__((naked)) u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) { asm_unified("\tpush {r4-r7,lr}\n" "\tmov r7, r9\n" @@ -435,7 +435,7 @@ static bool8 GetAvailableFieldObjectSlot(u16 localId, u8 mapNum, u8 mapGroup, u8 return FALSE; } -void RemoveFieldObject(struct MapObject *mapObject) +static void RemoveFieldObject(struct MapObject *mapObject) { mapObject->active = FALSE; RemoveFieldObjectInternal(mapObject); @@ -472,7 +472,7 @@ void unref_sub_808D958(void) } } -u8 SpawnFieldObjectInternal(struct MapObjectTemplate *mapObjectTemplate, struct SpriteTemplate *spriteTemplate, u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY) +static u8 SpawnFieldObjectInternal(struct MapObjectTemplate *mapObjectTemplate, struct SpriteTemplate *spriteTemplate, u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY) { struct MapObject *mapObject; const struct MapObjectGraphicsInfo *graphicsInfo; @@ -533,7 +533,7 @@ u8 SpawnFieldObjectInternal(struct MapObjectTemplate *mapObjectTemplate, struct return mapObjectId; } -u8 SpawnFieldObject(struct MapObjectTemplate *mapObjectTemplate, u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY) +static u8 SpawnFieldObject(struct MapObjectTemplate *mapObjectTemplate, u8 mapNum, u8 mapGroup, s16 cameraX, s16 cameraY) { const struct MapObjectGraphicsInfo *graphicsInfo; struct SpriteTemplate spriteTemplate; @@ -603,7 +603,7 @@ u8 show_sprite(u8 localId, u8 mapNum, u8 mapGroup) return SpawnFieldObject(mapObjectTemplate, mapNum, mapGroup, cameraX, cameraY); } -void MakeObjectTemplateFromFieldObjectGraphicsInfo(u16 graphicsId, void (*callback)(struct Sprite *), struct SpriteTemplate *sprTemplate, const struct SubspriteTable **subspriteTables) +static void MakeObjectTemplateFromFieldObjectGraphicsInfo(u16 graphicsId, void (*callback)(struct Sprite *), struct SpriteTemplate *sprTemplate, const struct SubspriteTable **subspriteTables) { const struct MapObjectGraphicsInfo *gfxInfo = GetFieldObjectGraphicsInfo(graphicsId); @@ -617,12 +617,12 @@ void MakeObjectTemplateFromFieldObjectGraphicsInfo(u16 graphicsId, void (*callba *subspriteTables = gfxInfo->subspriteTables; } -void MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(u16 graphicsId, u16 callbackIndex, struct SpriteTemplate *sprTemplate, const struct SubspriteTable **subspriteTables) +static void MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(u16 graphicsId, u16 callbackIndex, struct SpriteTemplate *sprTemplate, const struct SubspriteTable **subspriteTables) { MakeObjectTemplateFromFieldObjectGraphicsInfo(graphicsId, gUnknown_08505438[callbackIndex], sprTemplate, subspriteTables); } -void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *mapObjectTemplate, struct SpriteTemplate *spriteTemplate, const struct SubspriteTable **subspriteTables) +static void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *mapObjectTemplate, struct SpriteTemplate *spriteTemplate, const struct SubspriteTable **subspriteTables) { MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(mapObjectTemplate->graphicsId, mapObjectTemplate->movementType, spriteTemplate, subspriteTables); } @@ -745,7 +745,7 @@ void SpawnFieldObjectsInView(s16 cameraX, s16 cameraY) } } -void RemoveFieldObjectsOutsideView(void) +/*static*/ void RemoveFieldObjectsOutsideView(void) { u8 i; u8 j; @@ -769,7 +769,7 @@ void RemoveFieldObjectsOutsideView(void) } } -void RemoveFieldObjectIfOutsideView(struct MapObject *mapObject) +static void RemoveFieldObjectIfOutsideView(struct MapObject *mapObject) { s16 left; s16 right; @@ -879,3 +879,16 @@ static void sub_808E1B8(u8 mapObjectId, s16 x, s16 y) SetObjectSubpriorityByZCoord(mapObject->elevation, sprite, 1); } } + +/*static*/ void sub_808E38C(struct MapObject *mapObject) +{ + mapObject->mapobj_bit_1 = FALSE; + mapObject->mapobj_bit_2 = TRUE; + mapObject->mapobj_bit_22 = FALSE; + mapObject->mapobj_bit_17 = FALSE; + mapObject->mapobj_bit_18 = FALSE; + mapObject->mapobj_bit_19 = FALSE; + mapObject->mapobj_bit_20 = FALSE; + mapObject->mapobj_bit_21 = FALSE; + FieldObjectClearAnim(mapObject); +} -- cgit v1.2.3 From f8e8adf82ec56e986ece7a5eb6de87977ce2f506 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 20:04:59 -0400 Subject: SetPlayerAvatarFieldObjectIdAndObjectId --- src/field_map_obj.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 469993068..53dd1a863 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -36,7 +36,7 @@ static void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate * /*static*/ void sub_808E894(u16); static void RemoveFieldObjectIfOutsideView(struct MapObject *); static void sub_808E1B8(u8, s16, s16); -/*static*/ void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8); +static void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8); /*static*/ void sub_808E38C(struct MapObject *); // ROM data @@ -205,6 +205,8 @@ static u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u mapObject->mapobj_unk_20 = gUnknown_085055CD[template->movementType]; FieldObjectSetDirection(mapObject, mapObject->mapobj_unk_20); FieldObjectHandleDynamicGraphicsId(mapObject); + + // This block is the culprit if (gUnknown_0850557C[mapObject->animPattern]) { if (mapObject->mapobj_unk_19 == 0) @@ -892,3 +894,11 @@ static void sub_808E1B8(u8 mapObjectId, s16 x, s16 y) mapObject->mapobj_bit_21 = FALSE; FieldObjectClearAnim(mapObject); } + +static void SetPlayerAvatarFieldObjectIdAndObjectId(u8 mapObjectId, u8 spriteId) +{ + gPlayerAvatar.mapObjectId = mapObjectId; + gPlayerAvatar.spriteId = spriteId; + gPlayerAvatar.gender = GetPlayerAvatarGenderByGraphicsId(gMapObjects[mapObjectId].graphicsId); + SetPlayerAvatarExtraStateTransition(gMapObjects[mapObjectId].graphicsId, 0x20); +} -- cgit v1.2.3 From a87b35f9a73c09994bbe389fc73299b185db1fac Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 21:04:32 -0400 Subject: FieldObjectSetGraphicsId --- src/field_map_obj.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 53dd1a863..bbdaaf6ec 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -902,3 +902,44 @@ static void SetPlayerAvatarFieldObjectIdAndObjectId(u8 mapObjectId, u8 spriteId) gPlayerAvatar.gender = GetPlayerAvatarGenderByGraphicsId(gMapObjects[mapObjectId].graphicsId); SetPlayerAvatarExtraStateTransition(gMapObjects[mapObjectId].graphicsId, 0x20); } + +void FieldObjectSetGraphicsId(struct MapObject *mapObject, u8 graphicsId) +{ + const struct MapObjectGraphicsInfo *graphicsInfo; + struct Sprite *sprite; + u8 paletteSlot; + + graphicsInfo = GetFieldObjectGraphicsInfo(graphicsId); + sprite = &gSprites[mapObject->spriteId]; + paletteSlot = graphicsInfo->paletteSlot; + if (paletteSlot == 0) + { + pal_patch_for_npc(graphicsInfo->paletteTag1, graphicsInfo->paletteSlot); + } + else if (paletteSlot == 10) + { + npc_load_two_palettes__and_record(graphicsInfo->paletteTag1, graphicsInfo->paletteSlot); + } + else if (paletteSlot >= 16) + { + paletteSlot -= 16; + sub_808EAB0(graphicsInfo->paletteTag1, paletteSlot); + } + sprite->oam.shape = graphicsInfo->oam->shape; + sprite->oam.size = graphicsInfo->oam->size; + sprite->images = graphicsInfo->images; + sprite->anims = graphicsInfo->anims; + sprite->subspriteTables = graphicsInfo->subspriteTables; + sprite->oam.paletteNum = paletteSlot; + mapObject->mapobj_bit_12 = graphicsInfo->inanimate; + mapObject->graphicsId = graphicsId; + sub_8093038(mapObject->coords2.x, mapObject->coords2.y, &sprite->pos1.x, &sprite->pos1.y); + sprite->centerToCornerVecX = -(graphicsInfo->width >> 1); + sprite->centerToCornerVecY = -(graphicsInfo->height >> 1); + sprite->pos1.x += 8; + sprite->pos1.y += 16 + sprite->centerToCornerVecY; + if (mapObject->mapobj_bit_15) + { + CameraObjectReset1(); + } +} -- cgit v1.2.3 From ad99377734e1f982a347e33da60c82bf1120c2f3 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 7 Sep 2017 21:17:55 -0400 Subject: unref_sub_808E504 --- src/field_map_obj.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index bbdaaf6ec..b85432e69 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -782,7 +782,7 @@ static void RemoveFieldObjectIfOutsideView(struct MapObject *mapObject) right = gSaveBlock1Ptr->pos.x + 17; top = gSaveBlock1Ptr->pos.y; bottom = gSaveBlock1Ptr->pos.y + 16; - + if (mapObject->coords2.x >= left && mapObject->coords2.x <= right && mapObject->coords2.y >= top && mapObject->coords2.y <= bottom) return; @@ -943,3 +943,13 @@ void FieldObjectSetGraphicsId(struct MapObject *mapObject, u8 graphicsId) CameraObjectReset1(); } } + +void unref_sub_808E504(u8 localId, u8 mapNum, u8 mapGroup, u8 graphicsId) +{ + u8 mapObjectId; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + FieldObjectSetGraphicsId(&gMapObjects[mapObjectId], graphicsId); + } +} -- cgit v1.2.3 From ddcce8c3bc831023894191ceac058b8f2fe31ced Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 8 Sep 2017 13:41:55 -0400 Subject: FieldObjectTurn --- src/field_map_obj.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index b85432e69..55f1fd9fb 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -944,7 +944,7 @@ void FieldObjectSetGraphicsId(struct MapObject *mapObject, u8 graphicsId) } } -void unref_sub_808E504(u8 localId, u8 mapNum, u8 mapGroup, u8 graphicsId) +void FieldObjectSetGraphicsIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup, u8 graphicsId) { u8 mapObjectId; @@ -953,3 +953,23 @@ void unref_sub_808E504(u8 localId, u8 mapNum, u8 mapGroup, u8 graphicsId) FieldObjectSetGraphicsId(&gMapObjects[mapObjectId], graphicsId); } } + +void FieldObjectTurn(struct MapObject *mapObject, u8 direction) +{ + FieldObjectSetDirection(mapObject, direction); + if (!mapObject->mapobj_bit_12) + { + StartSpriteAnim(&gSprites[mapObject->spriteId], FieldObjectDirectionToImageAnimId(mapObject->mapobj_unk_18)); + SeekSpriteAnim(&gSprites[mapObject->spriteId], 0); + } +} + +void FieldObjectTurnByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup, u8 direction) +{ + u8 mapObjectId; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + FieldObjectTurn(&gMapObjects[mapObjectId], direction); + } +} -- cgit v1.2.3 From 9b98055ecc5174e92c1cf4bcad8f7a1ecc317581 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 13:46:21 -0400 Subject: PlayerObjectTurn --- src/field_map_obj.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 55f1fd9fb..4d5efd1b9 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -973,3 +973,8 @@ void FieldObjectTurnByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup, u8 direc FieldObjectTurn(&gMapObjects[mapObjectId], direction); } } + +void PlayerObjectTurn(struct PlayerAvatar *playerAvatar, u8 direction) +{ + FieldObjectTurn(&gMapObjects[playerAvatar->mapObjectId], direction); +} -- cgit v1.2.3 From 823f8d6a0c827025f280e1d57fb71959ca529fbe Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 14:05:45 -0400 Subject: get_berry_tree_graphics --- src/field_map_obj.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 4d5efd1b9..37ab01762 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4,6 +4,7 @@ #include "malloc.h" #include "sprite.h" #include "rom4.h" +#include "berry.h" #include "field_player_avatar.h" #include "event_data.h" #include "rom_818CFC8.h" @@ -978,3 +979,28 @@ void PlayerObjectTurn(struct PlayerAvatar *playerAvatar, u8 direction) { FieldObjectTurn(&gMapObjects[playerAvatar->mapObjectId], direction); } + +void get_berry_tree_graphics(struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 berryStage; + u8 berryId; + + mapObject->mapobj_bit_13 = TRUE; + sprite->invisible = TRUE; + berryStage = GetStageByBerryTreeId(mapObject->trainerRange_berryTreeId); + if (berryStage != 0) + { + mapObject->mapobj_bit_13 = FALSE; + sprite->invisible = FALSE; + berryId = GetBerryTypeByBerryTreeId(mapObject->trainerRange_berryTreeId) - 1; + berryStage -= 1; + if (berryId >= NUM_BERRIES) + { + berryId = 0; + } + FieldObjectSetGraphicsId(mapObject, gBerryTreeFieldObjectGraphicsIdTablePointers[berryId][berryStage]); + sprite->images = gBerryTreePicTablePointers[berryId]; + sprite->oam.paletteNum = gBerryTreePaletteSlotTablePointers[berryId][berryStage]; + StartSpriteAnim(sprite, berryStage); + } +} -- cgit v1.2.3 From e0b2e6cdbf0ff124a8e6a83f580418a06cee9df7 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 14:16:44 -0400 Subject: GetFieldObjectGraphicsInfo --- src/field_map_obj.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 37ab01762..775a7b4e4 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -11,6 +11,7 @@ #include "rom_81BE66C.h" #include "field_ground_effect.h" #include "map_obj_8097404.h" +#include "mauville_old_man.h" #include "field_effect_helpers.h" #include "field_map_obj.h" @@ -45,6 +46,8 @@ static void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8); void (*const gUnknown_08505438[NUM_FIELD_MAP_OBJECT_TEMPLATES])(struct Sprite *); const u8 gUnknown_0850557C[NUM_FIELD_MAP_OBJECT_TEMPLATES]; const u8 gUnknown_085055CD[NUM_FIELD_MAP_OBJECT_TEMPLATES]; +const struct MapObjectGraphicsInfo *const gMauvilleOldManGraphicsInfoPointers[7]; +const struct MapObjectGraphicsInfo *const gFieldObjectGraphicsInfoPointers[0xEF]; // Code @@ -980,7 +983,7 @@ void PlayerObjectTurn(struct PlayerAvatar *playerAvatar, u8 direction) FieldObjectTurn(&gMapObjects[playerAvatar->mapObjectId], direction); } -void get_berry_tree_graphics(struct MapObject *mapObject, struct Sprite *sprite) +/*static*/ void get_berry_tree_graphics(struct MapObject *mapObject, struct Sprite *sprite) { u8 berryStage; u8 berryId; @@ -1004,3 +1007,23 @@ void get_berry_tree_graphics(struct MapObject *mapObject, struct Sprite *sprite) StartSpriteAnim(sprite, berryStage); } } + +const struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8 graphicsId) +{ + u8 bard; + + if (graphicsId >= SPRITE_VAR) + { + graphicsId = VarGetFieldObjectGraphicsId(graphicsId - SPRITE_VAR); + } + if (graphicsId == 0x45) + { + bard = sub_81201C8(); + return gMauvilleOldManGraphicsInfoPointers[bard]; + } + if (graphicsId >= NUM_OBJECT_GRAPHICS_INFO) + { + graphicsId = 0x05; // LittleBoy1 + } + return gFieldObjectGraphicsInfoPointers[graphicsId]; +} -- cgit v1.2.3 From 511474cc15f8c7f52d4311b82898ee5c331b1260 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 14:20:13 -0400 Subject: FieldObjectHandleDynamicGraphicsId --- src/field_map_obj.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 775a7b4e4..c8d25341f 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -27,7 +27,7 @@ static void sub_808D450(void); static u8 GetFieldObjectIdByLocalId(u8); static u8 GetFieldObjectIdByLocalIdAndMapInternal(u8, u8, u8); static bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); -/*static*/ void FieldObjectHandleDynamicGraphicsId(struct MapObject *); +static void FieldObjectHandleDynamicGraphicsId(struct MapObject *); static void RemoveFieldObjectInternal (struct MapObject *); /*static*/ u16 GetFieldObjectFlagIdByFieldObjectId(u8); /*static*/ const struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8); @@ -1027,3 +1027,11 @@ const struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8 graphicsId) } return gFieldObjectGraphicsInfoPointers[graphicsId]; } + +static void FieldObjectHandleDynamicGraphicsId(struct MapObject *mapObject) +{ + if (mapObject->graphicsId >= SPRITE_VAR) + { + mapObject->graphicsId = VarGetFieldObjectGraphicsId(mapObject->graphicsId - SPRITE_VAR); + } +} -- cgit v1.2.3 From 67955bb51a14b464add672774a50b67788cf56c6 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 14:36:58 -0400 Subject: npc_by_local_id_and_map_set_field_1_bit_x20 --- src/field_map_obj.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index c8d25341f..bac056ee6 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -30,7 +30,6 @@ static bool8 GetAvailableFieldObjectSlot(u16, u8, u8, u8 *); static void FieldObjectHandleDynamicGraphicsId(struct MapObject *); static void RemoveFieldObjectInternal (struct MapObject *); /*static*/ u16 GetFieldObjectFlagIdByFieldObjectId(u8); -/*static*/ const struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8); void sub_8096518(struct MapObject *, struct Sprite *); static void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *, struct SpriteTemplate *, const struct SubspriteTable **); /*static*/ void GetFieldObjectMovingCameraOffset(s16 *, s16 *); @@ -1035,3 +1034,13 @@ static void FieldObjectHandleDynamicGraphicsId(struct MapObject *mapObject) mapObject->graphicsId = VarGetFieldObjectGraphicsId(mapObject->graphicsId - SPRITE_VAR); } } + +void npc_by_local_id_and_map_set_field_1_bit_x20(u8 localId, u8 mapNum, u8 mapGroup, u8 state) +{ + u8 mapObjectId; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + gMapObjects[mapObjectId].mapobj_bit_13 = state; + } +} -- cgit v1.2.3 From 05685f396150113bb4124493e6ada131e0e8307f Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 14:40:34 -0400 Subject: FieldObjectGetLocalIdAndMap --- src/field_map_obj.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index bac056ee6..94e2fb694 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1044,3 +1044,10 @@ void npc_by_local_id_and_map_set_field_1_bit_x20(u8 localId, u8 mapNum, u8 mapGr gMapObjects[mapObjectId].mapobj_bit_13 = state; } } + +void FieldObjectGetLocalIdAndMap(struct MapObject *mapObject, u8 *localId, u8 *mapNum, u8 *mapGroup) +{ + *localId = mapObject->localId; + *mapNum = mapObject->mapNum; + *mapGroup = mapObject->mapGroup; +} -- cgit v1.2.3 From 62eca9535836a9e57fd15c5ec9f12707d44d0597 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 14:53:00 -0400 Subject: sub_808E75C --- src/field_map_obj.c | 57 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 94e2fb694..ac4f85a47 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -63,7 +63,7 @@ static void npcs_clear_ids_and_state(void) { u8 i; - for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) { npc_clear_ids_and_state(&gMapObjects[i]); } @@ -98,7 +98,7 @@ u8 sub_808D4F4(void) { u8 i; - for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) { if (!gMapObjects[i].active) { @@ -120,7 +120,7 @@ u8 GetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapId, u8 mapGroupId) bool8 TryGetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapId, u8 mapGroupId, u8 *fieldObjectId) { *fieldObjectId = GetFieldObjectIdByLocalIdAndMap(localId, mapId, mapGroupId); - if (*fieldObjectId == ARRAY_COUNT(gMapObjects)) + if (*fieldObjectId == NUM_FIELD_OBJECTS) { return TRUE; } @@ -131,7 +131,7 @@ u8 GetFieldObjectIdByXY(s16 x, s16 y) { u8 i; - for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) { if (gMapObjects[i].active && gMapObjects[i].coords2.x == x && gMapObjects[i].coords2.y == y) { @@ -145,28 +145,28 @@ static u8 GetFieldObjectIdByLocalIdAndMapInternal(u8 localId, u8 mapId, u8 mapGr { u8 i; - for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) { if (gMapObjects[i].active && gMapObjects[i].localId == localId && gMapObjects[i].mapNum == mapId && gMapObjects[i].mapGroup == mapGroupId) { return i; } } - return ARRAY_COUNT(gMapObjects); + return NUM_FIELD_OBJECTS; } static u8 GetFieldObjectIdByLocalId(u8 localId) { u8 i; - for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) { if (gMapObjects[i].active && gMapObjects[i].localId == localId) { return i; } } - return ARRAY_COUNT(gMapObjects); + return NUM_FIELD_OBJECTS; } // This function has the same nonmatching quirk as in Ruby/Sapphire. @@ -180,7 +180,7 @@ static u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u if (GetAvailableFieldObjectSlot(template->localId, mapId, mapGroupId, &slot)) { - return ARRAY_COUNT(gMapObjects); + return NUM_FIELD_OBJECTS; } mapObject = &gMapObjects[slot]; npc_clear_ids_and_state(mapObject); @@ -409,7 +409,7 @@ u8 unref_sub_808D77C(u8 localId) } } } - return ARRAY_COUNT(gMapObjects); + return NUM_FIELD_OBJECTS; } static bool8 GetAvailableFieldObjectSlot(u16 localId, u8 mapNum, u8 mapGroup, u8 *result) @@ -421,14 +421,14 @@ static bool8 GetAvailableFieldObjectSlot(u16 localId, u8 mapNum, u8 mapGroup, u8 { u8 i = 0; - for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) { if (!gMapObjects[i].active) break; if (gMapObjects[i].localId == localId && gMapObjects[i].mapNum == mapNum && gMapObjects[i].mapGroup == mapGroup) return TRUE; } - if (i >= ARRAY_COUNT(gMapObjects)) + if (i >= NUM_FIELD_OBJECTS) return TRUE; *result = i; do @@ -436,7 +436,7 @@ static bool8 GetAvailableFieldObjectSlot(u16 localId, u8 mapNum, u8 mapGroup, u8 if (gMapObjects[i].active && gMapObjects[i].localId == localId && gMapObjects[i].mapNum == mapNum && gMapObjects[i].mapGroup == mapGroup) return TRUE; i ++; - } while (i < ARRAY_COUNT(gMapObjects)); + } while (i < NUM_FIELD_OBJECTS); return FALSE; } @@ -468,7 +468,7 @@ void unref_sub_808D958(void) { u8 i; - for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) { if (i != gPlayerAvatar.mapObjectId) { @@ -487,9 +487,9 @@ static u8 SpawnFieldObjectInternal(struct MapObjectTemplate *mapObjectTemplate, u8 spriteId; mapObjectId = InitFieldObjectStateFromTemplate(mapObjectTemplate, mapNum, mapGroup); - if (mapObjectId == ARRAY_COUNT(gMapObjects)) + if (mapObjectId == NUM_FIELD_OBJECTS) { - return ARRAY_COUNT(gMapObjects); + return NUM_FIELD_OBJECTS; } mapObject = &gMapObjects[mapObjectId]; graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId); @@ -516,7 +516,7 @@ static u8 SpawnFieldObjectInternal(struct MapObjectTemplate *mapObjectTemplate, if (spriteId == MAX_SPRITES) { gMapObjects[mapObjectId].active = FALSE; - return ARRAY_COUNT(gMapObjects); + return NUM_FIELD_OBJECTS; } sprite = &gSprites[spriteId]; sub_8092FF0(mapObject->coords2.x + cameraX, mapObject->coords2.y + cameraY, &sprite->pos1.x, &sprite->pos1.y); @@ -552,9 +552,9 @@ static u8 SpawnFieldObject(struct MapObjectTemplate *mapObjectTemplate, u8 mapNu spriteFrameImage.size = graphicsInfo->size; spriteTemplate.images = &spriteFrameImage; mapObjectId = SpawnFieldObjectInternal(mapObjectTemplate, &spriteTemplate, mapNum, mapGroup, cameraX, cameraY); - if (mapObjectId == ARRAY_COUNT(gMapObjects)) + if (mapObjectId == NUM_FIELD_OBJECTS) { - return ARRAY_COUNT(gMapObjects); + return NUM_FIELD_OBJECTS; } gSprites[gMapObjects[mapObjectId].spriteId].images = graphicsInfo->images; if (subspriteTables != NULL) @@ -602,7 +602,7 @@ u8 show_sprite(u8 localId, u8 mapNum, u8 mapGroup) mapObjectTemplate = GetFieldObjectTemplateByLocalIdAndMap(localId, mapNum, mapGroup); if (mapObjectTemplate == NULL) { - return ARRAY_COUNT(gMapObjects); + return NUM_FIELD_OBJECTS; } GetFieldObjectMovingCameraOffset(&cameraX, &cameraY); return SpawnFieldObject(mapObjectTemplate, mapNum, mapGroup, cameraX, cameraY); @@ -757,7 +757,7 @@ void SpawnFieldObjectsInView(s16 cameraX, s16 cameraY) bool8 isActiveLinkPlayer; struct MapObject *mapObject; - for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) { for (j = 0, isActiveLinkPlayer = FALSE; j < ARRAY_COUNT(gLinkPlayerMapObjects); j ++) { @@ -800,7 +800,7 @@ void sub_808E16C(s16 x, s16 y) u8 i; ClearPlayerAvatarInfo(); - for (i = 0; i < ARRAY_COUNT(gMapObjects); i ++) + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) { if (gMapObjects[i].active) { @@ -1051,3 +1051,16 @@ void FieldObjectGetLocalIdAndMap(struct MapObject *mapObject, u8 *localId, u8 *m *mapNum = mapObject->mapNum; *mapGroup = mapObject->mapGroup; } + +void sub_808E75C(s16 x, s16 y) +{ + u8 mapObjectId; + struct MapObject *mapObject; + + mapObjectId = GetFieldObjectIdByXY(x, y); + if (mapObjectId != NUM_FIELD_OBJECTS) + { + mapObject = &gMapObjects[mapObjectId]; + mapObject->mapobj_bit_2 = TRUE; + } +} -- cgit v1.2.3 From 782f21f63e1ac8615203818ebb69f40e91cc70f2 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 14:58:17 -0400 Subject: sub_808E78C --- src/field_map_obj.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index ac4f85a47..a4d7e4097 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1064,3 +1064,18 @@ void sub_808E75C(s16 x, s16 y) mapObject->mapobj_bit_2 = TRUE; } } + +void sub_808E78C(u8 localId, u8 mapNum, u8 mapGroup, u8 subpriority) +{ + u8 mapObjectId; + struct MapObject *mapObject; + struct Sprite *sprite; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + mapObject = &gMapObjects[mapObjectId]; + sprite = &gSprites[mapObject->spriteId]; + mapObject->mapobj_bit_26 = TRUE; + sprite->subpriority = subpriority; + } +} -- cgit v1.2.3 From 8ef5d059550cb5d6d21639992e6ce67a9dd327f0 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 15:05:04 -0400 Subject: sub_808E7E4 --- src/field_map_obj.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index a4d7e4097..910a58ffb 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1079,3 +1079,16 @@ void sub_808E78C(u8 localId, u8 mapNum, u8 mapGroup, u8 subpriority) sprite->subpriority = subpriority; } } + +void sub_808E7E4(u8 localId, u8 mapNum, u8 mapGroup) +{ + u8 mapObjectId; + struct MapObject *mapObject; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + mapObject = &gMapObjects[mapObjectId]; + mapObject->mapobj_bit_26 = FALSE; + mapObject->mapobj_bit_2 = TRUE; + } +} -- cgit v1.2.3 From d3edf5642ed0f76f678bb4c566a7c96eaf793fdd Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 15:08:10 -0400 Subject: sub_808E82C --- src/field_map_obj.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 910a58ffb..5a31881ad 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1092,3 +1092,16 @@ void sub_808E7E4(u8 localId, u8 mapNum, u8 mapGroup) mapObject->mapobj_bit_2 = TRUE; } } + +void sub_808E82C(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y) +{ + u8 mapObjectId; + struct Sprite *sprite; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + sprite = &gSprites[gMapObjects[mapObjectId].spriteId]; + sprite->pos2.x = x; + sprite->pos2.y = y; + } +} -- cgit v1.2.3 From db2b371e70a8cbf1134866906c7eccaae7f65203 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 15:11:29 -0400 Subject: gpu_pal_allocator_reset__manage_upper_four --- src/field_map_obj.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 5a31881ad..cb3390844 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1105,3 +1105,9 @@ void sub_808E82C(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y) sprite->pos2.y = y; } } + +void gpu_pal_allocator_reset__manage_upper_four(void) +{ + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 12; +} -- cgit v1.2.3 From 1de5a14a35f6da79a2bc603ce5a0cb3a116c31b0 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 15:18:03 -0400 Subject: sub_808E894 --- src/field_map_obj.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index cb3390844..7122bcc9e 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4,6 +4,7 @@ #include "malloc.h" #include "sprite.h" #include "rom4.h" +#include "data3.h" #include "berry.h" #include "field_player_avatar.h" #include "event_data.h" @@ -39,6 +40,8 @@ static void RemoveFieldObjectIfOutsideView(struct MapObject *); static void sub_808E1B8(u8, s16, s16); static void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8); /*static*/ void sub_808E38C(struct MapObject *); +/*static*/ void sub_808E8F4(const struct SpritePalette *); +/*static*/ u16 FindFieldObjectPaletteIndexByTag(u16); // ROM data @@ -1111,3 +1114,14 @@ void gpu_pal_allocator_reset__manage_upper_four(void) FreeAllSpritePalettes(); gReservedSpritePaletteCount = 12; } + +void sub_808E894(u16 paletteTag) +{ + u16 paletteSlot; + + paletteSlot = (u8)FindFieldObjectPaletteIndexByTag(paletteTag); + if (paletteSlot != 0x11ff) // always true + { + sub_808E8F4(&gUnknown_0850BBC8[paletteSlot]); + } +} -- cgit v1.2.3 From 444887ba228a94866641bfa2d420cf1903af1a82 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 15:21:32 -0400 Subject: sub_808E8C0 --- src/field_map_obj.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 7122bcc9e..1ae142075 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1125,3 +1125,13 @@ void sub_808E894(u16 paletteTag) sub_808E8F4(&gUnknown_0850BBC8[paletteSlot]); } } + +void sub_808E8C0(u16 *paletteTags) +{ + u8 i; + + for (i = 0; paletteTags[i] != 0x11ff; i ++) + { + sub_808E894(paletteTags[i]); + } +} -- cgit v1.2.3 From 2d3ce87c4c653d1789192e0083ee93a2090cdca5 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 15:27:08 -0400 Subject: sub_808E8F4 --- src/field_map_obj.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 1ae142075..ccc88db15 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -35,12 +35,12 @@ void sub_8096518(struct MapObject *, struct Sprite *); static void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *, struct SpriteTemplate *, const struct SubspriteTable **); /*static*/ void GetFieldObjectMovingCameraOffset(s16 *, s16 *); /*static*/ struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8, u8, u8); -/*static*/ void sub_808E894(u16); +static void sub_808E894(u16); static void RemoveFieldObjectIfOutsideView(struct MapObject *); static void sub_808E1B8(u8, s16, s16); static void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8); /*static*/ void sub_808E38C(struct MapObject *); -/*static*/ void sub_808E8F4(const struct SpritePalette *); +/*static*/ u8 sub_808E8F4(const struct SpritePalette *); /*static*/ u16 FindFieldObjectPaletteIndexByTag(u16); // ROM data @@ -1115,7 +1115,7 @@ void gpu_pal_allocator_reset__manage_upper_four(void) gReservedSpritePaletteCount = 12; } -void sub_808E894(u16 paletteTag) +static void sub_808E894(u16 paletteTag) { u16 paletteSlot; @@ -1135,3 +1135,12 @@ void sub_808E8C0(u16 *paletteTags) sub_808E894(paletteTags[i]); } } + +u8 sub_808E8F4(const struct SpritePalette *spritePalette) +{ + if (IndexOfSpritePaletteTag(spritePalette->tag) != 0xff) + { + return 0xff; + } + return LoadSpritePalette(spritePalette); +} -- cgit v1.2.3 From e6e0dc80f6ec0284ae49fd83847fac241c9e86b3 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 17:17:03 -0400 Subject: pal_patch_for_npc --- src/field_map_obj.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index ccc88db15..c8d147e6d 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -6,6 +6,7 @@ #include "rom4.h" #include "data3.h" #include "berry.h" +#include "palette.h" #include "field_player_avatar.h" #include "event_data.h" #include "rom_818CFC8.h" @@ -1144,3 +1145,11 @@ u8 sub_808E8F4(const struct SpritePalette *spritePalette) } return LoadSpritePalette(spritePalette); } + +void pal_patch_for_npc(u16 paletteTag, u8 paletteSlot) +{ + u8 paletteIdx; + + paletteIdx = FindFieldObjectPaletteIndexByTag(paletteTag); + LoadPalette(gUnknown_0850BBC8[paletteIdx].data, 16 * paletteSlot + 256, 0x20); +} -- cgit v1.2.3 From 07b1668623f6d028d1c1f32c29e377064f577680 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 17:21:58 -0400 Subject: pal_patch_for_npc_range --- src/field_map_obj.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index c8d147e6d..4e785e969 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1153,3 +1153,13 @@ void pal_patch_for_npc(u16 paletteTag, u8 paletteSlot) paletteIdx = FindFieldObjectPaletteIndexByTag(paletteTag); LoadPalette(gUnknown_0850BBC8[paletteIdx].data, 16 * paletteSlot + 256, 0x20); } + +void pal_patch_for_npc_range(u16 *paletteTags, u8 minSlot, u8 maxSlot) +{ + while (minSlot < maxSlot) + { + pal_patch_for_npc(*paletteTags, minSlot); + paletteTags ++; + minSlot ++; + } +} -- cgit v1.2.3 From 5a020a47f3ac99bf80854817873e211cbf22102d Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 17:34:12 -0400 Subject: FindFieldObjectPaletteIndexByTag --- src/field_map_obj.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 4e785e969..0614a82d7 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -41,8 +41,8 @@ static void RemoveFieldObjectIfOutsideView(struct MapObject *); static void sub_808E1B8(u8, s16, s16); static void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8); /*static*/ void sub_808E38C(struct MapObject *); -/*static*/ u8 sub_808E8F4(const struct SpritePalette *); -/*static*/ u16 FindFieldObjectPaletteIndexByTag(u16); +static u8 sub_808E8F4(const struct SpritePalette *); +static u8 FindFieldObjectPaletteIndexByTag(u16); // ROM data @@ -1120,7 +1120,7 @@ static void sub_808E894(u16 paletteTag) { u16 paletteSlot; - paletteSlot = (u8)FindFieldObjectPaletteIndexByTag(paletteTag); + paletteSlot = FindFieldObjectPaletteIndexByTag(paletteTag); if (paletteSlot != 0x11ff) // always true { sub_808E8F4(&gUnknown_0850BBC8[paletteSlot]); @@ -1137,7 +1137,7 @@ void sub_808E8C0(u16 *paletteTags) } } -u8 sub_808E8F4(const struct SpritePalette *spritePalette) +static u8 sub_808E8F4(const struct SpritePalette *spritePalette) { if (IndexOfSpritePaletteTag(spritePalette->tag) != 0xff) { @@ -1148,7 +1148,7 @@ u8 sub_808E8F4(const struct SpritePalette *spritePalette) void pal_patch_for_npc(u16 paletteTag, u8 paletteSlot) { - u8 paletteIdx; + u16 paletteIdx; paletteIdx = FindFieldObjectPaletteIndexByTag(paletteTag); LoadPalette(gUnknown_0850BBC8[paletteIdx].data, 16 * paletteSlot + 256, 0x20); @@ -1163,3 +1163,17 @@ void pal_patch_for_npc_range(u16 *paletteTags, u8 minSlot, u8 maxSlot) minSlot ++; } } + +static u8 FindFieldObjectPaletteIndexByTag(u16 tag) +{ + u8 i; + + for (i = 0; gUnknown_0850BBC8[i].tag != 0x11ff; i ++) + { + if (gUnknown_0850BBC8[i].tag == tag) + { + return i; + } + } + return 0xff; +} -- cgit v1.2.3 From dddb44e3018ba915564d6e1a3bcc888ec37aa0bd Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 17:58:41 -0400 Subject: npc_load_two_palettes__no_record --- src/field_map_obj.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 0614a82d7..fae9b12d8 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -23,6 +23,9 @@ // Static RAM declarations +extern u8 gUnknown_020375B4; +extern u16 gUnknown_020375B6; + // Static ROM declarations static void sub_808D450(void); @@ -1177,3 +1180,18 @@ static u8 FindFieldObjectPaletteIndexByTag(u16 tag) } return 0xff; } + +void npc_load_two_palettes__no_record(u16 tag, u8 slot) +{ + u8 i; + + pal_patch_for_npc(tag, slot); + for (i = 0; gUnknown_0850BD00[i].tag != 0x11ff; i ++) + { + if (gUnknown_0850BD00[i].tag == tag) + { + pal_patch_for_npc(gUnknown_0850BD00[i].data[gUnknown_020375B4], gUnknown_084975C4[slot]); + return; + } + } +} -- cgit v1.2.3 From a17a1bb27aeca68624c2b8d1b55cbd44e1c34e11 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 18:04:23 -0400 Subject: npc_load_two_palettes__and_record --- src/field_map_obj.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index fae9b12d8..b5a0ce5e5 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1195,3 +1195,19 @@ void npc_load_two_palettes__no_record(u16 tag, u8 slot) } } } + +void npc_load_two_palettes__and_record(u16 tag, u8 slot) +{ + u8 i; + + gUnknown_020375B6 = tag; + pal_patch_for_npc(tag, slot); + for (i = 0; gUnknown_0850BD78[i].tag != 0x11ff; i ++) + { + if (gUnknown_0850BD78[i].tag == tag) + { + pal_patch_for_npc(gUnknown_0850BD78[i].data[gUnknown_020375B4], gUnknown_084975C4[slot]); + return; + } + } +} -- cgit v1.2.3 From b639ca3b15bea19d7115d7ad619a1e6140015740 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 8 Sep 2017 18:12:27 -0400 Subject: sub_808EAB0 --- src/field_map_obj.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index b5a0ce5e5..8042348f2 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -46,6 +46,7 @@ static void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8); /*static*/ void sub_808E38C(struct MapObject *); static u8 sub_808E8F4(const struct SpritePalette *); static u8 FindFieldObjectPaletteIndexByTag(u16); +static void sub_808EAB0(u16, u8); // ROM data @@ -1211,3 +1212,8 @@ void npc_load_two_palettes__and_record(u16 tag, u8 slot) } } } + +static void sub_808EAB0(u16 tag, u8 slot) +{ + pal_patch_for_npc(tag, slot); +} -- cgit v1.2.3 From 43c3b9fdff01c05860969d80fbc6ae0b0dbbcb90 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 8 Sep 2017 21:25:20 -0400 Subject: unref_sub_808EAC4 --- src/field_map_obj.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 8042348f2..e5025fccf 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1217,3 +1217,11 @@ static void sub_808EAB0(u16 tag, u8 slot) { pal_patch_for_npc(tag, slot); } + +void unref_sub_808EAC4(struct MapObject *mapObject, s16 x, s16 y) +{ + mapObject->coords3.x = mapObject->coords2.x; + mapObject->coords3.y = mapObject->coords2.y; + mapObject->coords2.x = x + mapObject->coords3.x; + mapObject->coords2.y = y + mapObject->coords3.y; +} -- cgit v1.2.3 From 70e982d1fabc62a6d145b1a8dda866931886bb4d Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 8 Sep 2017 21:27:02 -0400 Subject: npc_coords_shift --- src/field_map_obj.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index e5025fccf..6298c977b 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1222,6 +1222,15 @@ void unref_sub_808EAC4(struct MapObject *mapObject, s16 x, s16 y) { mapObject->coords3.x = mapObject->coords2.x; mapObject->coords3.y = mapObject->coords2.y; - mapObject->coords2.x = x + mapObject->coords3.x; - mapObject->coords2.y = y + mapObject->coords3.y; + mapObject->coords2.x += x; + mapObject->coords2.y += y; } + +void npc_coords_shift(struct MapObject *mapObject, s16 x, s16 y) +{ + mapObject->coords3.x = mapObject->coords2.x; + mapObject->coords3.y = mapObject->coords2.y; + mapObject->coords2.x = x; + mapObject->coords2.y = y; +} + -- cgit v1.2.3 From 019935fb73b7a065c735045a80d5124132ee6e5e Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 8 Sep 2017 21:28:22 -0400 Subject: npc_coords_set --- src/field_map_obj.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 6298c977b..c7d9e32d7 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1234,3 +1234,11 @@ void npc_coords_shift(struct MapObject *mapObject, s16 x, s16 y) mapObject->coords2.y = y; } +/*static*/ void npc_coords_set(struct MapObject *mapObject, s16 x, s16 y) +{ + mapObject->coords3.x = x; + mapObject->coords3.y = y; + mapObject->coords2.x = x; + mapObject->coords2.y = y; +} + -- cgit v1.2.3 From ba6987b7335d6b3f0a641e0dee62be37bff4ffd8 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 8 Sep 2017 21:35:46 -0400 Subject: sub_808EB08 --- src/field_map_obj.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index c7d9e32d7..acfbd60a7 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1242,3 +1242,23 @@ void npc_coords_shift(struct MapObject *mapObject, s16 x, s16 y) mapObject->coords2.y = y; } +void sub_808EB08(struct MapObject *mapObject, s16 x, s16 y) +{ + struct Sprite *sprite; + const struct MapObjectGraphicsInfo *graphicsInfo; + + sprite = &gSprites[mapObject->spriteId]; + graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId); + npc_coords_set(mapObject, x, y); + sub_8093038(mapObject->coords2.x, mapObject->coords2.y, &sprite->pos1.x, &sprite->pos1.y); + sprite->centerToCornerVecX = -(graphicsInfo->width >> 1); + sprite->centerToCornerVecY = -(graphicsInfo->height >> 1); + sprite->pos1.x += 8; + sprite->pos1.y += 16 + sprite->centerToCornerVecY; + sub_808E38C(mapObject); + if (mapObject->mapobj_bit_15) + { + CameraObjectReset1(); + } +} + -- cgit v1.2.3 From 1ed1fbab1ca140edebb7ec1ebfabaaaf04f9c054 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 15:12:48 -0400 Subject: sub_808EBA8 --- src/field_map_obj.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index acfbd60a7..7465370b9 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1262,3 +1262,15 @@ void sub_808EB08(struct MapObject *mapObject, s16 x, s16 y) } } +void sub_808EBA8(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y) +{ + u8 mapObjectId; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + x += 7; + y += 7; + sub_808EB08(&gMapObjects[mapObjectId], x, y); + } +} + -- cgit v1.2.3 From 5bb58867748b91de2c20860d73b1a36896f11dd1 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 15:14:46 -0400 Subject: npc_coords_shift_still --- src/field_map_obj.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 7465370b9..1a4ab1a74 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1274,3 +1274,8 @@ void sub_808EBA8(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y) } } +void npc_coords_shift_still(struct MapObject *mapObject) +{ + npc_coords_shift(mapObject, mapObject->coords2.x, mapObject->coords2.y); +} + -- cgit v1.2.3 From 79b19a36b864abb359f7ec2122dea851f8ac5e7b Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 15:35:21 -0400 Subject: UpdateFieldObjectCoordsForCameraUpdate --- src/field_map_obj.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 1a4ab1a74..ced0ecb27 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1279,3 +1279,28 @@ void npc_coords_shift_still(struct MapObject *mapObject) npc_coords_shift(mapObject, mapObject->coords2.x, mapObject->coords2.y); } +void UpdateFieldObjectCoordsForCameraUpdate(void) +{ + u8 i; + s16 dx; + s16 dy; + + if (gCamera.active) + { + dx = gCamera.x; + dy = gCamera.y; + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) + { + if (gMapObjects[i].active) + { + gMapObjects[i].coords1.x -= dx; + gMapObjects[i].coords1.y -= dy; + gMapObjects[i].coords2.x -= dx; + gMapObjects[i].coords2.y -= dy; + gMapObjects[i].coords3.x -= dx; + gMapObjects[i].coords3.y -= dy; + } + } + } +} + -- cgit v1.2.3 From d8e22380869e4e04c2ebbc71fae43cd38ed646a9 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 15:54:41 -0400 Subject: FieldObjectDoesZCoordMatch --- src/field_map_obj.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index ced0ecb27..a48a2506e 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -47,6 +47,7 @@ static void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8); static u8 sub_808E8F4(const struct SpritePalette *); static u8 FindFieldObjectPaletteIndexByTag(u16); static void sub_808EAB0(u16, u8); +static bool8 FieldObjectDoesZCoordMatch(struct MapObject *, u8); // ROM data @@ -1304,3 +1305,27 @@ void UpdateFieldObjectCoordsForCameraUpdate(void) } } +u8 GetFieldObjectIdByXYZ(u16 x, u16 y, u8 z) +{ + u8 i; + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) + { + if (gMapObjects[i].active) + { + if (gMapObjects[i].coords2.x == x && gMapObjects[i].coords2.y == y && FieldObjectDoesZCoordMatch(&gMapObjects[i], z)) + { + return i; + } + } + } + return NUM_FIELD_OBJECTS; +} + +static bool8 FieldObjectDoesZCoordMatch(struct MapObject *mapObject, u8 z) +{ + if (mapObject->mapobj_unk_0B_0 != 0 && z != 0 && mapObject->mapobj_unk_0B_0 != z) + { + return FALSE; + } + return TRUE; +} -- cgit v1.2.3 From 5a5ea8c740ba17a542c55aa81a576af18cf76b45 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 15:56:03 -0400 Subject: UpdateFieldObjectsForCameraUpdate --- src/field_map_obj.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index a48a2506e..8214c5efa 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1329,3 +1329,10 @@ static bool8 FieldObjectDoesZCoordMatch(struct MapObject *mapObject, u8 z) } return TRUE; } + +void UpdateFieldObjectsForCameraUpdate(s16 x, s16 y) +{ + UpdateFieldObjectCoordsForCameraUpdate(); + SpawnFieldObjectsInView(x, y); + RemoveFieldObjectsOutsideView(); +} -- cgit v1.2.3 From 9e0a17109840593a034bd42e96ffbcf73bc16b1c Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 16:02:20 -0400 Subject: AddCameraObject --- src/field_map_obj.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 8214c5efa..933908886 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1336,3 +1336,13 @@ void UpdateFieldObjectsForCameraUpdate(s16 x, s16 y) SpawnFieldObjectsInView(x, y); RemoveFieldObjectsOutsideView(); } + +u8 AddCameraObject(u8 data0) +{ + u8 spriteId; + + spriteId = CreateSprite(&gUnknown_084975D4, 0, 0, 4); + gSprites[spriteId].invisible = TRUE; + gSprites[spriteId].data0 = data0; + return spriteId; +} -- cgit v1.2.3 From c7b1a8c3daa5183f8e522d6d6fcba1ffea79e72f Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 16:13:19 -0400 Subject: ObjectCB_CameraObject --- src/field_map_obj.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 933908886..3fc962336 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -48,6 +48,9 @@ static u8 sub_808E8F4(const struct SpritePalette *); static u8 FindFieldObjectPaletteIndexByTag(u16); static void sub_808EAB0(u16, u8); static bool8 FieldObjectDoesZCoordMatch(struct MapObject *, u8); +//static void CameraObject_0(struct Sprite *); +/*static*/ void CameraObject_1(struct Sprite *); +//static void CameraObject_2(struct Sprite *); // ROM data @@ -1337,12 +1340,50 @@ void UpdateFieldObjectsForCameraUpdate(s16 x, s16 y) RemoveFieldObjectsOutsideView(); } -u8 AddCameraObject(u8 data0) +u8 AddCameraObject(u8 linkedSpriteId) { u8 spriteId; spriteId = CreateSprite(&gUnknown_084975D4, 0, 0, 4); gSprites[spriteId].invisible = TRUE; - gSprites[spriteId].data0 = data0; + gSprites[spriteId].data0 = linkedSpriteId; return spriteId; } + +void ObjectCB_CameraObject(struct Sprite *sprite) +{ + void (*callbacks[ARRAY_COUNT(gUnknown_084975EC)])(struct Sprite *); + + memcpy(callbacks, gUnknown_084975EC, sizeof gUnknown_084975EC); + callbacks[sprite->data1](sprite); +} + +/*static*/ void CameraObject_0(struct Sprite *sprite) +{ + sprite->pos1.x = gSprites[sprite->data0].pos1.x; + sprite->pos1.y = gSprites[sprite->data0].pos1.y; + sprite->invisible = TRUE; + sprite->data1 = 1; + CameraObject_1(sprite); +} + +/*static*/ void CameraObject_1(struct Sprite *sprite) +{ + s16 x; + s16 y; + + y = gSprites[sprite->data0].pos1.y; + x = gSprites[sprite->data0].pos1.x; + sprite->data2 = x - sprite->pos1.x; + sprite->data3 = y - sprite->pos1.y; + sprite->pos1.x = x; + sprite->pos1.y = y; +} + +/*static*/ void CameraObject_2(struct Sprite *sprite) +{ + sprite->pos1.x = gSprites[sprite->data0].pos1.x; + sprite->pos1.y = gSprites[sprite->data0].pos1.y; + sprite->data2 = 0; + sprite->data3 = 0; +} -- cgit v1.2.3 From 4dfae8b9e450467942b227895853c37043bee401 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 16:32:26 -0400 Subject: FindCameraObject --- src/field_map_obj.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 3fc962336..f600db934 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1387,3 +1387,17 @@ void ObjectCB_CameraObject(struct Sprite *sprite) sprite->data2 = 0; sprite->data3 = 0; } + +/*static*/ struct Sprite *FindCameraObject(void) +{ + u8 spriteId; + + for (spriteId = 0; spriteId < MAX_SPRITES; spriteId ++) + { + if (gSprites[spriteId].inUse && gSprites[spriteId].callback == ObjectCB_CameraObject) + { + return &gSprites[spriteId]; + } + } + return NULL; +} -- cgit v1.2.3 From a89da3ae31144d032f942fb963acc34f23818a91 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 16:36:19 -0400 Subject: Functions operating on the camera object --- src/field_map_obj.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index f600db934..40b12b1b3 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1388,7 +1388,7 @@ void ObjectCB_CameraObject(struct Sprite *sprite) sprite->data3 = 0; } -/*static*/ struct Sprite *FindCameraObject(void) +static struct Sprite *FindCameraObject(void) { u8 spriteId; @@ -1401,3 +1401,44 @@ void ObjectCB_CameraObject(struct Sprite *sprite) } return NULL; } + +void CameraObjectReset1(void) +{ + struct Sprite *cameraObject; + + cameraObject = FindCameraObject(); + if (cameraObject != NULL) + { + cameraObject->data1 = 0; + cameraObject->callback(cameraObject); + } +} + +void CameraObjectSetFollowedObjectId(u8 objectId) +{ + struct Sprite *cameraObject; + + cameraObject = FindCameraObject(); + if (cameraObject != NULL) + { + cameraObject->data0 = objectId; + CameraObjectReset1(); + } +} + +u8 CameraObjectGetFollowedObjectId(void) +{ + struct Sprite *cameraObject; + + cameraObject = FindCameraObject(); + if (cameraObject == NULL) + { + return MAX_SPRITES; + } + return cameraObject->data0; +} + +void CameraObjectReset2(void) +{ + FindCameraObject()->data1 = 2; +} -- cgit v1.2.3 From 251360624a2f4802a607b7a114a6fe5db66623af Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 16:53:08 -0400 Subject: CopySprite --- src/field_map_obj.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 40b12b1b3..a54444c59 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1442,3 +1442,21 @@ void CameraObjectReset2(void) { FindCameraObject()->data1 = 2; } + +u8 CopySprite(struct Sprite *sprite, s16 x, s16 y, u8 subpriority) +{ + u8 i; + + for (i = 0; i < MAX_SPRITES; i ++) + { + if (!gSprites[i].inUse) + { + gSprites[i] = *sprite; + gSprites[i].pos1.x = x; + gSprites[i].pos1.y = y; + gSprites[i].subpriority = subpriority; + break; + } + } + return i; +} -- cgit v1.2.3 From 69a1ff984d8673bb3a93c490591866573dde2ac7 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 16:57:08 -0400 Subject: obj_unfreeze --- src/field_map_obj.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index a54444c59..3d3934aa1 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1460,3 +1460,21 @@ u8 CopySprite(struct Sprite *sprite, s16 x, s16 y, u8 subpriority) } return i; } + +u8 obj_unfreeze(struct Sprite *sprite, s16 x, s16 y, u8 subpriority) +{ + s16 i; + + for (i = MAX_SPRITES - 1; i > -1; i --) + { + if (!gSprites[i].inUse) + { + gSprites[i] = *sprite; + gSprites[i].pos1.x = x; + gSprites[i].pos1.y = y; + gSprites[i].subpriority = subpriority; + return i; + } + } + return MAX_SPRITES; +} -- cgit v1.2.3 From b263dcc7cf6caab910511caf2d1c2aff9f629476 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 17:04:37 -0400 Subject: FieldObjectSetDirection --- src/field_map_obj.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 3d3934aa1..d5481c573 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1478,3 +1478,15 @@ u8 obj_unfreeze(struct Sprite *sprite, s16 x, s16 y, u8 subpriority) } return MAX_SPRITES; } + +void FieldObjectSetDirection(struct MapObject *mapObject, u8 direction) +{ + s8 d2; + mapObject->mapobj_unk_20 = mapObject->mapobj_unk_18; + if (!mapObject->mapobj_bit_9) + { + d2 = direction; + mapObject->mapobj_unk_18 = d2; + } + mapObject->placeholder18 = direction; +} -- cgit v1.2.3 From 84569918376aa346cbb94925a70d64569821a4ac Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 17:11:03 -0400 Subject: Functions for retrieving flag and script pointer given map object id --- src/field_map_obj.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index d5481c573..42769ed13 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1490,3 +1490,23 @@ void FieldObjectSetDirection(struct MapObject *mapObject, u8 direction) } mapObject->placeholder18 = direction; } + +static const u8 *GetFieldObjectScriptPointerByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup) +{ + return GetFieldObjectTemplateByLocalIdAndMap(localId, mapNum, mapGroup)->script; +} + +const u8 *GetFieldObjectScriptPointerByFieldObjectId(u8 mapObjectId) +{ + return GetFieldObjectScriptPointerByLocalIdAndMap(gMapObjects[mapObjectId].localId, gMapObjects[mapObjectId].mapNum, gMapObjects[mapObjectId].mapGroup); +} + +static u16 GetFieldObjectFlagIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup) +{ + return GetFieldObjectTemplateByLocalIdAndMap(localId, mapNum, mapGroup)->flagId; +} + +u16 GetFieldObjectFlagIdByFieldObjectId(u8 mapObjectId) +{ + return GetFieldObjectFlagIdByLocalIdAndMap(gMapObjects[mapObjectId].localId, gMapObjects[mapObjectId].mapNum, gMapObjects[mapObjectId].mapGroup); +} -- cgit v1.2.3 From bcf844f965912cac05b6cfb26f430b2ede75f743 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 10 Sep 2017 17:47:37 -0400 Subject: sub_808F080 --- src/field_map_obj.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 42769ed13..b33332661 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1510,3 +1510,14 @@ u16 GetFieldObjectFlagIdByFieldObjectId(u8 mapObjectId) { return GetFieldObjectFlagIdByLocalIdAndMap(gMapObjects[mapObjectId].localId, gMapObjects[mapObjectId].mapNum, gMapObjects[mapObjectId].mapGroup); } + +u8 sub_808F080(u8 localId, u8 mapNum, u8 mapGroup) +{ + u8 mapObjectId; + + if (TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + return 0xFF; + } + return gMapObjects[mapObjectId].trainerType; +} -- cgit v1.2.3 From bd9b81546f4eedae24278b54b02301b8184112a4 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 11 Sep 2017 10:19:03 -0400 Subject: through FieldObjectGetBerryTreeId --- src/field_map_obj.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index b33332661..d4f724079 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1521,3 +1521,25 @@ u8 sub_808F080(u8 localId, u8 mapNum, u8 mapGroup) } return gMapObjects[mapObjectId].trainerType; } + +u8 sub_808F0BC(u8 mapObjectId) +{ + return gMapObjects[mapObjectId].trainerType; +} + +u8 sub_808F0D4(u8 localId, u8 mapNum, u8 mapGroup) +{ + u8 mapObjectId; + + if (TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + return 0xFF; + } + return gMapObjects[mapObjectId].trainerRange_berryTreeId; +} + +u8 FieldObjectGetBerryTreeId(u8 mapObjectId) +{ + return gMapObjects[mapObjectId].trainerRange_berryTreeId; +} + -- cgit v1.2.3 From 5ad282c82c79205045fce2e8d7db993846d86b17 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 11 Sep 2017 10:29:00 -0400 Subject: GetFieldObjectTemplateByLocalIdAndMap --- src/field_map_obj.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index d4f724079..78269fd58 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -51,6 +51,7 @@ static bool8 FieldObjectDoesZCoordMatch(struct MapObject *, u8); //static void CameraObject_0(struct Sprite *); /*static*/ void CameraObject_1(struct Sprite *); //static void CameraObject_2(struct Sprite *); +/*static*/ struct MapObjectTemplate *FindFieldObjectTemplateInArrayByLocalId(u8 localId, struct MapObjectTemplate *templates, u8 count); // ROM data @@ -1543,3 +1544,23 @@ u8 FieldObjectGetBerryTreeId(u8 mapObjectId) return gMapObjects[mapObjectId].trainerRange_berryTreeId; } +struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup) +{ + struct MapObjectTemplate *templates; + const struct MapHeader *mapHeader; + u8 count; + + if (gSaveBlock1Ptr->location.mapNum == mapNum && gSaveBlock1Ptr->location.mapGroup == mapGroup) + { + templates = gSaveBlock1Ptr->mapObjectTemplates; + count = gMapHeader.events->mapObjectCount; + } + else + { + mapHeader = get_mapheader_by_bank_and_number(mapGroup, mapNum); + templates = mapHeader->events->mapObjects; + count = mapHeader->events->mapObjectCount; + } + return FindFieldObjectTemplateInArrayByLocalId(localId, templates, count); +} + -- cgit v1.2.3 From 7c40186e35a35f4cf84612af5c9326b7879342f2 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 11 Sep 2017 10:31:09 -0400 Subject: FindFieldObjectTemplateInArrayByLocalId --- src/field_map_obj.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 78269fd58..86ac6a00f 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1564,3 +1564,16 @@ struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8 localId, u8 m return FindFieldObjectTemplateInArrayByLocalId(localId, templates, count); } +struct MapObjectTemplate *FindFieldObjectTemplateInArrayByLocalId(u8 localId, struct MapObjectTemplate *templates, u8 count) +{ + u8 i; + + for (i = 0; i < count; i ++) + { + if (templates[i].localId == localId) + { + return &templates[i]; + } + } + return NULL; +} -- cgit v1.2.3 From 2b9b75a8245c32467d97ffeef280003c4fe0bb66 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 11 Sep 2017 10:40:34 -0400 Subject: sub_808F1B4 --- src/field_map_obj.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 86ac6a00f..56c5dee85 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1577,3 +1577,21 @@ struct MapObjectTemplate *FindFieldObjectTemplateInArrayByLocalId(u8 localId, st } return NULL; } + +struct MapObjectTemplate *sub_808F1B4(struct MapObject *mapObject) +{ + int i; + + if (mapObject->mapNum != gSaveBlock1Ptr->location.mapNum || mapObject->mapGroup != gSaveBlock1Ptr->location.mapGroup) + { + return NULL; + } + for (i = 0; i < 64; i ++) // Using ARRAY_COUNT here results in the wrong conditional branch instruction (bls instead of ble) + { + if (mapObject->localId == gSaveBlock1Ptr->mapObjectTemplates[i].localId) + { + return &gSaveBlock1Ptr->mapObjectTemplates[i]; + } + } + return NULL; +} -- cgit v1.2.3 From 9306122359968579b27b9a41e3cfd082860a4231 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 11 Sep 2017 10:46:26 -0400 Subject: through sub_808F23C --- src/field_map_obj.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 56c5dee85..59f8d35a1 100644 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1578,7 +1578,7 @@ struct MapObjectTemplate *FindFieldObjectTemplateInArrayByLocalId(u8 localId, st return NULL; } -struct MapObjectTemplate *sub_808F1B4(struct MapObject *mapObject) +struct MapObjectTemplate *sub_808F1B4(const struct MapObject *mapObject) { int i; @@ -1595,3 +1595,37 @@ struct MapObjectTemplate *sub_808F1B4(struct MapObject *mapObject) } return NULL; } + +void sub_808F208(const struct MapObject *mapObject) +{ + struct MapObjectTemplate *mapObjectTemplate; + + mapObjectTemplate = sub_808F1B4(mapObject); + if (mapObjectTemplate != NULL) + { + mapObjectTemplate->x = mapObject->coords2.x - 7; + mapObjectTemplate->y = mapObject->coords2.y - 7; + } +} + +void sub_808F228(const struct MapObject *mapObject, const u8 *script) +{ + struct MapObjectTemplate *mapObjectTemplate; + + mapObjectTemplate = sub_808F1B4(mapObject); + if (mapObjectTemplate != NULL) + { + mapObjectTemplate->script = script; + } +} + +void sub_808F23C(const struct MapObject *mapObject, u8 movementType) +{ + struct MapObjectTemplate *mapObjectTemplate; + + mapObjectTemplate = sub_808F1B4(mapObject); + if (mapObjectTemplate != NULL) + { + mapObjectTemplate->movementType = movementType; + } +} -- cgit v1.2.3 From c6ef3442621227562f15017441aa6fb7709e7187 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 12 Sep 2017 16:17:52 -0400 Subject: sub_808F254 --- src/field_map_obj.c | 10 ++++++++++ 1 file changed, 10 insertions(+) mode change 100644 => 100755 src/field_map_obj.c (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c old mode 100644 new mode 100755 index 59f8d35a1..af36d95f7 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1629,3 +1629,13 @@ void sub_808F23C(const struct MapObject *mapObject, u8 movementType) mapObjectTemplate->movementType = movementType; } } + +void sub_808F254(u8 localId, u8 mapNum, u8 mapGroup) +{ + u8 mapObjectId; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + sub_808F208(&gMapObjects[mapObjectId]); + } +} -- cgit v1.2.3 From 9286c93c8afd9505259487481e45db6956444004 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 12 Sep 2017 16:47:51 -0400 Subject: npc_paltag_set_load --- src/field_map_obj.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index af36d95f7..b4617cd5a 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -5,6 +5,7 @@ #include "sprite.h" #include "rom4.h" #include "data3.h" +#include "event_scripts.h" #include "berry.h" #include "palette.h" #include "field_player_avatar.h" @@ -1163,7 +1164,7 @@ void pal_patch_for_npc(u16 paletteTag, u8 paletteSlot) LoadPalette(gUnknown_0850BBC8[paletteIdx].data, 16 * paletteSlot + 256, 0x20); } -void pal_patch_for_npc_range(u16 *paletteTags, u8 minSlot, u8 maxSlot) +void pal_patch_for_npc_range(const u16 *paletteTags, u8 minSlot, u8 maxSlot) { while (minSlot < maxSlot) { @@ -1639,3 +1640,37 @@ void sub_808F254(u8 localId, u8 mapNum, u8 mapGroup) sub_808F208(&gMapObjects[mapObjectId]); } } + +void sub_808F28C(u8 localId, u8 mapNum, u8 mapGroup, u8 action) +{ + u8 mapObjectId; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + switch (action) + { + case 6: + sub_808F228(&gMapObjects[mapObjectId], gUnknown_082766A2); + break; + case 7: + sub_808F228(&gMapObjects[mapObjectId], gUnknown_082766A6); + break; + } + } +} + +void npc_paltag_set_load(u8 a0) +{ + gpu_pal_allocator_reset__manage_upper_four(); + gUnknown_020375B6 = 0x11ff; + gUnknown_020375B4 = a0; + if (a0 == 1) + { + pal_patch_for_npc_range(gUnknown_0850BE38[gUnknown_020375B4], 0, 6); + gReservedSpritePaletteCount = 8; + } + else + { + pal_patch_for_npc_range(gUnknown_0850BE38[gUnknown_020375B4], 0, 10); + } +} -- cgit v1.2.3 From c8696f15528add1c1a4a195c5fc02192c3f04a77 Mon Sep 17 00:00:00 2001 From: scnorton Date: Tue, 12 Sep 2017 17:35:08 -0400 Subject: npc_paltag_by_palslot --- src/field_map_obj.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index b4617cd5a..e142a35d6 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1659,12 +1659,12 @@ void sub_808F28C(u8 localId, u8 mapNum, u8 mapGroup, u8 action) } } -void npc_paltag_set_load(u8 a0) +void npc_paltag_set_load(u8 palSlot) { gpu_pal_allocator_reset__manage_upper_four(); gUnknown_020375B6 = 0x11ff; - gUnknown_020375B4 = a0; - if (a0 == 1) + gUnknown_020375B4 = palSlot; + if (palSlot == 1) { pal_patch_for_npc_range(gUnknown_0850BE38[gUnknown_020375B4], 0, 6); gReservedSpritePaletteCount = 8; @@ -1674,3 +1674,21 @@ void npc_paltag_set_load(u8 a0) pal_patch_for_npc_range(gUnknown_0850BE38[gUnknown_020375B4], 0, 10); } } + +u16 npc_paltag_by_palslot(u8 palSlot) +{ + u8 i; + + if (palSlot < 10) + { + return gUnknown_0850BE38[gUnknown_020375B4][palSlot]; + } + for (i = 0; gUnknown_0850BD78[i].tag != 0x11ff; i ++) + { + if (gUnknown_0850BD78[i].tag == gUnknown_020375B6) + { + return gUnknown_0850BD78[i].data[gUnknown_020375B4]; + } + } + return 0x11ff; +} -- cgit v1.2.3 From 28b272bf52e32374a3d0e493b47953bfad8e9cac Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 13 Sep 2017 09:41:11 -0400 Subject: NoMovement1, GoRandomDirections --- src/field_map_obj.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index e142a35d6..3dd47d540 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -20,6 +20,29 @@ #define NUM_FIELD_MAP_OBJECT_TEMPLATES 0x51 +#define null_object_step(name, retval) \ +static bool8 FieldObjectCB2_##name(struct MapObject *, struct Sprite *);\ +void FieldObjectCB_##name(struct Sprite *sprite)\ +{\ + FieldObjectStep(&gMapObjects[sprite->data0], sprite, FieldObjectCB2_##name);\ +}\ +static bool8 FieldObjectCB2_##name(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + return (retval);\ +} + +#define field_object_step(name, table) \ +extern bool8 (*const (table)[])(struct MapObject *, struct Sprite *);\ +static bool8 FieldObjectCB2_##name(struct MapObject *, struct Sprite *);\ +void FieldObjectCB_##name(struct Sprite *sprite)\ +{\ + FieldObjectStep(&gMapObjects[sprite->data0], sprite, FieldObjectCB2_##name);\ +}\ +static bool8 FieldObjectCB2_##name(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + return (table)[sprite->data1](mapObject, sprite);\ +} + // Static struct declarations // Static RAM declarations @@ -1692,3 +1715,8 @@ u16 npc_paltag_by_palslot(u8 palSlot) } return 0x11ff; } + +null_object_step(NoMovement1, FALSE) + +field_object_step(GoRandomDirections, gUnknown_0850D6F4) + -- cgit v1.2.3 From e26501f130ed84b160f80232db642ec49722025f Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 13 Sep 2017 10:59:25 -0400 Subject: Support functions for GoRandomDirections --- src/field_map_obj.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 3dd47d540..90b2f0302 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4,6 +4,7 @@ #include "malloc.h" #include "sprite.h" #include "rom4.h" +#include "rng.h" #include "data3.h" #include "event_scripts.h" #include "berry.h" @@ -76,6 +77,14 @@ static bool8 FieldObjectDoesZCoordMatch(struct MapObject *, u8); /*static*/ void CameraObject_1(struct Sprite *); //static void CameraObject_2(struct Sprite *); /*static*/ struct MapObjectTemplate *FindFieldObjectTemplateInArrayByLocalId(u8 localId, struct MapObjectTemplate *templates, u8 count); +void npc_reset(struct MapObject *, struct Sprite *); +void FieldObjectSetRegularAnim(struct MapObject *, struct Sprite *, u8); +u8 GetFaceDirectionAnimId(u8); +bool8 FieldObjectExecRegularAnim(struct MapObject *, struct Sprite *); +void sub_8097978(struct Sprite *, s16); +bool8 sub_809797C(struct Sprite *); +bool8 sub_8092B88(struct MapObject *, u8); +u8 GetGoSpeed0AnimId(u8); // ROM data @@ -1716,7 +1725,77 @@ u16 npc_paltag_by_palslot(u8 palSlot) return 0x11ff; } +// Map Object Step Callbacks + null_object_step(NoMovement1, FALSE) field_object_step(GoRandomDirections, gUnknown_0850D6F4) +bool8 sub_808F44C(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_808F460(struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_808F48C(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (!FieldObjectExecRegularAnim(mapObject, sprite)) + { + return FALSE; + } + sub_8097978(sprite, gUnknown_0850D6DC[Random() & 0x03]); + sprite->data1 = 3; + return TRUE; +} + +bool8 sub_808F4C8(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_809797C(sprite)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_808F4E8(struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[4]; + u8 chosenDirection; + + memcpy(directions, gUnknown_0850D710, sizeof directions); + chosenDirection = directions[Random() & 0x03]; + FieldObjectSetDirection(mapObject, chosenDirection); + sprite->data1 = 5; + if (sub_8092B88(mapObject, chosenDirection)) + { + sprite->data1 = 1; + } + return TRUE; +} + +bool8 sub_808F534(struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetGoSpeed0AnimId(mapObject->placeholder18)); + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 6; + return TRUE; +} + +bool8 sub_808F564(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 1; + } + return FALSE; +} -- cgit v1.2.3 From d72231379bd5b113744cf28c7fe9c9d6784e0174 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 13 Sep 2017 19:13:44 -0400 Subject: FieldObjectIsTrainerAndCloseToPlayer --- src/field_map_obj.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 90b2f0302..f86e544a8 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1799,3 +1799,36 @@ bool8 sub_808F564(struct MapObject *mapObject, struct Sprite *sprite) } return FALSE; } + +bool8 FieldObjectIsTrainerAndCloseToPlayer(struct MapObject *mapObject) +{ + s16 playerX; + s16 playerY; + s16 objX; + s16 objY; + s16 minX; + s16 maxX; + s16 minY; + s16 maxY; + + if (!TestPlayerAvatarFlags(0x80)) + { + return FALSE; + } + if (mapObject->trainerType != 1 && mapObject->trainerType != 3) + { + return FALSE; + } + PlayerGetDestCoords(&playerX, &playerY); + objX = mapObject->coords2.x; + objY = mapObject->coords2.y; + minX = objX - mapObject->trainerRange_berryTreeId; + minY = objY - mapObject->trainerRange_berryTreeId; + maxX = objX + mapObject->trainerRange_berryTreeId; + maxY = objY + mapObject->trainerRange_berryTreeId; + if (minX > playerX || maxX < playerX || minY > playerY || maxY < playerY) + { + return FALSE; + } + return TRUE; +} -- cgit v1.2.3 From c2e31f0618e19a1edad6bfface74901c8cd405f7 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 13 Sep 2017 19:21:05 -0400 Subject: sub_808F608 --- src/field_map_obj.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index f86e544a8..fd3cc7967 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1832,3 +1832,26 @@ bool8 FieldObjectIsTrainerAndCloseToPlayer(struct MapObject *mapObject) } return TRUE; } + +u8 sub_808F608(s16 x1, s16 x2, s16 y1, s16 y2) +{ + u8 retval; + + if (y1 > y2) + { + retval = DIR_EAST; + if (x1 < 0) + { + retval = DIR_WEST; + } + } + else + { + retval = DIR_SOUTH; + if (x2 < 0) + { + retval = DIR_NORTH; + } + } + return retval; +} -- cgit v1.2.3 From f9de01dc863fb0b9a7a2d4c4412e213b259eb4c7 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 13 Sep 2017 19:45:59 -0400 Subject: sub_808F638 and sub_808F648 --- src/field_map_obj.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index fd3cc7967..0cb73620c 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1855,3 +1855,27 @@ u8 sub_808F608(s16 x1, s16 x2, s16 y1, s16 y2) } return retval; } + +u8 sub_808F638(s16 x1, s16 x2, s16 y1, s16 y2) +{ + u8 retval; + + retval = DIR_SOUTH; + if (x2 < 0) + { + retval = DIR_NORTH; + } + return retval; +} + +u8 sub_808F648(s16 x1, s16 x2, s16 y1, s16 y2) +{ + u8 retval; + + retval = DIR_EAST; + if (x1 < 0) + { + retval = DIR_WEST; + } + return retval; +} -- cgit v1.2.3 From a04666e2d3f04e0f8158ce2a769042f696846830 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 13 Sep 2017 19:54:43 -0400 Subject: Running-past facing direction callbacks (North/East restricted) --- src/field_map_obj.c | 68 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 0cb73620c..4b92a792d 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1833,49 +1833,73 @@ bool8 FieldObjectIsTrainerAndCloseToPlayer(struct MapObject *mapObject) return TRUE; } -u8 sub_808F608(s16 x1, s16 x2, s16 y1, s16 y2) +u8 GetRegularRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) { - u8 retval; + u8 direction; - if (y1 > y2) + if (dx2 > dy2) { - retval = DIR_EAST; - if (x1 < 0) + direction = DIR_EAST; + if (dx1 < 0) { - retval = DIR_WEST; + direction = DIR_WEST; } } else { - retval = DIR_SOUTH; - if (x2 < 0) + direction = DIR_SOUTH; + if (dy1 < 0) { - retval = DIR_NORTH; + direction = DIR_NORTH; } } - return retval; + return direction; } -u8 sub_808F638(s16 x1, s16 x2, s16 y1, s16 y2) +u8 GetNorthSouthRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) { - u8 retval; + u8 direction; - retval = DIR_SOUTH; - if (x2 < 0) + direction = DIR_SOUTH; + if (dy1 < 0) { - retval = DIR_NORTH; + direction = DIR_NORTH; } - return retval; + return direction; } -u8 sub_808F648(s16 x1, s16 x2, s16 y1, s16 y2) +u8 GetEastWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) { - u8 retval; + u8 direction; - retval = DIR_EAST; - if (x1 < 0) + direction = DIR_EAST; + if (dx1 < 0) { - retval = DIR_WEST; + direction = DIR_WEST; } - return retval; + return direction; +} + +u8 GetNorthEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +{ + u8 direction; + + direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_SOUTH) + { + direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_EAST) + { + direction = DIR_NORTH; + } + } + else if (direction == DIR_EAST) + { + direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_SOUTH) + { + direction = DIR_NORTH; + } + } + return direction; } -- cgit v1.2.3 From 6b906d95b986611d148780e8c8fc0be367569ca2 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 13 Sep 2017 20:22:38 -0400 Subject: Three more running-past-facing-direction callbacks --- src/field_map_obj.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 4b92a792d..00ccb4493 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1903,3 +1903,75 @@ u8 GetNorthEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) } return direction; } + +u8 GetNorthWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +{ + u8 direction; + + direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_SOUTH) + { + direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_WEST) + { + direction = DIR_NORTH; + } + } + else if (direction == DIR_WEST) + { + direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_SOUTH) + { + direction = DIR_NORTH; + } + } + return direction; +} + +u8 GetSouthEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +{ + u8 direction; + + direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_NORTH) + { + direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_EAST) + { + direction = DIR_SOUTH; + } + } + else if (direction == DIR_EAST) + { + direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_NORTH) + { + direction = DIR_SOUTH; + } + } + return direction; +} + +u8 GetSouthWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +{ + u8 direction; + + direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_NORTH) + { + direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_WEST) + { + direction = DIR_SOUTH; + } + } + else if (direction == DIR_WEST) + { + direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_NORTH) + { + direction = DIR_SOUTH; + } + } + return direction; +} -- cgit v1.2.3 From c1f5183f4033fa29868fdc1c7aa64a51fd939615 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 13 Sep 2017 20:26:08 -0400 Subject: Three-direction get-running-past-facing callbacks --- src/field_map_obj.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 00ccb4493..48b423d85 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1975,3 +1975,51 @@ u8 GetSouthWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) } return direction; } + +u8 GetNonEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +{ + u8 direction; + + direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_EAST) + { + direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + } + return direction; +} + +u8 GetNonWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +{ + u8 direction; + + direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_WEST) + { + direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + } + return direction; +} + +u8 GetNonSouthRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +{ + u8 direction; + + direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_SOUTH) + { + direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + } + return direction; +} + +u8 GetNonNorthRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +{ + u8 direction; + + direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + if (direction == DIR_NORTH) + { + direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + } + return direction; +} -- cgit v1.2.3 From ddf712beac8f166c90c0f97d2a6ccdc97c7f6d08 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 13 Sep 2017 20:34:25 -0400 Subject: sub_808F8BC --- src/field_map_obj.c | 100 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 48b423d85..24f48db40 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -93,6 +93,7 @@ const u8 gUnknown_0850557C[NUM_FIELD_MAP_OBJECT_TEMPLATES]; const u8 gUnknown_085055CD[NUM_FIELD_MAP_OBJECT_TEMPLATES]; const struct MapObjectGraphicsInfo *const gMauvilleOldManGraphicsInfoPointers[7]; const struct MapObjectGraphicsInfo *const gFieldObjectGraphicsInfoPointers[0xEF]; +u8 (*const gUnknown_0850D714[11])(s16, s16, s16, s16); // Code @@ -1833,14 +1834,14 @@ bool8 FieldObjectIsTrainerAndCloseToPlayer(struct MapObject *mapObject) return TRUE; } -u8 GetRegularRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetRegularRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; - if (dx2 > dy2) + if (absdx > absdy) { direction = DIR_EAST; - if (dx1 < 0) + if (dx < 0) { direction = DIR_WEST; } @@ -1848,7 +1849,7 @@ u8 GetRegularRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) else { direction = DIR_SOUTH; - if (dy1 < 0) + if (dy < 0) { direction = DIR_NORTH; } @@ -1856,38 +1857,38 @@ u8 GetRegularRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) return direction; } -u8 GetNorthSouthRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetNorthSouthRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; direction = DIR_SOUTH; - if (dy1 < 0) + if (dy < 0) { direction = DIR_NORTH; } return direction; } -u8 GetEastWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetEastWestRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; direction = DIR_EAST; - if (dx1 < 0) + if (dx < 0) { direction = DIR_WEST; } return direction; } -u8 GetNorthEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetNorthEastRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; - direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetRegularRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_SOUTH) { - direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetEastWestRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_EAST) { direction = DIR_NORTH; @@ -1895,7 +1896,7 @@ u8 GetNorthEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) } else if (direction == DIR_EAST) { - direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetNorthSouthRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_SOUTH) { direction = DIR_NORTH; @@ -1904,14 +1905,14 @@ u8 GetNorthEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) return direction; } -u8 GetNorthWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetNorthWestRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; - direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetRegularRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_SOUTH) { - direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetEastWestRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_WEST) { direction = DIR_NORTH; @@ -1919,7 +1920,7 @@ u8 GetNorthWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) } else if (direction == DIR_WEST) { - direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetNorthSouthRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_SOUTH) { direction = DIR_NORTH; @@ -1928,14 +1929,14 @@ u8 GetNorthWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) return direction; } -u8 GetSouthEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetSouthEastRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; - direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetRegularRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_NORTH) { - direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetEastWestRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_EAST) { direction = DIR_SOUTH; @@ -1943,7 +1944,7 @@ u8 GetSouthEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) } else if (direction == DIR_EAST) { - direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetNorthSouthRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_NORTH) { direction = DIR_SOUTH; @@ -1952,14 +1953,14 @@ u8 GetSouthEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) return direction; } -u8 GetSouthWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetSouthWestRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; - direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetRegularRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_NORTH) { - direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetEastWestRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_WEST) { direction = DIR_SOUTH; @@ -1967,7 +1968,7 @@ u8 GetSouthWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) } else if (direction == DIR_WEST) { - direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetNorthSouthRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_NORTH) { direction = DIR_SOUTH; @@ -1976,50 +1977,77 @@ u8 GetSouthWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) return direction; } -u8 GetNonEastRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetNonEastRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; - direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetRegularRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_EAST) { - direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetNorthSouthRunningPastFacingDirection(dx, dy, absdx, absdy); } return direction; } -u8 GetNonWestRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetNonWestRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; - direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetRegularRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_WEST) { - direction = GetNorthSouthRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetNorthSouthRunningPastFacingDirection(dx, dy, absdx, absdy); } return direction; } -u8 GetNonSouthRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetNonSouthRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; - direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetRegularRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_SOUTH) { - direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetEastWestRunningPastFacingDirection(dx, dy, absdx, absdy); } return direction; } -u8 GetNonNorthRunningPastFacingDirection(s16 dx1, s16 dy1, s16 dx2, s16 dy2) +u8 GetNonNorthRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; - direction = GetRegularRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetRegularRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_NORTH) { - direction = GetEastWestRunningPastFacingDirection(dx1, dy1, dx2, dy2); + direction = GetEastWestRunningPastFacingDirection(dx, dy, absdx, absdy); } return direction; } + +u8 sub_808F8BC(struct MapObject *mapObject, u8 movementType) +{ + s16 dx; + s16 dy; + s16 absdx; + s16 absdy; + + if (!FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + return 0; + } + PlayerGetDestCoords(&dx, &dy); + dx -= mapObject->coords2.x; + dy -= mapObject->coords2.y; + absdx = dx; + absdy = dy; + if (absdx < 0) + { + absdx = -absdx; + } + if (absdy < 0) + { + absdy = -absdy; + } + return gUnknown_0850D714[movementType](dx, dy, absdx, absdy); +} -- cgit v1.2.3 From 2895765964014d241808ee936293d255a6578daa Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 13 Sep 2017 20:36:58 -0400 Subject: LookRandomDirections --- src/field_map_obj.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 24f48db40..9fd533f60 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2051,3 +2051,5 @@ u8 sub_808F8BC(struct MapObject *mapObject, u8 movementType) } return gUnknown_0850D714[movementType](dx, dy, absdx, absdy); } + +field_object_step(LookRandomDirections, gUnknown_0850D740) -- cgit v1.2.3 From c1c12981fe5d89c85750a477229b3b31f2e6f2ee Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 13 Sep 2017 21:11:59 -0400 Subject: LookRandomDirections helpers --- src/field_map_obj.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 9fd533f60..40129cc3f 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2053,3 +2053,54 @@ u8 sub_808F8BC(struct MapObject *mapObject, u8 movementType) } field_object_step(LookRandomDirections, gUnknown_0850D740) + +bool8 sub_808F988(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_808F99C(struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_808F9C8(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + sub_8097978(sprite, gUnknown_0850D6DC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_808FA0C(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_809797C(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_808FA3C(struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[4]; + u8 direction; + + memcpy(directions, gUnknown_0850D710, sizeof directions); + direction = sub_808F8BC(mapObject, 0); + if (direction == 0) + { + direction = directions[Random() & 0x03]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} -- cgit v1.2.3 From 0ae3347e472686be8c7c21862afe4a62222cdcd1 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 14 Sep 2017 08:38:21 -0400 Subject: Rename some functions --- src/field_map_obj.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 40129cc3f..cf11e675d 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -81,8 +81,8 @@ void npc_reset(struct MapObject *, struct Sprite *); void FieldObjectSetRegularAnim(struct MapObject *, struct Sprite *, u8); u8 GetFaceDirectionAnimId(u8); bool8 FieldObjectExecRegularAnim(struct MapObject *, struct Sprite *); -void sub_8097978(struct Sprite *, s16); -bool8 sub_809797C(struct Sprite *); +void SetFieldObjectStepTimer(struct Sprite *, s16); +bool8 RunFieldObjectStepTimer(struct Sprite *); bool8 sub_8092B88(struct MapObject *, u8); u8 GetGoSpeed0AnimId(u8); @@ -1752,14 +1752,14 @@ bool8 sub_808F48C(struct MapObject *mapObject, struct Sprite *sprite) { return FALSE; } - sub_8097978(sprite, gUnknown_0850D6DC[Random() & 0x03]); + SetFieldObjectStepTimer(sprite, gUnknown_0850D6DC[Random() & 0x03]); sprite->data1 = 3; return TRUE; } bool8 sub_808F4C8(struct MapObject *mapObject, struct Sprite *sprite) { - if (sub_809797C(sprite)) + if (RunFieldObjectStepTimer(sprite)) { sprite->data1 = 4; return TRUE; @@ -2025,7 +2025,7 @@ u8 GetNonNorthRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) return direction; } -u8 sub_808F8BC(struct MapObject *mapObject, u8 movementType) +u8 GetRunningPastFacingDirection(struct MapObject *mapObject, u8 movementType) { s16 dx; s16 dy; @@ -2072,7 +2072,7 @@ bool8 sub_808F9C8(struct MapObject *mapObject, struct Sprite *sprite) { if (FieldObjectExecRegularAnim(mapObject, sprite)) { - sub_8097978(sprite, gUnknown_0850D6DC[Random() & 0x03]); + SetFieldObjectStepTimer(sprite, gUnknown_0850D6DC[Random() & 0x03]); mapObject->mapobj_bit_1 = FALSE; sprite->data1 = 3; } @@ -2081,7 +2081,7 @@ bool8 sub_808F9C8(struct MapObject *mapObject, struct Sprite *sprite) bool8 sub_808FA0C(struct MapObject *mapObject, struct Sprite *sprite) { - if (sub_809797C(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) { sprite->data1 = 4; return TRUE; @@ -2095,7 +2095,7 @@ bool8 sub_808FA3C(struct MapObject *mapObject, struct Sprite *sprite) u8 direction; memcpy(directions, gUnknown_0850D710, sizeof directions); - direction = sub_808F8BC(mapObject, 0); + direction = GetRunningPastFacingDirection(mapObject, 0); if (direction == 0) { direction = directions[Random() & 0x03]; -- cgit v1.2.3 From 4a1383d77bb1da701290848020b5ebf942182283 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 14 Sep 2017 21:22:14 -0400 Subject: RandomlyGoNorthOrSouth --- src/field_map_obj.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index cf11e675d..5b0916e33 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -83,7 +83,7 @@ u8 GetFaceDirectionAnimId(u8); bool8 FieldObjectExecRegularAnim(struct MapObject *, struct Sprite *); void SetFieldObjectStepTimer(struct Sprite *, s16); bool8 RunFieldObjectStepTimer(struct Sprite *); -bool8 sub_8092B88(struct MapObject *, u8); +bool8 npc_block_way__next_tile(struct MapObject *, u8); u8 GetGoSpeed0AnimId(u8); // ROM data @@ -1776,7 +1776,7 @@ bool8 sub_808F4E8(struct MapObject *mapObject, struct Sprite *sprite) chosenDirection = directions[Random() & 0x03]; FieldObjectSetDirection(mapObject, chosenDirection); sprite->data1 = 5; - if (sub_8092B88(mapObject, chosenDirection)) + if (npc_block_way__next_tile(mapObject, chosenDirection)) { sprite->data1 = 1; } @@ -2104,3 +2104,74 @@ bool8 sub_808FA3C(struct MapObject *mapObject, struct Sprite *sprite) sprite->data1 = 1; return TRUE; } + +field_object_step(RandomlyGoNorthOrSouth, gUnknown_0850D754) + +bool8 sub_808FAC8(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_808FADC(struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_808FB08(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (!FieldObjectExecRegularAnim(mapObject, sprite)) + { + return FALSE; + } + SetFieldObjectStepTimer(sprite, gUnknown_0850D6DC[Random() & 0x03]); + sprite->data1 = 3; + return TRUE; +} + +bool8 sub_808FB44(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_808FB64(struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[2]; + u8 direction; + + memcpy(directions, gUnknown_0850D770, sizeof directions); + direction = directions[Random() & 0x01]; + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 5; + if (npc_block_way__next_tile(mapObject, direction)) + { + sprite->data1 = 1; + } + return TRUE; +} + +bool8 sub_808FBB0(struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetGoSpeed0AnimId(mapObject->placeholder18)); + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 6; + return TRUE; +} + +bool8 sub_808FBE0(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 1; + } + return FALSE; +} -- cgit v1.2.3 From 68c62595f569e9b6ccca1596776330ce31d9d805 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 14 Sep 2017 21:25:30 -0400 Subject: RandomlyGoEastOrWest --- src/field_map_obj.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 5b0916e33..edd16b6a8 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2175,3 +2175,74 @@ bool8 sub_808FBE0(struct MapObject *mapObject, struct Sprite *sprite) } return FALSE; } + +field_object_step(RandomlyGoEastOrWest, gUnknown_0850D774) + +bool8 sub_808FC4C(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_808FC60(struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_808FC8C(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (!FieldObjectExecRegularAnim(mapObject, sprite)) + { + return FALSE; + } + SetFieldObjectStepTimer(sprite, gUnknown_0850D6DC[Random() & 0x03]); + sprite->data1 = 3; + return TRUE; +} + +bool8 sub_808FCC8(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_808FCE8(struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[2]; + u8 direction; + + memcpy(directions, gUnknown_0850D790, sizeof directions); + direction = directions[Random() & 0x01]; + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 5; + if (npc_block_way__next_tile(mapObject, direction)) + { + sprite->data1 = 1; + } + return TRUE; +} + +bool8 sub_808FD34(struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetGoSpeed0AnimId(mapObject->placeholder18)); + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 6; + return TRUE; +} + +bool8 sub_808FD64(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 1; + } + return FALSE; +} -- cgit v1.2.3 From 9a13b1f34e8ccb2b4c868a5c7d06ff86210125f2 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 14 Sep 2017 21:30:14 -0400 Subject: FaceFixedDirection --- src/field_map_obj.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index edd16b6a8..04b207d96 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2246,3 +2246,29 @@ bool8 sub_808FD64(struct MapObject *mapObject, struct Sprite *sprite) } return FALSE; } + +field_object_step(FaceFixedDirection, gUnknown_0850D794) + +bool8 sub_808FDD0(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_808FDFC(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + sprite->data1 = 2; + return TRUE; + } + return FALSE; +} + +bool8 sub_808FE1C(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_1 = FALSE; + return FALSE; +} -- cgit v1.2.3 From 9f6a4be9f05a46031d20ed7a48398147def2643c Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 15 Sep 2017 14:26:01 -0400 Subject: BerryTree --- src/field_map_obj.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 04b207d96..16a9e5851 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -16,6 +16,7 @@ #include "field_ground_effect.h" #include "map_obj_8097404.h" #include "mauville_old_man.h" +#include "field_effect.h" #include "field_effect_helpers.h" #include "field_map_obj.h" @@ -1884,7 +1885,7 @@ u8 GetEastWestRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) u8 GetNorthEastRunningPastFacingDirection(s16 dx, s16 dy, s16 absdx, s16 absdy) { u8 direction; - + direction = GetRegularRunningPastFacingDirection(dx, dy, absdx, absdy); if (direction == DIR_SOUTH) { @@ -2272,3 +2273,110 @@ bool8 sub_808FE1C(struct MapObject *mapObject, struct Sprite *sprite) mapObject->mapobj_bit_1 = FALSE; return FALSE; } + +static bool8 FieldObjectCB2_BerryTree(struct MapObject *mapObject, struct Sprite *sprite); +extern bool8 (*const gUnknown_0850D7A0[])(struct MapObject *mapObject, struct Sprite *sprite); +void FieldObjectCB_BerryTree(struct Sprite *sprite) +{ + struct MapObject *mapObject; + + mapObject = &gMapObjects[sprite->data0]; + if (!(sprite->data7 & 0x0001)) + { + get_berry_tree_graphics(mapObject, sprite); + sprite->data7 |= 0x0001; + } + FieldObjectStep(mapObject, sprite, FieldObjectCB2_BerryTree); +} +static bool8 FieldObjectCB2_BerryTree(struct MapObject *mapObject, struct Sprite *sprite) +{ + return gUnknown_0850D7A0[sprite->data1](mapObject, sprite); +} + +bool8 do_berry_tree_growth_sparkle_1 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 berryStage; + + npc_reset(mapObject, sprite); + mapObject->mapobj_bit_13 = TRUE; + sprite->invisible = TRUE; + berryStage = GetStageByBerryTreeId(mapObject->trainerRange_berryTreeId); + if (berryStage == 0) + { + if (!(sprite->data7 & 0x0004) && sprite->animNum == 4) + { + gFieldEffectSpawnParams[0] = mapObject->coords2.x; + gFieldEffectSpawnParams[1] = mapObject->coords2.y; + gFieldEffectSpawnParams[2] = sprite->subpriority - 1; + gFieldEffectSpawnParams[3] = sprite->oam.priority; + FieldEffectStart(FLDEFF_BERRY_TREE_GROWTH_SPARKLE); + sprite->animNum = berryStage; + } + return FALSE; + } + mapObject->mapobj_bit_13 = FALSE; + sprite->invisible = FALSE; + berryStage --; + if (sprite->animNum != berryStage) + { + sprite->data1 = 2; + return TRUE; + } + get_berry_tree_graphics(mapObject, sprite); + FieldObjectSetRegularAnim(mapObject, sprite, 0x39); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_808FF48 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + sprite->data1 = 0; + return TRUE; + } + return FALSE; +} + +bool8 do_berry_tree_growth_sparkle_2 (struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 3; + sprite->data2 = 0; + sprite->data7 |= 0x0002; + gFieldEffectSpawnParams[0] = mapObject->coords2.x; + gFieldEffectSpawnParams[1] = mapObject->coords2.y; + gFieldEffectSpawnParams[2] = sprite->subpriority - 1; + gFieldEffectSpawnParams[3] = sprite->oam.priority; + FieldEffectStart(FLDEFF_BERRY_TREE_GROWTH_SPARKLE); + return TRUE; +} + +bool8 sub_808FFB4 (struct MapObject *mapObject, struct Sprite *sprite) +{ + sprite->data2 ++; + mapObject->mapobj_bit_13 = (sprite->data2 & 0x02) >> 1; + sprite->animPaused = TRUE; + if (sprite->data2 > 64) + { + get_berry_tree_graphics(mapObject, sprite); + sprite->data1 = 4; + sprite->data2 = 0; + return TRUE; + } + return FALSE; +} + +bool8 sub_8090004 (struct MapObject *mapObject, struct Sprite *sprite) +{ + sprite->data2 ++; + mapObject->mapobj_bit_13 = (sprite->data2 & 0x02) >> 1; + sprite->animPaused = TRUE; + if (sprite->data2 > 64) + { + sprite->data1 = 0; + sprite->data7 &= ~0x0002; + return TRUE; + } + return FALSE; +} -- cgit v1.2.3 From 7440bba1b19eb8fbd4fa91bc0ad2e722fa1e3c4c Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 15 Sep 2017 14:36:54 -0400 Subject: RandomlyLookNorthOrSouth --- src/field_map_obj.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 16a9e5851..88b4ab9b7 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2380,3 +2380,56 @@ bool8 sub_8090004 (struct MapObject *mapObject, struct Sprite *sprite) } return FALSE; } + +field_object_step(RandomlyLookNorthOrSouth, gUnknown_0850D7B4) + +bool8 sub_8090094 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_80900A8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_80900D4 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, gUnknown_0850D6DC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_8090118 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_8090148 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[2]; + u8 direction; + + memcpy(directions, gUnknown_0850D770, sizeof gUnknown_0850D770); + direction = GetRunningPastFacingDirection(mapObject, 1); + if (direction == 0) + { + direction = directions[Random() & 0x01]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} -- cgit v1.2.3 From bf101743c2d965c97ade9925ff6db17a35de31fc Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 15 Sep 2017 14:42:54 -0400 Subject: RandomlyLookEastOrWest --- src/field_map_obj.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 88b4ab9b7..7c99c8a97 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2433,3 +2433,56 @@ bool8 sub_8090148 (struct MapObject *mapObject, struct Sprite *sprite) sprite->data1 = 1; return TRUE; } + +field_object_step(RandomlyLookEastOrWest, gUnknown_0850D7C8) + +bool8 sub_80901D4 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_80901E8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8090214 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, gUnknown_0850D6DC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_8090258 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_8090288 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[2]; + u8 direction; + + memcpy(directions, gUnknown_0850D790, sizeof gUnknown_0850D790); + direction = GetRunningPastFacingDirection(mapObject, 2); + if (direction == 0) + { + direction = directions[Random() & 0x01]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} -- cgit v1.2.3 From 0571056955121d57f7ea691b40f807c8f80ef7b2 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 15 Sep 2017 15:26:51 -0400 Subject: RandomlyLookNorthOrWest --- src/field_map_obj.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 7c99c8a97..014001d93 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2486,3 +2486,56 @@ bool8 sub_8090288 (struct MapObject *mapObject, struct Sprite *sprite) sprite->data1 = 1; return TRUE; } + +field_object_step(RandomlyLookNorthOrWest, gUnknown_0850D7DC) + +bool8 sub_8090314 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_8090328 (struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8090354 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, gUnknown_0850D6EC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_8090398 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_80903C8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[2]; + u8 direction; + + memcpy(directions, gUnknown_0850D7F0, sizeof gUnknown_0850D7F0); + direction = GetRunningPastFacingDirection(mapObject, 3); + if (direction == 0) + { + direction = directions[Random() & 0x01]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} -- cgit v1.2.3 From 8c6367f997f4c53dfb1819d2cc42953fb7a82eb5 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 15 Sep 2017 15:53:07 -0400 Subject: RandomlyLookNorthOrEast --- src/field_map_obj.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 014001d93..1228d93be 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2096,7 +2096,7 @@ bool8 sub_808FA3C(struct MapObject *mapObject, struct Sprite *sprite) u8 direction; memcpy(directions, gUnknown_0850D710, sizeof directions); - direction = GetRunningPastFacingDirection(mapObject, 0); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_ANY); if (direction == 0) { direction = directions[Random() & 0x03]; @@ -2424,7 +2424,7 @@ bool8 sub_8090148 (struct MapObject *mapObject, struct Sprite *sprite) u8 direction; memcpy(directions, gUnknown_0850D770, sizeof gUnknown_0850D770); - direction = GetRunningPastFacingDirection(mapObject, 1); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_NORTH_SOUTH); if (direction == 0) { direction = directions[Random() & 0x01]; @@ -2477,7 +2477,7 @@ bool8 sub_8090288 (struct MapObject *mapObject, struct Sprite *sprite) u8 direction; memcpy(directions, gUnknown_0850D790, sizeof gUnknown_0850D790); - direction = GetRunningPastFacingDirection(mapObject, 2); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_EAST_WEST); if (direction == 0) { direction = directions[Random() & 0x01]; @@ -2530,7 +2530,60 @@ bool8 sub_80903C8 (struct MapObject *mapObject, struct Sprite *sprite) u8 direction; memcpy(directions, gUnknown_0850D7F0, sizeof gUnknown_0850D7F0); - direction = GetRunningPastFacingDirection(mapObject, 3); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_NORTH_WEST); + if (direction == 0) + { + direction = directions[Random() & 0x01]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} + +field_object_step(RandomlyLookNorthOrEast, gUnknown_0850D7F4) + +bool8 sub_8090454 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_8090468 (struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8090494 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, gUnknown_0850D6EC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_80904D8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_8090508 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[2]; + u8 direction; + + memcpy(directions, gUnknown_0850D808, sizeof gUnknown_0850D808); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_NORTH_EAST); if (direction == 0) { direction = directions[Random() & 0x01]; -- cgit v1.2.3 From b269048369afcb0a4bf5a5f251d9ff7506a3f588 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 15 Sep 2017 15:57:38 -0400 Subject: RandomlyLookSouthOrWest --- src/field_map_obj.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 1228d93be..639267890 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2592,3 +2592,56 @@ bool8 sub_8090508 (struct MapObject *mapObject, struct Sprite *sprite) sprite->data1 = 1; return TRUE; } + +field_object_step(RandomlyLookSouthOrWest, gUnknown_0850D80C) + +bool8 sub_8090594 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_80905A8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_80905D4 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, gUnknown_0850D6EC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_8090618 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_8090648 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[2]; + u8 direction; + + memcpy(directions, gUnknown_0850D820, sizeof gUnknown_0850D820); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_SOUTH_WEST); + if (direction == 0) + { + direction = directions[Random() & 0x01]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} -- cgit v1.2.3 From f6840ba7e7783cb961f6b6afb7ac7eb45717a13f Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 15 Sep 2017 16:00:39 -0400 Subject: RandomlyLookSouthOrEast --- src/field_map_obj.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 639267890..f4092265c 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2645,3 +2645,56 @@ bool8 sub_8090648 (struct MapObject *mapObject, struct Sprite *sprite) sprite->data1 = 1; return TRUE; } + +field_object_step(RandomlyLookSouthOrEast, gUnknown_0850D824) + +bool8 sub_80906D4 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_80906E8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8090714 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, gUnknown_0850D6EC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_8090758 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_8090788 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[2]; + u8 direction; + + memcpy(directions, gUnknown_0850D838, sizeof gUnknown_0850D838); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_SOUTH_EAST); + if (direction == 0) + { + direction = directions[Random() & 0x01]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} -- cgit v1.2.3 From 2e1ecdb87711172b1916f3e102315867c5b65d18 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 15 Sep 2017 16:08:01 -0400 Subject: Tridirectional spinners --- src/field_map_obj.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index f4092265c..0ccf6039f 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2698,3 +2698,215 @@ bool8 sub_8090788 (struct MapObject *mapObject, struct Sprite *sprite) sprite->data1 = 1; return TRUE; } + +field_object_step(RandomlyLookNorthOrSouthOrWest, gUnknown_0850D83C) + +bool8 sub_8090814 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_8090828 (struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8090854 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, gUnknown_0850D6EC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_8090898 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_80908C8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[4]; + u8 direction; + + memcpy(directions, gUnknown_0850D850, sizeof gUnknown_0850D850); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_NORTH_SOUTH_WEST); + if (direction == 0) + { + direction = directions[Random() & 0x03]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} + +field_object_step(RandomlyLookNorthOrSouthOrEast, gUnknown_0850D854) + +bool8 sub_8090954 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_8090968 (struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8090994 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, gUnknown_0850D6EC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_80909D8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_8090A08 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[4]; + u8 direction; + + memcpy(directions, gUnknown_0850D868, sizeof gUnknown_0850D868); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_NORTH_SOUTH_EAST); + if (direction == 0) + { + direction = directions[Random() & 0x03]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} + +field_object_step(RandomlyLookNorthOrEastOrWest, gUnknown_0850D86C) + +bool8 sub_8090A94 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_8090AA8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8090AD4 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, gUnknown_0850D6EC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_8090B18 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_8090B48 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[4]; + u8 direction; + + memcpy(directions, gUnknown_0850D880, sizeof gUnknown_0850D880); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_NORTH_EAST_WEST); + if (direction == 0) + { + direction = directions[Random() & 0x03]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} + +field_object_step(RandomlyLookSouthOrEastOrWest, gUnknown_0850D884) + +bool8 sub_8090BD4 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_8090BE8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8090C14 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, gUnknown_0850D6EC[Random() & 0x03]); + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_8090C58 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 4; + return TRUE; + } + return FALSE; +} + +bool8 sub_8090C88 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[4]; + u8 direction; + + memcpy(directions, gUnknown_0850D898, sizeof gUnknown_0850D898); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_SOUTH_EAST_WEST); + if (direction == 0) + { + direction = directions[Random() & 0x03]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 1; + return TRUE; +} -- cgit v1.2.3 From 1c6177f67895a20c99d7dfafd43afd83cf3bfff2 Mon Sep 17 00:00:00 2001 From: scnorton Date: Fri, 15 Sep 2017 16:34:03 -0400 Subject: Rotatoes --- src/field_map_obj.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 0ccf6039f..0ba4cc052 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -2910,3 +2910,93 @@ bool8 sub_8090C88 (struct MapObject *mapObject, struct Sprite *sprite) sprite->data1 = 1; return TRUE; } + +field_object_step(LookAroundCounterclockwise, gUnknown_0850D89C) + +bool8 sub_8090D14 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_8090D40 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, 48); + sprite->data1 = 2; + } + return FALSE; +} + +bool8 sub_8090D64 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_8090D90 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[5]; + u8 direction; + + memcpy(directions, gUnknown_0850D8AC, sizeof gUnknown_0850D8AC); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_ANY); + if (direction == 0) + { + direction = directions[mapObject->mapobj_unk_18]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 0; + return TRUE; +} + +field_object_step(LookAroundClockwise, gUnknown_0850D8B4) + +bool8 sub_8090E18 (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_8090E44 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + SetFieldObjectStepTimer(sprite, 48); + sprite->data1 = 2; + } + return FALSE; +} + +bool8 sub_8090E68 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (RunFieldObjectStepTimer(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject)) + { + sprite->data1 = 3; + } + return FALSE; +} + +bool8 sub_8090E94 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 directions[5]; + u8 direction; + + memcpy(directions, gUnknown_0850D8C4, sizeof gUnknown_0850D8C4); + direction = GetRunningPastFacingDirection(mapObject, RUNFOLLOW_ANY); + if (direction == 0) + { + direction = directions[mapObject->mapobj_unk_18]; + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 0; + return TRUE; +} -- cgit v1.2.3 From 79e8235701de373e7d7cb84162343c487c7e1a5e Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 15 Sep 2017 21:26:56 -0400 Subject: AlternatelyGoInOppositeDirections --- src/field_map_obj.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 0ba4cc052..91856d1ee 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3000,3 +3000,65 @@ bool8 sub_8090E94 (struct MapObject *mapObject, struct Sprite *sprite) sprite->data1 = 0; return TRUE; } + +field_object_step(AlternatelyGoInOppositeDirections, gUnknown_0850D8CC) + +bool8 sub_8090F1C (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_8090F30 (struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 direction; + + direction = gUnknown_085055CD[mapObject->animPattern]; + if (mapObject->mapobj_unk_21) + { + direction = GetOppositeDirection(direction); + } + FieldObjectSetDirection(mapObject, direction); + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8090F68 (struct MapObject *mapObject, struct Sprite *sprite) +{ + bool8 blockingWay; + u8 animId; + + if (mapObject->mapobj_unk_21 && mapObject->coords1.x == mapObject->coords2.x && mapObject->coords1.y == mapObject->coords2.y) + { + mapObject->mapobj_unk_21 = 0; + FieldObjectSetDirection(mapObject, GetOppositeDirection(mapObject->placeholder18)); + } + blockingWay = npc_block_way__next_tile(mapObject, mapObject->placeholder18); + animId = GetGoSpeed0AnimId(mapObject->placeholder18); + if (blockingWay == TRUE) + { + mapObject->mapobj_unk_21 ++; + FieldObjectSetDirection(mapObject, GetOppositeDirection(mapObject->placeholder18)); + animId = GetGoSpeed0AnimId(mapObject->placeholder18); + blockingWay = npc_block_way__next_tile(mapObject, mapObject->placeholder18); + } + if (blockingWay) + { + animId = GetStepInPlaceDelay16AnimId(mapObject->mapobj_unk_18); + } + FieldObjectSetRegularAnim(mapObject, sprite, animId); + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 3; + return TRUE; +} + +bool8 sub_8091020 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 1; + } + return FALSE; +} -- cgit v1.2.3 From 3e9e4b13ec977cc4f5dd696d2dc8d362f58317dc Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 15 Sep 2017 21:39:24 -0400 Subject: MoveFieldObjectInNextDirectionInSequence --- src/field_map_obj.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 91856d1ee..cfe04f395 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3062,3 +3062,39 @@ bool8 sub_8091020 (struct MapObject *mapObject, struct Sprite *sprite) } return FALSE; } + +bool8 sub_8091048(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + sprite->data1 = 1; + return TRUE; +} + +bool8 MoveFieldObjectInNextDirectionInSequence(struct MapObject *mapObject, struct Sprite *sprite, u8 *route) +{ + u8 blockingWay; + u8 animId; + + if (mapObject->mapobj_unk_21 == 3 && mapObject->coords1.x == mapObject->coords2.x && mapObject->coords1.y == mapObject->coords2.y) + { + mapObject->mapobj_unk_21 = 0; + } + FieldObjectSetDirection(mapObject, route[mapObject->mapobj_unk_21]); + animId = GetGoSpeed0AnimId(mapObject->placeholder18); + blockingWay = npc_block_way__next_tile(mapObject, mapObject->placeholder18); + if (blockingWay == TRUE) + { + mapObject->mapobj_unk_21 ++; + FieldObjectSetDirection(mapObject, route[mapObject->mapobj_unk_21]); + animId = GetGoSpeed0AnimId(mapObject->placeholder18); + blockingWay = npc_block_way__next_tile(mapObject, mapObject->placeholder18); + } + if (blockingWay) + { + animId = GetStepInPlaceDelay16AnimId(mapObject->mapobj_unk_18); + } + FieldObjectSetRegularAnim(mapObject, sprite, animId); + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 2; + return TRUE; +} -- cgit v1.2.3 From 54c8580d34b61dfd1db5dd91e301dfc788e564de Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 15 Sep 2017 22:12:45 -0400 Subject: rom_81700F8 --- src/rom_81700F8.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/rom_81700F8.c (limited to 'src') diff --git a/src/rom_81700F8.c b/src/rom_81700F8.c new file mode 100644 index 000000000..b786ff9f8 --- /dev/null +++ b/src/rom_81700F8.c @@ -0,0 +1,32 @@ +#include "global.h" +#include "main.h" +#include "gpu_regs.h" +#include "m4a.h" +#include "load_save.h" +#include "save.h" +#include "new_game.h" +#include "rom4.h" +#include "malloc.h" + +void sub_81700F8(void) +{ + u16 imeBackup; + + imeBackup = REG_IME; + REG_IME = 0; + RegisterRamReset(0x00000001); + ClearGpuRegBits(REG_OFFSET_DISPCNT, 0x80); + REG_IME = imeBackup; + gMain.inBattle = FALSE; + SetSaveBlocksPointers(sub_815355C()); + sub_808447C(); + ResetSaveCounters(); + sub_81534D0(0); + if (gSaveFileStatus == 0 || gSaveFileStatus == 2) + { + Sav2_ClearSetDefault(); + } + SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound); + InitHeap(gHeap, 0x1c000); + SetMainCallback2(sub_8086230); +} -- cgit v1.2.3 From a082f9258148831bfa35d925e4d0fd05e7479e6f Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 08:13:37 -0400 Subject: sub_8091110 --- src/field_map_obj.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index cfe04f395..0c6397730 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3098,3 +3098,13 @@ bool8 MoveFieldObjectInNextDirectionInSequence(struct MapObject *mapObject, stru sprite->data1 = 2; return TRUE; } + +bool8 sub_8091110(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 1; + } + return FALSE; +} -- cgit v1.2.3 From 86df6d10736e1b680e874d7440f478fe5ddf8105 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 08:44:43 -0400 Subject: Field object path movement --- src/field_map_obj.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 0c6397730..99d417ae2 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -45,6 +45,20 @@ static bool8 FieldObjectCB2_##name(struct MapObject *mapObject, struct Sprite *s return (table)[sprite->data1](mapObject, sprite);\ } +#define field_object_path(idx, table, sub, path, catch, coord)\ +field_object_step(GoInDirectionSequence##idx, table)\ +extern const u8 path[4];\ +bool8 sub(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + u8 route[sizeof(path)];\ + memcpy(route, path, sizeof(path));\ + if (mapObject->mapobj_unk_21 == (catch) && mapObject->coords1.coord == mapObject->coords2.coord)\ + {\ + mapObject->mapobj_unk_21 = (catch) + 1;\ + }\ + return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, route);\ +}\ + // Static struct declarations // Static RAM declarations @@ -3108,3 +3122,28 @@ bool8 sub_8091110(struct MapObject *mapObject, struct Sprite *sprite) } return FALSE; } + +field_object_path( 1, gUnknown_0850D8DC, sub_809117C, gUnknown_0850D8E8, 2, x) +field_object_path( 2, gUnknown_0850D8EC, sub_8091208, gUnknown_0850D8F8, 1, x) +field_object_path( 3, gUnknown_0850D8FC, sub_8091294, gUnknown_0850D908, 1, y) +field_object_path( 4, gUnknown_0850D90C, sub_8091320, gUnknown_0850D918, 2, y) +field_object_path( 5, gUnknown_0850D91C, sub_80913AC, gUnknown_0850D928, 2, x) +field_object_path( 6, gUnknown_0850D92C, sub_8091438, gUnknown_0850D938, 1, x) +field_object_path( 7, gUnknown_0850D93C, sub_80914C4, gUnknown_0850D710, 1, y) +field_object_path( 8, gUnknown_0850D948, sub_8091550, gUnknown_0850D954, 2, y) +field_object_path( 9, gUnknown_0850D958, sub_80915DC, gUnknown_0850D964, 2, y) +field_object_path(10, gUnknown_0850D968, sub_8091668, gUnknown_0850D974, 1, y) +field_object_path(11, gUnknown_0850D978, sub_80916F4, gUnknown_0850D984, 1, x) +field_object_path(12, gUnknown_0850D988, sub_8091780, gUnknown_0850D994, 2, x) +field_object_path(13, gUnknown_0850D998, sub_809180C, gUnknown_0850D9A4, 2, y) +field_object_path(14, gUnknown_0850D9A8, sub_8091898, gUnknown_0850D9B4, 1, y) +field_object_path(15, gUnknown_0850D9B8, sub_8091924, gUnknown_0850D9C4, 1, x) +field_object_path(16, gUnknown_0850D9C8, sub_80919B0, gUnknown_0850D9D4, 2, x) +field_object_path(17, gUnknown_0850D9D8, sub_8091A3C, gUnknown_0850D9E4, 2, y) +field_object_path(18, gUnknown_0850D9E8, sub_8091AC8, gUnknown_0850D9F4, 2, y) +field_object_path(19, gUnknown_0850D9F8, sub_8091B54, gUnknown_0850DA04, 2, x) +field_object_path(20, gUnknown_0850DA08, sub_8091BE0, gUnknown_0850DA14, 2, x) +field_object_path(21, gUnknown_0850DA18, sub_8091C6C, gUnknown_0850DA24, 2, y) +field_object_path(22, gUnknown_0850DA28, sub_8091CF8, gUnknown_0850DA34, 2, y) +field_object_path(23, gUnknown_0850DA38, sub_8091D84, gUnknown_0850DA44, 2, x) +field_object_path(24, gUnknown_0850DA48, sub_8091E10, gUnknown_0850DA54, 2, x) -- cgit v1.2.3 From ee3dc1edda08ae6e2bab34b8555ec410f1a930a9 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 09:43:49 -0400 Subject: Some more functions, including some swiss-cheesing that got out of hand --- src/field_map_obj.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 99d417ae2..77c2a8068 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -94,12 +94,21 @@ static bool8 FieldObjectDoesZCoordMatch(struct MapObject *, u8); /*static*/ struct MapObjectTemplate *FindFieldObjectTemplateInArrayByLocalId(u8 localId, struct MapObjectTemplate *templates, u8 count); void npc_reset(struct MapObject *, struct Sprite *); void FieldObjectSetRegularAnim(struct MapObject *, struct Sprite *, u8); -u8 GetFaceDirectionAnimId(u8); +u8 GetFaceDirectionAnimId(u32); bool8 FieldObjectExecRegularAnim(struct MapObject *, struct Sprite *); void SetFieldObjectStepTimer(struct Sprite *, s16); bool8 RunFieldObjectStepTimer(struct Sprite *); bool8 npc_block_way__next_tile(struct MapObject *, u8); u8 GetGoSpeed0AnimId(u8); +u32 state_to_direction(u8, u8, u8); +void DoGroundEffects_OnSpawn(struct MapObject *, struct Sprite *); +void sub_80964E8(struct MapObject *, struct Sprite *); +bool8 FieldObjectIsSpecialAnimActive(struct MapObject *); +void FieldObjectExecSpecialAnim(struct MapObject *, struct Sprite *); +void DoGroundEffects_OnBeginStep(struct MapObject *, struct Sprite *); +void DoGroundEffects_OnFinishStep(struct MapObject *, struct Sprite *); +void npc_obj_transfer_image_anim_pause_flag(struct MapObject *, struct Sprite *); +void FieldObjectUpdateSubpriority(struct MapObject *, struct Sprite *); // ROM data @@ -3147,3 +3156,115 @@ field_object_path(21, gUnknown_0850DA18, sub_8091C6C, gUnknown_0850DA24, 2, y) field_object_path(22, gUnknown_0850DA28, sub_8091CF8, gUnknown_0850DA34, 2, y) field_object_path(23, gUnknown_0850DA38, sub_8091D84, gUnknown_0850DA44, 2, x) field_object_path(24, gUnknown_0850DA48, sub_8091E10, gUnknown_0850DA54, 2, x) + +field_object_step(CopyPlayer1, gUnknown_0850DA58) + +bool8 mss_npc_reset_oampriv3_1_unk2_unk3(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + if (mapObject->mapobj_unk_21 == 0) + { + mapObject->mapobj_unk_21 = player_get_direction_lower_nybble(); + } + sprite->data1 = 1; + return TRUE; +} + +bool8 sub_8091EC0(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C == 0xFF || gPlayerAvatar.running1 == 2) + { + return FALSE; + } + return gUnknown_0850DA64[player_get_x22()](mapObject, sprite, player_get_direction_upper_nybble(), 0); +} + +bool8 sub_8091F20(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + mapObject->mapobj_bit_1 = FALSE; + sprite->data1 = 1; + } + return FALSE; +} + +bool8 sub_8091F48(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, u8 a3) +{ + return FALSE; +} + +bool8 sub_8091F4C(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, u8 a3) +{ + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(state_to_direction(gUnknown_085055CD[mapObject->animPattern], mapObject->mapobj_unk_21, playerDirection))); + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 2; + return TRUE; +} + +asm(".section .text.get_face_direction_anim_id"); + +void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); + +u8 FieldObjectCheckIfSpecialAnimFinishedOrInactive(struct MapObject *mapObject) +{ + if (mapObject->mapobj_bit_6) + { + return mapObject->mapobj_bit_7; + } + return 0x10; +} + +u8 FieldObjectClearAnimIfSpecialAnimFinished(struct MapObject *mapObject) +{ + u8 specialAnimState; + + specialAnimState = FieldObjectCheckIfSpecialAnimFinishedOrInactive(mapObject); + if (specialAnimState != 0 && specialAnimState != 16) + { + FieldObjectClearAnimIfSpecialAnimActive(mapObject); + } + return specialAnimState; +} + +u8 FieldObjectGetSpecialAnim(struct MapObject *mapObject) +{ + if (mapObject->mapobj_bit_6) + { + return mapObject->mapobj_unk_1C; + } + return 0xFF; +} + +void FieldObjectStep(struct MapObject *mapObject, struct Sprite *sprite, bool8 (*callback)(struct MapObject *, struct Sprite *)) +{ + DoGroundEffects_OnSpawn(mapObject, sprite); + sub_80964E8(mapObject, sprite); + if (FieldObjectIsSpecialAnimActive(mapObject)) + { + FieldObjectExecSpecialAnim(mapObject, sprite); + } + else if (!mapObject->mapobj_bit_8) + { + while (callback(mapObject, sprite)); + } + DoGroundEffects_OnBeginStep(mapObject, sprite); + DoGroundEffects_OnFinishStep(mapObject, sprite); + npc_obj_transfer_image_anim_pause_flag(mapObject, sprite); + sub_8096518(mapObject, sprite); + FieldObjectUpdateSubpriority(mapObject, sprite); +} + +u8 GetFaceDirectionAnimId(u32 direction) +{ + u8 dirn2; + u8 animIds[sizeof gUnknown_0850DBA0]; + + dirn2 = direction; + memcpy(animIds, gUnknown_0850DBA0, sizeof gUnknown_0850DBA0); + if (dirn2 > DIR_EAST) + { + dirn2 = 0; + } + return animIds[dirn2]; +} -- cgit v1.2.3 From 66fbc9753fa8411d715fdad1067eb98c68ace27a Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 13:54:33 -0400 Subject: sub_8091F94 --- src/field_map_obj.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 77c2a8068..cdf4006de 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -10,6 +10,7 @@ #include "berry.h" #include "palette.h" #include "field_player_avatar.h" +#include "fieldmap.h" #include "event_data.h" #include "rom_818CFC8.h" #include "rom_81BE66C.h" @@ -95,12 +96,12 @@ static bool8 FieldObjectDoesZCoordMatch(struct MapObject *, u8); void npc_reset(struct MapObject *, struct Sprite *); void FieldObjectSetRegularAnim(struct MapObject *, struct Sprite *, u8); u8 GetFaceDirectionAnimId(u32); +u8 GetGoSpeed0AnimId(u32); bool8 FieldObjectExecRegularAnim(struct MapObject *, struct Sprite *); void SetFieldObjectStepTimer(struct Sprite *, s16); bool8 RunFieldObjectStepTimer(struct Sprite *); bool8 npc_block_way__next_tile(struct MapObject *, u8); -u8 GetGoSpeed0AnimId(u8); -u32 state_to_direction(u8, u8, u8); +u32 state_to_direction(u8, u8, u32); void DoGroundEffects_OnSpawn(struct MapObject *, struct Sprite *); void sub_80964E8(struct MapObject *, struct Sprite *); bool8 FieldObjectIsSpecialAnimActive(struct MapObject *); @@ -3176,7 +3177,7 @@ bool8 sub_8091EC0(struct MapObject *mapObject, struct Sprite *sprite) { return FALSE; } - return gUnknown_0850DA64[player_get_x22()](mapObject, sprite, player_get_direction_upper_nybble(), 0); + return gUnknown_0850DA64[player_get_x22()](mapObject, sprite, player_get_direction_upper_nybble(), NULL); } bool8 sub_8091F20(struct MapObject *mapObject, struct Sprite *sprite) @@ -3189,12 +3190,12 @@ bool8 sub_8091F20(struct MapObject *mapObject, struct Sprite *sprite) return FALSE; } -bool8 sub_8091F48(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, u8 a3) +bool8 sub_8091F48(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8)) { return FALSE; } -bool8 sub_8091F4C(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, u8 a3) +bool8 sub_8091F4C(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8)) { FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(state_to_direction(gUnknown_085055CD[mapObject->animPattern], mapObject->mapobj_unk_21, playerDirection))); mapObject->mapobj_bit_1 = TRUE; @@ -3202,6 +3203,42 @@ bool8 sub_8091F4C(struct MapObject *mapObject, struct Sprite *sprite, u8 playerD return TRUE; } +bool8 sub_8091F94(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8)) +{ + u32 direction; + s16 x; + s16 y; + + direction = playerDirection; + if (FieldObjectIsFarawayIslandMew(mapObject)) + { + direction = sub_81D427C(); + if (direction == 0) + { + direction = playerDirection; + direction = state_to_direction(gUnknown_085055CD[mapObject->animPattern], mapObject->mapobj_unk_21, direction); + FieldObjectMoveDestCoords(mapObject, direction, &x, &y); + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction)); + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 2; + return TRUE; + } + } + else + { + direction = state_to_direction(gUnknown_085055CD[mapObject->animPattern], mapObject->mapobj_unk_21, direction); + } + FieldObjectMoveDestCoords(mapObject, direction, &x, &y); + FieldObjectSetRegularAnim(mapObject, sprite, GetGoSpeed0AnimId(direction)); + if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y)))) + { + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction)); + } + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 2; + return TRUE; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From c7f28f034c4a86b6373b45941f47e5a231392ad0 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 15:16:39 -0400 Subject: Change type of state_to_direction argument 1 to match pokeruby --- src/field_map_obj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index cdf4006de..cd330a18d 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -101,7 +101,7 @@ bool8 FieldObjectExecRegularAnim(struct MapObject *, struct Sprite *); void SetFieldObjectStepTimer(struct Sprite *, s16); bool8 RunFieldObjectStepTimer(struct Sprite *); bool8 npc_block_way__next_tile(struct MapObject *, u8); -u32 state_to_direction(u8, u8, u32); +u32 state_to_direction(u8, u32, u32); void DoGroundEffects_OnSpawn(struct MapObject *, struct Sprite *); void sub_80964E8(struct MapObject *, struct Sprite *); bool8 FieldObjectIsSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From c6bb13939e39bfae41ebaa8f1ea63295ddb050e1 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 16:10:55 -0400 Subject: state_to_direction memes --- src/field_map_obj.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 133 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index cd330a18d..42b18a1ac 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -95,8 +95,17 @@ static bool8 FieldObjectDoesZCoordMatch(struct MapObject *, u8); /*static*/ struct MapObjectTemplate *FindFieldObjectTemplateInArrayByLocalId(u8 localId, struct MapObjectTemplate *templates, u8 count); void npc_reset(struct MapObject *, struct Sprite *); void FieldObjectSetRegularAnim(struct MapObject *, struct Sprite *, u8); + u8 GetFaceDirectionAnimId(u32); u8 GetGoSpeed0AnimId(u32); +u8 GetGoSpeed1AnimId(u32); +u8 GetGoSpeed3AnimId(u32); +u8 sub_8093438(u32); +u8 sub_80934BC(u32); +u8 sub_8093514(u32); +u8 GetJumpLedgeAnimId(u32); +void sub_8092F88(u32, s16 *, s16 *, s16, s16); + bool8 FieldObjectExecRegularAnim(struct MapObject *, struct Sprite *); void SetFieldObjectStepTimer(struct Sprite *, s16); bool8 RunFieldObjectStepTimer(struct Sprite *); @@ -3239,6 +3248,115 @@ bool8 sub_8091F94(struct MapObject *mapObject, struct Sprite *sprite, u8 playerD return TRUE; } +bool8 sub_80920A4(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8)) +{ + u32 direction; + s16 x; + s16 y; + + direction = playerDirection; + direction = state_to_direction(gUnknown_085055CD[mapObject->animPattern], mapObject->mapobj_unk_21, direction); + FieldObjectMoveDestCoords(mapObject, direction, &x, &y); + FieldObjectSetRegularAnim(mapObject, sprite, GetGoSpeed1AnimId(direction)); + if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y)))) + { + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction)); + } + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_809215C(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8)) +{ + u32 direction; + s16 x; + s16 y; + + direction = playerDirection; + direction = state_to_direction(gUnknown_085055CD[mapObject->animPattern], mapObject->mapobj_unk_21, direction); + FieldObjectMoveDestCoords(mapObject, direction, &x, &y); + FieldObjectSetRegularAnim(mapObject, sprite, GetGoSpeed3AnimId(direction)); + if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y)))) + { + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction)); + } + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8092214(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8)) +{ + u32 direction; + s16 x; + s16 y; + + direction = playerDirection; + direction = state_to_direction(gUnknown_085055CD[mapObject->animPattern], mapObject->mapobj_unk_21, direction); + FieldObjectMoveDestCoords(mapObject, direction, &x, &y); + FieldObjectSetRegularAnim(mapObject, sprite, sub_8093438(direction)); + if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y)))) + { + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction)); + } + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 2; + return TRUE; +} + +bool8 cph_IM_DIFFERENT(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8)) +{ + u32 direction; + + direction = playerDirection; + direction = state_to_direction(gUnknown_085055CD[mapObject->animPattern], mapObject->mapobj_unk_21, direction); + FieldObjectSetRegularAnim(mapObject, sprite, sub_80934BC(direction)); + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 2; + return TRUE; +} + +bool8 sub_8092314(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8)) +{ + u32 direction; + s16 x; + s16 y; + + direction = playerDirection; + direction = state_to_direction(gUnknown_085055CD[mapObject->animPattern], mapObject->mapobj_unk_21, direction); + FieldObjectMoveDestCoords(mapObject, direction, &x, &y); + FieldObjectSetRegularAnim(mapObject, sprite, sub_8093514(direction)); + if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y)))) + { + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction)); + } + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 2; + return TRUE; +} + +bool8 oac_hopping(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8)) +{ + u32 direction; + s16 x; + s16 y; + + direction = playerDirection; + direction = state_to_direction(gUnknown_085055CD[mapObject->animPattern], mapObject->mapobj_unk_21, direction); + x = mapObject->coords2.x; + y = mapObject->coords2.y; + sub_8092F88(direction, &x, &y, 2, 2); + FieldObjectSetRegularAnim(mapObject, sprite, GetJumpLedgeAnimId(direction)); + if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y)))) + { + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction)); + } + mapObject->mapobj_bit_1 = TRUE; + sprite->data1 = 2; + return TRUE; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); @@ -3292,16 +3410,19 @@ void FieldObjectStep(struct MapObject *mapObject, struct Sprite *sprite, bool8 ( FieldObjectUpdateSubpriority(mapObject, sprite); } -u8 GetFaceDirectionAnimId(u32 direction) -{ - u8 dirn2; - u8 animIds[sizeof gUnknown_0850DBA0]; - - dirn2 = direction; - memcpy(animIds, gUnknown_0850DBA0, sizeof gUnknown_0850DBA0); - if (dirn2 > DIR_EAST) - { - dirn2 = 0; - } - return animIds[dirn2]; +#define dirn2anim(name, table) \ +extern const u8 table[5]; \ +u8 name(u32 direction) \ +{ \ + u8 dirn2; \ + u8 animIds[5]; \ + dirn2 = direction; \ + memcpy(animIds, table, 5); \ + if (dirn2 > DIR_EAST) \ + { \ + dirn2 = 0; \ + } \ + return animIds[dirn2]; \ } + +dirn2anim(GetFaceDirectionAnimId, gUnknown_0850DBA0); -- cgit v1.2.3 From 12885ca371f0b89d7df6decc133a14452ab567e0 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 16:40:00 -0400 Subject: CopyPlayer2 --- src/field_map_obj.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 42b18a1ac..c35105b44 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -17,6 +17,7 @@ #include "field_ground_effect.h" #include "map_obj_8097404.h" #include "mauville_old_man.h" +#include "metatile_behavior.h" #include "field_effect.h" #include "field_effect_helpers.h" #include "field_map_obj.h" @@ -3357,6 +3358,17 @@ bool8 oac_hopping(struct MapObject *mapObject, struct Sprite *sprite, u8 playerD return TRUE; } +field_object_step(CopyPlayer2, gUnknown_0850DA90) + +bool8 mss_08062EA4(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C == 0xFF || gPlayerAvatar.running1 == 2) + { + return FALSE; + } + return gUnknown_0850DA64[player_get_x22()](mapObject, sprite, player_get_direction_upper_nybble(), sub_8088E64); +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 6247fe742c095885fa0938d8e91ee222e25a6354 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 16:53:55 -0400 Subject: Tree and Mountain Disguise FOCB --- src/field_map_obj.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index c35105b44..7b62e6d05 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3369,6 +3369,44 @@ bool8 mss_08062EA4(struct MapObject *mapObject, struct Sprite *sprite) return gUnknown_0850DA64[player_get_x22()](mapObject, sprite, player_get_direction_upper_nybble(), sub_8088E64); } +bool8 sub_80925AC(struct MapObject *, struct Sprite *); + +void FieldObjectCB_TreeDisguise(struct Sprite *sprite) +{ + struct MapObject *mapObject; + + mapObject = &gMapObjects[sprite->data0]; + if (mapObject->mapobj_unk_21 == 0 || (mapObject->mapobj_unk_21 == 1 && !sprite->data7)) + { + FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectSpawnParams[0], (u8 *)&gFieldEffectSpawnParams[1], (u8 *)&gFieldEffectSpawnParams[2]); + mapObject->mapobj_unk_1A = FieldEffectStart(FLDEFF_TREE_DISGUISE); + mapObject->mapobj_unk_21 = 1; + sprite->data7 ++; + } + FieldObjectStep(&gMapObjects[sprite->data0], sprite, sub_80925AC); +} + +bool8 sub_80925AC(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + return FALSE; +} + +void FieldObjectCB_MountainDisguise(struct Sprite *sprite) +{ + struct MapObject *mapObject; + + mapObject = &gMapObjects[sprite->data0]; + if (mapObject->mapobj_unk_21 == 0 || (mapObject->mapobj_unk_21 == 1 && !sprite->data7)) + { + FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectSpawnParams[0], (u8 *)&gFieldEffectSpawnParams[1], (u8 *)&gFieldEffectSpawnParams[2]); + mapObject->mapobj_unk_1A = FieldEffectStart(FLDEFF_MOUNTAIN_DISGUISE); + mapObject->mapobj_unk_21 = 1; + sprite->data7 ++; + } + FieldObjectStep(&gMapObjects[sprite->data0], sprite, sub_80925AC); +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 15aba9a07633092ad340a5f11df962e2aaf6703d Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 17:24:26 -0400 Subject: Hidden1 --- src/field_map_obj.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 7b62e6d05..80c376a2f 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3407,6 +3407,40 @@ void FieldObjectCB_MountainDisguise(struct Sprite *sprite) FieldObjectStep(&gMapObjects[sprite->data0], sprite, sub_80925AC); } +extern bool8 (*const gUnknown_0850DA9C[])(struct MapObject *, struct Sprite *); +bool8 sub_809268C(struct MapObject *, struct Sprite *); + +void FieldObjectCB_Hidden1(struct Sprite *sprite) +{ + if (!sprite->data7) + { + gMapObjects[sprite->data0].mapobj_bit_26 = TRUE; + sprite->subspriteMode = 2; + sprite->oam.priority = 3; + sprite->data7 ++; + } + FieldObjectStep(&gMapObjects[sprite->data0], sprite, sub_809268C); +} + +bool8 sub_809268C(struct MapObject *mapObject, struct Sprite *sprite) +{ + return gUnknown_0850DA9C[sprite->data1](mapObject, sprite); +} + +bool8 sub_80926AC (struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + return FALSE; +} +bool8 sub_80926B8 (struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + sprite->data1 = 0; + } + return FALSE; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 34950dbd13f9ec9e4616b3cb33a9b1aae912eee2 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 17:34:41 -0400 Subject: remaining field object step callbacks --- src/field_map_obj.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 80c376a2f..5d5747be9 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3441,6 +3441,72 @@ bool8 sub_80926B8 (struct MapObject *mapObject, struct Sprite *sprite) return FALSE; } +field_object_step(WalkInPlace1, gUnknown_0850DAA0) + +bool8 sub_8092718(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + FieldObjectSetRegularAnim(mapObject, sprite, GetStepInPlaceDelay16AnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 1; + return TRUE; +} + +field_object_step(WalkInPlace4, gUnknown_0850DAA8) + +bool8 sub_8092788(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + FieldObjectSetRegularAnim(mapObject, sprite, GetStepInPlaceDelay32AnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 1; + return TRUE; +} + +field_object_step(WalkInPlace2, gUnknown_0850DAB0) + +bool8 sub_80927F8(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + FieldObjectSetRegularAnim(mapObject, sprite, GetStepInPlaceDelay8AnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 1; + return TRUE; +} + +field_object_step(WalkInPlace3, gUnknown_0850DAB8) + +bool8 sub_8092868(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + FieldObjectSetRegularAnim(mapObject, sprite, GetStepInPlaceDelay4AnimId(mapObject->mapobj_unk_18)); + sprite->data1 = 1; + return TRUE; +} + +field_object_step(Hidden2, gUnknown_0850DAC0) + +bool8 sub_80928D8(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_reset(mapObject, sprite); + FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18)); + mapObject->mapobj_bit_13 = TRUE; + sprite->data1 = 1; + return TRUE; +} +bool8 sub_809290C(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (FieldObjectExecRegularAnim(mapObject, sprite)) + { + sprite->data1 = 2; + return TRUE; + } + return FALSE; +} + +bool8 sub_809292C(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_1 = FALSE; + return FALSE; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From fa436fca4dd0878eb1fdd905dec48e8c2cd310d2 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 17:41:46 -0400 Subject: a block of direction-based anim num fns --- src/field_map_obj.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 5d5747be9..8bb20abb4 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3507,6 +3507,38 @@ bool8 sub_809292C(struct MapObject *mapObject, struct Sprite *sprite) return FALSE; } +void npc_reset(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_1 = FALSE; + mapObject->mapobj_bit_6 = FALSE; + mapObject->mapobj_bit_7 = FALSE; + mapObject->mapobj_unk_1C = 0xFF; + sprite->data1 = 0; +} + +#define dirn2anim(name, table)\ +extern const u8 table[4];\ +u8 name(u8 direction)\ +{\ + return table[direction];\ +} + +dirn2anim(FieldObjectDirectionToImageAnimId, gUnknown_0850DACC) +dirn2anim(get_go_image_anim_num, gUnknown_0850DAD5) +dirn2anim(get_go_fast_image_anim_num, gUnknown_0850DADE) +dirn2anim(get_go_faster_image_anim_num, gUnknown_0850DAE7) +dirn2anim(get_go_fastest_image_anim_num, gUnknown_0850DAF0) +dirn2anim(sub_80929AC, gUnknown_0850DAF9) +dirn2anim(sub_80929BC, gUnknown_0850DB02) +dirn2anim(sub_80929CC, gUnknown_0850DB0B) +dirn2anim(sub_80929DC, gUnknown_0850DB14) +dirn2anim(sub_80929EC, gUnknown_0850DB1D) +dirn2anim(sub_80929FC, gUnknown_0850DB26) +dirn2anim(sub_8092A0C, gUnknown_0850DB2F) +dirn2anim(sub_8092A1C, gUnknown_0850DB38) +dirn2anim(sub_8092A2C, gUnknown_0850DB41) +dirn2anim(get_run_image_anim_num, gUnknown_0850DB4A) + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); @@ -3560,7 +3592,7 @@ void FieldObjectStep(struct MapObject *mapObject, struct Sprite *sprite, bool8 ( FieldObjectUpdateSubpriority(mapObject, sprite); } -#define dirn2anim(name, table) \ +#define dirn2anim_2(name, table) \ extern const u8 table[5]; \ u8 name(u32 direction) \ { \ @@ -3575,4 +3607,4 @@ u8 name(u32 direction) \ return animIds[dirn2]; \ } -dirn2anim(GetFaceDirectionAnimId, gUnknown_0850DBA0); +dirn2anim_2(GetFaceDirectionAnimId, gUnknown_0850DBA0); -- cgit v1.2.3 From 119c0e96b58b33c0b72ad2a209b42e7aa93cdf19 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 18:04:26 -0400 Subject: sub_8092A4C --- src/field_map_obj.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 8bb20abb4..7caa6d03d 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3539,6 +3539,27 @@ dirn2anim(sub_8092A1C, gUnknown_0850DB38) dirn2anim(sub_8092A2C, gUnknown_0850DB41) dirn2anim(get_run_image_anim_num, gUnknown_0850DB4A) +struct UnkStruct_085094AC { + const union AnimCmd **unk00; + u8 unk04[4]; +}; + +extern const struct UnkStruct_085094AC gUnknown_085094AC[]; + +const struct UnkStruct_085094AC *sub_8092A4C(const union AnimCmd **a0) +{ + const struct UnkStruct_085094AC *retval; + + for (retval = gUnknown_085094AC; retval->unk00 != NULL; retval ++) + { + if (retval->unk00 == a0) + { + return retval; + } + } + return NULL; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 589c34e30aa30236b13b7f6621808aca581675c3 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 18:18:34 -0400 Subject: obj_npc_animation_step, npc_apply_anim_looping --- src/field_map_obj.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 7caa6d03d..f47639a9e 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3540,19 +3540,19 @@ dirn2anim(sub_8092A2C, gUnknown_0850DB41) dirn2anim(get_run_image_anim_num, gUnknown_0850DB4A) struct UnkStruct_085094AC { - const union AnimCmd **unk00; - u8 unk04[4]; + const union AnimCmd *const *anims; + u8 animPos[4]; }; extern const struct UnkStruct_085094AC gUnknown_085094AC[]; -const struct UnkStruct_085094AC *sub_8092A4C(const union AnimCmd **a0) +static const struct UnkStruct_085094AC *sub_8092A4C(const union AnimCmd *const *anims) { const struct UnkStruct_085094AC *retval; - for (retval = gUnknown_085094AC; retval->unk00 != NULL; retval ++) + for (retval = gUnknown_085094AC; retval->anims != NULL; retval ++) { - if (retval->unk00 == a0) + if (retval->anims == anims) { return retval; } @@ -3560,6 +3560,51 @@ const struct UnkStruct_085094AC *sub_8092A4C(const union AnimCmd **a0) return NULL; } +void npc_apply_anim_looping(struct MapObject *mapObject, struct Sprite *sprite, u8 animNum) +{ + const struct UnkStruct_085094AC *unk85094AC; + + if (!mapObject->mapobj_bit_12) + { + sprite->animNum = animNum; + unk85094AC = sub_8092A4C(sprite->anims); + if (unk85094AC != NULL) + { + if (sprite->animCmdIndex == unk85094AC->animPos[0]) + { + sprite->animCmdIndex = unk85094AC->animPos[3]; + } + else if (sprite->animCmdIndex == unk85094AC->animPos[1]) + { + sprite->animCmdIndex = unk85094AC->animPos[2]; + } + } + SeekSpriteAnim(sprite, sprite->animCmdIndex); + } +} + +void obj_npc_animation_step(struct MapObject *mapObject, struct Sprite *sprite, u8 animNum) +{ + const struct UnkStruct_085094AC *unk85094AC; + + if (!mapObject->mapobj_bit_12) + { + u8 animPos; + + sprite->animNum = animNum; + unk85094AC = sub_8092A4C(sprite->anims); + if (unk85094AC != NULL) + { + animPos = unk85094AC->animPos[1]; + if (sprite->animCmdIndex <= unk85094AC->animPos[0]) + { + animPos = unk85094AC->animPos[0]; + } + SeekSpriteAnim(sprite, animPos); + } + } +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From edd5c81a8ee249625dbd015c80e0e0442776bde9 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 18:24:58 -0400 Subject: sub_8092AF8 --- src/field_map_obj.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index f47639a9e..2987c09ee 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3539,6 +3539,8 @@ dirn2anim(sub_8092A1C, gUnknown_0850DB38) dirn2anim(sub_8092A2C, gUnknown_0850DB41) dirn2anim(get_run_image_anim_num, gUnknown_0850DB4A) +// file boundary? + struct UnkStruct_085094AC { const union AnimCmd *const *anims; u8 animPos[4]; @@ -3605,6 +3607,25 @@ void obj_npc_animation_step(struct MapObject *mapObject, struct Sprite *sprite, } } +// file boundary? + +u8 sub_8092AF8(s16 x1, s16 y1, s16 x2, s16 y2) +{ + if (x1 > x2) + { + return DIR_WEST; + } + if (x1 < x2) + { + return DIR_EAST; + } + if (y1 > y2) + { + return DIR_NORTH; + } + return DIR_SOUTH; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From ca88036ebe4441a2afc7267da1fda2a4b68820a8 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 18:29:14 -0400 Subject: npc_set_running_behaviour_etc --- src/field_map_obj.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 2987c09ee..06fd36be3 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3626,6 +3626,15 @@ u8 sub_8092AF8(s16 x1, s16 y1, s16 x2, s16 y2) return DIR_SOUTH; } +void npc_set_running_behaviour_etc(struct MapObject *mapObject, u8 animPattern) +{ + mapObject->animPattern = animPattern; + mapObject->mapobj_unk_21 = 0; + mapObject->animId = 0; + gSprites[mapObject->spriteId].callback = gUnknown_08505438[animPattern]; + gSprites[mapObject->spriteId].data1 = 0; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 5812bc4ebe83bb80294bbb40846ae6fb1c76e5bf Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 18:33:38 -0400 Subject: npc_block_way__next_tile --- src/field_map_obj.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 06fd36be3..93baccf36 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3635,6 +3635,19 @@ void npc_set_running_behaviour_etc(struct MapObject *mapObject, u8 animPattern) gSprites[mapObject->spriteId].data1 = 0; } +dirn2anim(npc_running_behaviour_by_direction, gUnknown_0850DB53) + +bool8 npc_block_way__next_tile(struct MapObject *mapObject, u8 direction) +{ + s16 x; + s16 y; + + x = mapObject->coords2.x; + y = mapObject->coords2.y; + MoveCoords(direction, &x, &y); + return npc_block_way(mapObject, x, y, direction); +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From fedbcd7bb7202f37f4a3a017a2f4c1fe296a6ae3 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 18:42:35 -0400 Subject: npc_block_way --- src/field_map_obj.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 93baccf36..5ec5e68f4 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -121,6 +121,10 @@ void DoGroundEffects_OnFinishStep(struct MapObject *, struct Sprite *); void npc_obj_transfer_image_anim_pause_flag(struct MapObject *, struct Sprite *); void FieldObjectUpdateSubpriority(struct MapObject *, struct Sprite *); +bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject *fieldObject, s16 x, s16 y); +bool8 IsMetatileDirectionallyImpassable(struct MapObject *, s16, s16, u8); +bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *, s16, s16); + // ROM data void (*const gUnknown_08505438[NUM_FIELD_MAP_OBJECT_TEMPLATES])(struct Sprite *); @@ -3637,7 +3641,7 @@ void npc_set_running_behaviour_etc(struct MapObject *mapObject, u8 animPattern) dirn2anim(npc_running_behaviour_by_direction, gUnknown_0850DB53) -bool8 npc_block_way__next_tile(struct MapObject *mapObject, u8 direction) +u8 npc_block_way__next_tile(struct MapObject *mapObject, u8 direction) { s16 x; s16 y; @@ -3648,6 +3652,24 @@ bool8 npc_block_way__next_tile(struct MapObject *mapObject, u8 direction) return npc_block_way(mapObject, x, y, direction); } +u8 npc_block_way(struct MapObject *mapObject, s16 x, s16 y, u32 dirn) +{ + u8 direction; + + direction = dirn; + if (IsCoordOutsideFieldObjectMovementRect(mapObject, x, y)) + return 1; + else if (MapGridIsImpassableAt(x, y) || GetMapBorderIdAt(x, y) == -1 || IsMetatileDirectionallyImpassable(mapObject, x, y, direction)) + return 2; + else if (mapObject->mapobj_bit_15 && !CanCameraMoveInDirection(direction)) + return 2; + else if (IsZCoordMismatchAt(mapObject->mapobj_unk_0B_0, x, y)) + return 3; + else if (CheckForCollisionBetweenFieldObjects(mapObject, x, y)) + return 4; + return 0; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 7d58ce75ad421762f9820492d77b6b05c632f60b Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 18:52:20 -0400 Subject: sub_8092C8C --- src/field_map_obj.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 5ec5e68f4..a876797a4 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3658,18 +3658,52 @@ u8 npc_block_way(struct MapObject *mapObject, s16 x, s16 y, u32 dirn) direction = dirn; if (IsCoordOutsideFieldObjectMovementRect(mapObject, x, y)) + { return 1; - else if (MapGridIsImpassableAt(x, y) || GetMapBorderIdAt(x, y) == -1 || IsMetatileDirectionallyImpassable(mapObject, x, y, direction)) + } + if (MapGridIsImpassableAt(x, y) || GetMapBorderIdAt(x, y) == -1 || IsMetatileDirectionallyImpassable(mapObject, x, y, direction)) + { return 2; - else if (mapObject->mapobj_bit_15 && !CanCameraMoveInDirection(direction)) + } + if (mapObject->mapobj_bit_15 && !CanCameraMoveInDirection(direction)) + { return 2; - else if (IsZCoordMismatchAt(mapObject->mapobj_unk_0B_0, x, y)) + } + if (IsZCoordMismatchAt(mapObject->mapobj_unk_0B_0, x, y)) + { return 3; - else if (CheckForCollisionBetweenFieldObjects(mapObject, x, y)) + } + if (CheckForCollisionBetweenFieldObjects(mapObject, x, y)) + { return 4; + } return 0; } +u8 sub_8092C8C(struct MapObject *mapObject, s16 x, s16 y, u8 direction) +{ + u8 retval; + + retval = 0x00; + if (IsCoordOutsideFieldObjectMovementRect(mapObject, x, y)) + { + retval |= 1; + } + if (MapGridIsImpassableAt(x, y) || GetMapBorderIdAt(x, y) == -1 || IsMetatileDirectionallyImpassable(mapObject, x, y, direction) || (mapObject->mapobj_bit_15 && !CanCameraMoveInDirection(direction))) + { + retval |= 2; + } + if (IsZCoordMismatchAt(mapObject->mapobj_unk_0B_0, x, y)) + { + retval |= 4; + } + if (CheckForCollisionBetweenFieldObjects(mapObject, x, y)) + { + retval |= 8; + } + return retval; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 3e472ccc8b9231d3b447fdfdb706a3da5773546b Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 21:04:52 -0400 Subject: IsCoordOutsideFieldObjectMovementRect --- src/field_map_obj.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index a876797a4..cc81bcb29 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -121,7 +121,7 @@ void DoGroundEffects_OnFinishStep(struct MapObject *, struct Sprite *); void npc_obj_transfer_image_anim_pause_flag(struct MapObject *, struct Sprite *); void FieldObjectUpdateSubpriority(struct MapObject *, struct Sprite *); -bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject *fieldObject, s16 x, s16 y); +bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *fieldObject, s16 x, s16 y); bool8 IsMetatileDirectionallyImpassable(struct MapObject *, s16, s16, u8); bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *, s16, s16); @@ -3657,7 +3657,7 @@ u8 npc_block_way(struct MapObject *mapObject, s16 x, s16 y, u32 dirn) u8 direction; direction = dirn; - if (IsCoordOutsideFieldObjectMovementRect(mapObject, x, y)) + if (IsCoordOutsideFieldObjectMovementRect((struct MapObject2 *)mapObject, x, y)) { return 1; } @@ -3685,7 +3685,7 @@ u8 sub_8092C8C(struct MapObject *mapObject, s16 x, s16 y, u8 direction) u8 retval; retval = 0x00; - if (IsCoordOutsideFieldObjectMovementRect(mapObject, x, y)) + if (IsCoordOutsideFieldObjectMovementRect((struct MapObject2 *)mapObject, x, y)) { retval |= 1; } @@ -3704,6 +3704,34 @@ u8 sub_8092C8C(struct MapObject *mapObject, s16 x, s16 y, u8 direction) return retval; } +bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *mapObject, s16 x, s16 y) +{ + s16 left; + s16 right; + s16 top; + s16 bottom; + + if (mapObject->mapobj_unk_19 != 0) + { + left = mapObject->coords1.x - mapObject->mapobj_unk_19; + right = mapObject->coords1.x + mapObject->mapobj_unk_19; + if (left > x || right < x) + { + return TRUE; + } + } + if (mapObject->mapobj_unk_19b != 0) + { + top = mapObject->coords1.y - mapObject->mapobj_unk_19b; + bottom = mapObject->coords1.y + mapObject->mapobj_unk_19b; + if (top > y || bottom < y) + { + return TRUE; + } + } + return FALSE; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From c98299386077d8a0c34150405ab0458f52fc2015 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 21:08:44 -0400 Subject: IsMetatileDirectionallyImpassable --- src/field_map_obj.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index cc81bcb29..74c71333c 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3732,6 +3732,15 @@ bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *mapObject, s16 x, return FALSE; } +bool8 IsMetatileDirectionallyImpassable(struct MapObject *mapObject, s16 x, s16 y, u8 direction) +{ + if (gUnknown_0850DB5C[direction - 1](mapObject->mapobj_unk_1E) || gUnknown_0850DB6C[direction - 1](MapGridGetMetatileBehaviorAt(x, y))) + { + return TRUE; + } + return FALSE; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 951acc8c31029327775e90e21ba6c92c24ff8b3b Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 21:29:04 -0400 Subject: CheckForCollisionBetweenFieldObjects --- src/field_map_obj.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 74c71333c..9855321d3 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3741,6 +3741,28 @@ bool8 IsMetatileDirectionallyImpassable(struct MapObject *mapObject, s16 x, s16 return FALSE; } +bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *mapObject, s16 x, s16 y) +{ + u8 i; + struct MapObject *curObject; + + for (i = 0; i < NUM_FIELD_OBJECTS; i ++) + { + curObject = &gMapObjects[i]; + if (curObject->active && curObject != mapObject) + { + if ((curObject->coords2.x == x && curObject->coords2.y == y) || (curObject->coords3.x == x && curObject->coords3.y == y)) + { + if (AreZCoordsCompatible(mapObject->mapobj_unk_0B_0, curObject->mapobj_unk_0B_0)) + { + return TRUE; + } + } + } + } + return FALSE; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 996d9f4b4204396395e67e33a61ffd7111117fc2 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 21:31:37 -0400 Subject: sub_8092E9C --- src/field_map_obj.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 9855321d3..954088edc 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3763,6 +3763,17 @@ bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *mapObject, s16 x, s return FALSE; } +bool8 sub_8092E9C(u8 localId, u8 mapNum, u8 mapGroup) +{ + u8 mapObjectId; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId) && gSprites[gMapObjects[mapObjectId].spriteId].data7 & 0x02) + { + return TRUE; + } + return FALSE; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From f03c0dc3b4f763c65fefaa8cdf10a06b2fd00dc2 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 21:39:29 -0400 Subject: MoveCoords --- src/field_map_obj.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 954088edc..56281a10d 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3774,6 +3774,22 @@ bool8 sub_8092E9C(u8 localId, u8 mapNum, u8 mapGroup) return FALSE; } +void sub_8092EF0(u8 localId, u8 mapNum, u8 mapGroup) +{ + u8 mapObjectId; + + if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId)) + { + gSprites[gMapObjects[mapObjectId].spriteId].data7 |= 0x04; + } +} + +void MoveCoords(u8 direction, s16 *x, s16 *y) +{ + *x += gUnknown_0850DB7C[direction].x; + *y += gUnknown_0850DB7C[direction].y; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 76b68e039dc6cebee6da0f421be630f96ff75d2d Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 21:45:18 -0400 Subject: MoveCoordsPixel --- src/field_map_obj.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 56281a10d..d52bd86f7 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3790,6 +3790,12 @@ void MoveCoords(u8 direction, s16 *x, s16 *y) *y += gUnknown_0850DB7C[direction].y; } +void sub_8092F60(u8 direction, s16 *x, s16 *y) +{ + *x += gUnknown_0850DB7C[direction].x << 4; + *y += gUnknown_0850DB7C[direction].y << 4; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From bd48354207282b2948a2198fec35ae36aaa89f7a Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 21:52:55 -0400 Subject: sub_8092F88 --- src/field_map_obj.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index d52bd86f7..4592c4dfe 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3796,6 +3796,37 @@ void sub_8092F60(u8 direction, s16 *x, s16 *y) *y += gUnknown_0850DB7C[direction].y << 4; } +void sub_8092F88(u32 dirn, s16 *x, s16 *y, s16 dx, s16 dy) +{ + u8 direction; + s16 dx_2; + s16 dy_2; + s16 cur_x; + s16 cur_y; + + direction = dirn; + dx_2 = dx; + dy_2 = dy; + cur_x = gUnknown_0850DB7C[direction].x; + if (cur_x > 0) + { + *x += dx_2; + } + if (cur_x < 0) + { + *x -= dx_2; + } + cur_y = gUnknown_0850DB7C[direction].y; + if (cur_y > 0) + { + *y += dy_2; + } + if (cur_y < 0) + { + *y -= dy_2; + } +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 3f2c6556cb25c178b29b016dd87bb706a7fb631c Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 21:59:14 -0400 Subject: sub_8092FF0 --- src/field_map_obj.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 4592c4dfe..b8be79d73 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -20,6 +20,7 @@ #include "metatile_behavior.h" #include "field_effect.h" #include "field_effect_helpers.h" +#include "field_camera.h" #include "field_map_obj.h" #define NUM_FIELD_MAP_OBJECT_TEMPLATES 0x51 @@ -3827,6 +3828,14 @@ void sub_8092F88(u32 dirn, s16 *x, s16 *y, s16 dx, s16 dy) } } +void sub_8092FF0(s16 x, s16 y, s16 *dest_x, s16 *dest_y) +{ + *dest_x = (x - gSaveBlock1Ptr->pos.x) << 4; + *dest_y = (y - gSaveBlock1Ptr->pos.y) << 4; + *dest_x -= gUnknown_03005DEC; + *dest_y -= gUnknown_03005DE8; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 44e590add0b4f630397b9f9e206a9a66d1a41ccc Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 22:15:54 -0400 Subject: sub_8093038 --- src/field_map_obj.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index b8be79d73..d4793b0a7 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3836,6 +3836,33 @@ void sub_8092FF0(s16 x, s16 y, s16 *dest_x, s16 *dest_y) *dest_y -= gUnknown_03005DE8; } +void sub_8093038(s16 x, s16 y, s16 *dest_x, s16 *dest_y) +{ + s16 dx; + s16 dy; + + dx = -gUnknown_03005DEC - gUnknown_03005DD0.x; + dy = -gUnknown_03005DE8 - gUnknown_03005DD0.y; + if (gUnknown_03005DD0.x > 0) + { + dx += 0x10; + } + if (gUnknown_03005DD0.x < 0) + { + dx -= 0x10; + } + if (gUnknown_03005DD0.y > 0) + { + dy += 0x10; + } + if (gUnknown_03005DD0.y < 0) + { + dy -= 0x10; + } + *dest_x = ((x - gSaveBlock1Ptr->pos.x) << 4) + dx; + *dest_y = ((y - gSaveBlock1Ptr->pos.y) << 4) + dy; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 812ad017e892ff3d93b3df8310335287a556e871 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 22:19:23 -0400 Subject: sub_80930E0 --- src/field_map_obj.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index d4793b0a7..eb9ed2129 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3863,6 +3863,13 @@ void sub_8093038(s16 x, s16 y, s16 *dest_x, s16 *dest_y) *dest_y = ((y - gSaveBlock1Ptr->pos.y) << 4) + dy; } +void sub_80930E0(s16 *x, s16 *y, s16 dx, s16 dy) +{ + sub_8093038(*x, *y, x, y); + *x += dx; + *y += dy; +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From eb41c57ecdd008de76b2aa0ad4849a27ea222007 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 22:23:48 -0400 Subject: GetFieldObjectMovingCameraOffset --- src/field_map_obj.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index eb9ed2129..de72478cf 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3870,6 +3870,28 @@ void sub_80930E0(s16 *x, s16 *y, s16 dx, s16 dy) *y += dy; } +void GetFieldObjectMovingCameraOffset(s16 *x, s16 *y) +{ + *x = 0; + *y = 0; + if (gUnknown_03005DD0.x > 0) + { + (*x) ++; + } + if (gUnknown_03005DD0.x < 0) + { + (*x) --; + } + if (gUnknown_03005DD0.y > 0) + { + (*y) ++; + } + if (gUnknown_03005DD0.y < 0) + { + (*y) --; + } +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From 64d3a67b0c1750d4ff6f1011b62c0525c335f88e Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 22:27:04 -0400 Subject: FieldObjectMoveDestCoords --- src/field_map_obj.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index de72478cf..fd03082fb 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3892,6 +3892,16 @@ void GetFieldObjectMovingCameraOffset(s16 *x, s16 *y) } } +void FieldObjectMoveDestCoords(struct MapObject *mapObject, u32 dirn, s16 *x, s16 *y) +{ + u8 direction; + + direction = dirn; + *x = mapObject->coords2.x; + *y = mapObject->coords2.y; + MoveCoords(direction, x, y); +} + asm(".section .text.get_face_direction_anim_id"); void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -- cgit v1.2.3 From eb7e52d2a89d0d491722bcccaf28bfd7709bf371 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 22:44:47 -0400 Subject: Deswiss the cheese --- src/field_map_obj.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index fd03082fb..2fd6f57e5 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -125,6 +125,8 @@ void FieldObjectUpdateSubpriority(struct MapObject *, struct Sprite *); bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *fieldObject, s16 x, s16 y); bool8 IsMetatileDirectionallyImpassable(struct MapObject *, s16, s16, u8); bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *, s16, s16); +void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); +void FieldObjectClearAnim(struct MapObject *); // ROM data @@ -3902,9 +3904,62 @@ void FieldObjectMoveDestCoords(struct MapObject *mapObject, u32 dirn, s16 *x, s1 MoveCoords(direction, x, y); } -asm(".section .text.get_face_direction_anim_id"); +// file boundary? -void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); +bool8 FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(struct MapObject *mapObject) +{ + if (mapObject->mapobj_bit_1 || mapObject->mapobj_bit_6) + { + return TRUE; + } + return FALSE; +} + +bool8 FieldObjectIsSpecialAnimActive(struct MapObject *mapObject) +{ + if (mapObject->mapobj_bit_6 && mapObject->mapobj_unk_1C != 0xFF) + { + return TRUE; + } + return FALSE; +} + +bool8 FieldObjectSetSpecialAnim(struct MapObject *mapObject, u8 specialAnimId) +{ + if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject)) + { + return TRUE; + } + npc_sync_anim_pause_bits(mapObject); + mapObject->mapobj_unk_1C = specialAnimId; + mapObject->mapobj_bit_6 = TRUE; + mapObject->mapobj_bit_7 = FALSE; + gSprites[mapObject->spriteId].data2 = 0; + return FALSE; +} + +void FieldObjectForceSetSpecialAnim(struct MapObject *mapObject, u8 specialAnimId) +{ + FieldObjectClearAnimIfSpecialAnimActive(mapObject); + FieldObjectSetSpecialAnim(mapObject, specialAnimId); +} + +void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *mapObject) +{ + if (mapObject->mapobj_bit_6) + { + FieldObjectClearAnim(mapObject); + } +} + +void FieldObjectClearAnim(struct MapObject *mapObject) +{ + mapObject->mapobj_unk_1C = 0xFF; + mapObject->mapobj_bit_6 = FALSE; + mapObject->mapobj_bit_7 = FALSE; + gSprites[mapObject->spriteId].data1 = 0; + gSprites[mapObject->spriteId].data2 = 0; +} u8 FieldObjectCheckIfSpecialAnimFinishedOrInactive(struct MapObject *mapObject) { -- cgit v1.2.3 From d1666473d3a45b5407d5ca3514185d965394e0ed Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 22:48:19 -0400 Subject: Another block of functions for getting anim IDs from directions --- src/field_map_obj.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 2fd6f57e5..a1eccc9cb 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4026,3 +4026,19 @@ u8 name(u32 direction) \ } dirn2anim_2(GetFaceDirectionAnimId, gUnknown_0850DBA0); +dirn2anim_2(GetSimpleGoAnimId, gUnknown_0850DBA5); +dirn2anim_2(GetGoSpeed0AnimId, gUnknown_0850DBAA); +dirn2anim_2(GetGoSpeed1AnimId, gUnknown_0850DBAF); +dirn2anim_2(GetGoSpeed2AnimId, gUnknown_0850DBB4); +dirn2anim_2(GetGoSpeed3AnimId, gUnknown_0850DBB9); +dirn2anim_2(sub_8093438, gUnknown_0850DBBE); +dirn2anim_2(GetRunAnimId, gUnknown_0850DBC3); +dirn2anim_2(GetJumpLedgeAnimId, gUnknown_0850DBC8); +dirn2anim_2(sub_80934BC, gUnknown_0850DBCD); +dirn2anim_2(sub_80934E8, gUnknown_0850DBD2); +dirn2anim_2(sub_8093514, gUnknown_0850DBD7); +dirn2anim_2(sub_8093540, gUnknown_0850DBDC); +dirn2anim_2(GetStepInPlaceDelay32AnimId, gUnknown_0850DBE1); +dirn2anim_2(GetStepInPlaceDelay16AnimId, gUnknown_0850DBE6); +dirn2anim_2(GetStepInPlaceDelay8AnimId, gUnknown_0850DBEB); +dirn2anim_2(GetStepInPlaceDelay4AnimId, gUnknown_0850DBF0); -- cgit v1.2.3 From 08cb777fd788fd7cfc44d0d41d7b2ba697a4ed9e Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 22:54:15 -0400 Subject: FieldObjectFaceOppositeDirection --- src/field_map_obj.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index a1eccc9cb..6e2512000 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4042,3 +4042,8 @@ dirn2anim_2(GetStepInPlaceDelay32AnimId, gUnknown_0850DBE1); dirn2anim_2(GetStepInPlaceDelay16AnimId, gUnknown_0850DBE6); dirn2anim_2(GetStepInPlaceDelay8AnimId, gUnknown_0850DBEB); dirn2anim_2(GetStepInPlaceDelay4AnimId, gUnknown_0850DBF0); + +bool8 FieldObjectFaceOppositeDirection(struct MapObject *mapObject, u8 direction) +{ + return FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(GetOppositeDirection(direction))); +} -- cgit v1.2.3 From 95142069690b3d2ef30d759f99c0b3710eeab26a Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 22:58:17 -0400 Subject: Another block of functions for getting anim ids given direction --- src/field_map_obj.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 6e2512000..d0673fdbe 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4047,3 +4047,14 @@ bool8 FieldObjectFaceOppositeDirection(struct MapObject *mapObject, u8 direction { return FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(GetOppositeDirection(direction))); } + +dirn2anim_2(sub_8093648, gUnknown_0850DBF5); +dirn2anim_2(sub_8093674, gUnknown_0850DBFA); +dirn2anim_2(sub_80936A0, gUnknown_0850DBFF); +dirn2anim_2(sub_80936CC, gUnknown_0850DC04); +dirn2anim_2(sub_80936F8, gUnknown_0850DC09); +dirn2anim_2(sub_8093724, gUnknown_0850DC0E); +dirn2anim_2(sub_8093750, gUnknown_0850DC13); +dirn2anim_2(sub_809377C, gUnknown_0850DC18); +dirn2anim_2(sub_80937A8, gUnknown_0850DC1D); +dirn2anim_2(d2s_08064034, gUnknown_0850DC22); -- cgit v1.2.3 From 0e3dbf32350d41ff871bffcdb4700dc635b243b7 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 23:03:04 -0400 Subject: GetOppositeDirection --- src/field_map_obj.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index d0673fdbe..d17f77c1b 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4058,3 +4058,17 @@ dirn2anim_2(sub_8093750, gUnknown_0850DC13); dirn2anim_2(sub_809377C, gUnknown_0850DC18); dirn2anim_2(sub_80937A8, gUnknown_0850DC1D); dirn2anim_2(d2s_08064034, gUnknown_0850DC22); + +extern const u8 gUnknown_0850DC27[8]; + +u8 GetOppositeDirection(u8 direction) +{ + u8 directions[sizeof gUnknown_0850DC27]; + + memcpy(directions, gUnknown_0850DC27, sizeof gUnknown_0850DC27); + if (direction < 1 || direction > (sizeof gUnknown_0850DC27)) + { + return direction; + } + return directions[direction - 1]; +} -- cgit v1.2.3 From 5f189fa53b6791c5d0e24b85228797606f719bdc Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 23:05:53 -0400 Subject: state_to_direction memes --- src/field_map_obj.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index d17f77c1b..ba207e2bd 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4072,3 +4072,21 @@ u8 GetOppositeDirection(u8 direction) } return directions[direction - 1]; } + +u32 zffu_offset_calc(u8 a0, u8 a1) +{ + return gUnknown_0850DC2F[a0 - 1][a1 - 1]; +} + +u32 state_to_direction(u8 a0, u32 a1, u32 a2) +{ + u32 zffuOffset; + u8 a1_2 = a1; + u8 a2_2 = a2; + if (a1_2 == 0 || a2_2 == 0 || a1_2 > DIR_EAST || a2_2 > DIR_EAST) + { + return 0; + } + zffuOffset = zffu_offset_calc(a1_2, a2); + return gUnknown_0850DC3F[a0 - 1][zffuOffset - 1]; +} -- cgit v1.2.3 From 4e22f1e55fd43ebfd4c94dc7c22aa6b403249370 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 23:11:09 -0400 Subject: MapObjectExec***Anim --- src/field_map_obj.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index ba207e2bd..9702385e4 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4081,8 +4081,11 @@ u32 zffu_offset_calc(u8 a0, u8 a1) u32 state_to_direction(u8 a0, u32 a1, u32 a2) { u32 zffuOffset; - u8 a1_2 = a1; - u8 a2_2 = a2; + u8 a1_2; + u8 a2_2; + + a1_2 = a1; + a2_2 = a2; if (a1_2 == 0 || a2_2 == 0 || a1_2 > DIR_EAST || a2_2 > DIR_EAST) { return 0; @@ -4090,3 +4093,22 @@ u32 state_to_direction(u8 a0, u32 a1, u32 a2) zffuOffset = zffu_offset_calc(a1_2, a2); return gUnknown_0850DC3F[a0 - 1][zffuOffset - 1]; } + +void FieldObjectExecSpecialAnim(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (gUnknown_0850DC50[mapObject->mapobj_unk_1C][sprite->data2](mapObject, sprite)) + { + mapObject->mapobj_bit_7 = TRUE; + } +} + +bool8 FieldObjectExecRegularAnim(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (gUnknown_0850DC50[mapObject->mapobj_unk_1C][sprite->data2](mapObject, sprite)) + { + mapObject->mapobj_unk_1C = 0xFF; + sprite->data2 = 0; + return TRUE; + } + return FALSE; +} -- cgit v1.2.3 From 4ef7127561e4f2f60e2cfa6351b97143f08f6acb Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 23:12:35 -0400 Subject: FieldObjectSetRegularAnim --- src/field_map_obj.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 9702385e4..0629fd983 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4112,3 +4112,9 @@ bool8 FieldObjectExecRegularAnim(struct MapObject *mapObject, struct Sprite *spr } return FALSE; } + +void FieldObjectSetRegularAnim(struct MapObject *mapObject, struct Sprite *sprite, u8 animId) +{ + mapObject->mapobj_unk_1C = animId; + sprite->data2 = 0; +} -- cgit v1.2.3 From 8e03a0199c3226ae5426319c0e820e3337840fb8 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 23:20:44 -0400 Subject: an_look_any simple --- src/field_map_obj.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 0629fd983..80f628bb5 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -1769,6 +1769,7 @@ u16 npc_paltag_by_palslot(u8 palSlot) } // Map Object Step Callbacks +// file boundary? null_object_step(NoMovement1, FALSE) @@ -4118,3 +4119,38 @@ void FieldObjectSetRegularAnim(struct MapObject *mapObject, struct Sprite *sprit mapObject->mapobj_unk_1C = animId; sprite->data2 = 0; } + +// file boundary? + +void an_look_any(struct MapObject *mapObject, struct Sprite *sprite, u8 direction) +{ + FieldObjectSetDirection(mapObject, direction); + npc_coords_shift_still(mapObject); + obj_npc_animation_step(mapObject, sprite, get_go_image_anim_num(mapObject->mapobj_unk_18)); + sprite->animPaused = TRUE; + sprite->data2 = 1; +} + +bool8 sub_8093950(struct MapObject *mapObject, struct Sprite *sprite) +{ + an_look_any(mapObject, sprite, DIR_SOUTH); + return TRUE; +} + +bool8 sub_8093960(struct MapObject *mapObject, struct Sprite *sprite) +{ + an_look_any(mapObject, sprite, DIR_NORTH); + return TRUE; +} + +bool8 sub_8093970(struct MapObject *mapObject, struct Sprite *sprite) +{ + an_look_any(mapObject, sprite, DIR_WEST); + return TRUE; +} + +bool8 sub_8093980(struct MapObject *mapObject, struct Sprite *sprite) +{ + an_look_any(mapObject, sprite, DIR_EAST); + return TRUE; +} -- cgit v1.2.3 From 432924e56d99d37eb721a03907b0eab943458b60 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 23:31:43 -0400 Subject: npc_apply_direction --- src/field_map_obj.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 80f628bb5..4f2a359e4 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4154,3 +4154,23 @@ bool8 sub_8093980(struct MapObject *mapObject, struct Sprite *sprite) an_look_any(mapObject, sprite, DIR_EAST); return TRUE; } + +void npc_apply_direction(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 speed) +{ + s16 x; + s16 y; + + x = mapObject->coords2.x; + y = mapObject->coords2.y; + FieldObjectSetDirection(mapObject, direction); + MoveCoords(direction, &x, &y); + npc_coords_shift(mapObject, x, y); + oamt_npc_ministep_reset(sprite, direction, speed); + sprite->animPaused = FALSE; + if (gUnknown_020375B8 != NULL && sub_8097F78(mapObject) != 0x10) + { + sprite->animPaused = TRUE; + } + mapObject->mapobj_bit_2 = TRUE; + sprite->data2 = 1; +} -- cgit v1.2.3 From 529ccf9a960209333b21aab59b620330370cc791 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 23:49:31 -0400 Subject: do_go_anim --- src/field_map_obj.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 4f2a359e4..0e9086d33 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4174,3 +4174,12 @@ void npc_apply_direction(struct MapObject *mapObject, struct Sprite *sprite, u8 mapObject->mapobj_bit_2 = TRUE; sprite->data2 = 1; } + +void do_go_anim(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 speed) +{ + u8 (*functions[ARRAY_COUNT(gUnknown_0850DEE8)])(u8); + + memcpy(functions, gUnknown_0850DEE8, sizeof gUnknown_0850DEE8); + npc_apply_direction(mapObject, sprite, direction, speed); + npc_apply_anim_looping(mapObject, sprite, functions[speed](mapObject->mapobj_unk_18)); +} -- cgit v1.2.3 From 7c8991842f10cce925a5b3a23f3887a0bb41ecb5 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 16 Sep 2017 23:52:50 -0400 Subject: do_run_anim --- src/field_map_obj.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 0e9086d33..5e32d7330 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4183,3 +4183,9 @@ void do_go_anim(struct MapObject *mapObject, struct Sprite *sprite, u8 direction npc_apply_direction(mapObject, sprite, direction, speed); npc_apply_anim_looping(mapObject, sprite, functions[speed](mapObject->mapobj_unk_18)); } + +void do_run_anim(struct MapObject *mapObject, struct Sprite *sprite, u8 direction) +{ + npc_apply_direction(mapObject, sprite, direction, 1); + npc_apply_anim_looping(mapObject, sprite, get_run_image_anim_num(mapObject->mapobj_unk_18)); +} -- cgit v1.2.3 From 0582b5cb909298b49e7f0588c042fb20a951be44 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 08:05:33 -0400 Subject: npc_obj_ministep_stop_on_arrival --- src/field_map_obj.c | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 5e32d7330..cd840ba70 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -112,21 +112,14 @@ bool8 FieldObjectExecRegularAnim(struct MapObject *, struct Sprite *); void SetFieldObjectStepTimer(struct Sprite *, s16); bool8 RunFieldObjectStepTimer(struct Sprite *); bool8 npc_block_way__next_tile(struct MapObject *, u8); -u32 state_to_direction(u8, u32, u32); -void DoGroundEffects_OnSpawn(struct MapObject *, struct Sprite *); -void sub_80964E8(struct MapObject *, struct Sprite *); -bool8 FieldObjectIsSpecialAnimActive(struct MapObject *); -void FieldObjectExecSpecialAnim(struct MapObject *, struct Sprite *); -void DoGroundEffects_OnBeginStep(struct MapObject *, struct Sprite *); -void DoGroundEffects_OnFinishStep(struct MapObject *, struct Sprite *); -void npc_obj_transfer_image_anim_pause_flag(struct MapObject *, struct Sprite *); -void FieldObjectUpdateSubpriority(struct MapObject *, struct Sprite *); - -bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *fieldObject, s16 x, s16 y); -bool8 IsMetatileDirectionallyImpassable(struct MapObject *, s16, s16, u8); -bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *, s16, s16); -void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *); -void FieldObjectClearAnim(struct MapObject *); +static u32 state_to_direction(u8, u32, u32); +/*static*/ void sub_80964E8(struct MapObject *, struct Sprite *); +static void FieldObjectExecSpecialAnim(struct MapObject *, struct Sprite *); +/*static*/ void npc_obj_transfer_image_anim_pause_flag(struct MapObject *, struct Sprite *); + +static bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *, s16, s16); +static bool8 IsMetatileDirectionallyImpassable(struct MapObject *, s16, s16, u8); +static bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *, s16, s16); // ROM data @@ -3708,7 +3701,7 @@ u8 sub_8092C8C(struct MapObject *mapObject, s16 x, s16 y, u8 direction) return retval; } -bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *mapObject, s16 x, s16 y) +static bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *mapObject, s16 x, s16 y) { s16 left; s16 right; @@ -3736,7 +3729,7 @@ bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *mapObject, s16 x, return FALSE; } -bool8 IsMetatileDirectionallyImpassable(struct MapObject *mapObject, s16 x, s16 y, u8 direction) +static bool8 IsMetatileDirectionallyImpassable(struct MapObject *mapObject, s16 x, s16 y, u8 direction) { if (gUnknown_0850DB5C[direction - 1](mapObject->mapobj_unk_1E) || gUnknown_0850DB6C[direction - 1](MapGridGetMetatileBehaviorAt(x, y))) { @@ -3745,7 +3738,7 @@ bool8 IsMetatileDirectionallyImpassable(struct MapObject *mapObject, s16 x, s16 return FALSE; } -bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *mapObject, s16 x, s16 y) +static bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *mapObject, s16 x, s16 y) { u8 i; struct MapObject *curObject; @@ -4074,12 +4067,12 @@ u8 GetOppositeDirection(u8 direction) return directions[direction - 1]; } -u32 zffu_offset_calc(u8 a0, u8 a1) +static u32 zffu_offset_calc(u8 a0, u8 a1) { return gUnknown_0850DC2F[a0 - 1][a1 - 1]; } -u32 state_to_direction(u8 a0, u32 a1, u32 a2) +static u32 state_to_direction(u8 a0, u32 a1, u32 a2) { u32 zffuOffset; u8 a1_2; @@ -4095,7 +4088,7 @@ u32 state_to_direction(u8 a0, u32 a1, u32 a2) return gUnknown_0850DC3F[a0 - 1][zffuOffset - 1]; } -void FieldObjectExecSpecialAnim(struct MapObject *mapObject, struct Sprite *sprite) +static void FieldObjectExecSpecialAnim(struct MapObject *mapObject, struct Sprite *sprite) { if (gUnknown_0850DC50[mapObject->mapobj_unk_1C][sprite->data2](mapObject, sprite)) { @@ -4189,3 +4182,15 @@ void do_run_anim(struct MapObject *mapObject, struct Sprite *sprite, u8 directio npc_apply_direction(mapObject, sprite, direction, 1); npc_apply_anim_looping(mapObject, sprite, get_run_image_anim_num(mapObject->mapobj_unk_18)); } + +bool8 npc_obj_ministep_stop_on_arrival(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (obj_npc_ministep(sprite)) + { + npc_coords_shift_still(mapObject); + mapObject->mapobj_bit_3 = TRUE; + sprite->animPaused = TRUE; + return TRUE; + } + return FALSE; +} -- cgit v1.2.3 From a9a66b06ef9f747d55be846dfc02ee90a39deddb Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sun, 17 Sep 2017 14:10:32 +0200 Subject: start porting cam's port of battle3 --- src/battle_3.c | 1387 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/battle_ai.c | 6 +- src/hall_of_fame.c | 4 + 3 files changed, 1394 insertions(+), 3 deletions(-) create mode 100644 src/battle_3.c create mode 100644 src/hall_of_fame.c (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c new file mode 100644 index 000000000..34e45ca74 --- /dev/null +++ b/src/battle_3.c @@ -0,0 +1,1387 @@ +#include "global.h" +#include "battle.h" +#include "abilities.h" +#include "moves.h" +#include "hold_effects.h" +#include "pokemon.h" +#include "species.h" +#include "item.h" +#include "items.h" +#include "util.h" +#include "battle_move_effects.h" +#include "rng.h" +#include "text.h" +#include "string_util.h" +#include "battle_message.h" + +extern const u8* gBattlescriptCurrInstr; +extern const u8* gUnknown_02024220[BATTLE_BANKS_COUNT]; +extern const u8* gUnknown_02024230[BATTLE_BANKS_COUNT]; +extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT]; +extern u8 gActiveBank; +extern u8 gStringBank; +extern u16 gCurrentMove; +extern u16 gLastUsedItem; +extern u8 gNoOfAllBanks; +extern u32 gStatuses3[BATTLE_BANKS_COUNT]; +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern u8 gAbsentBankFlags; +extern u16 gBattleWeather; +extern u8 gTurnOrder[BATTLE_BANKS_COUNT]; +extern u16 gSideAffecting[]; +extern u8 gBattleCommunication[]; +extern void (*gBattleMainFunc)(void); +extern s32 gBattleMoveDamage; +extern struct BattleEnigmaBerry gEnigmaBerries[BATTLE_BANKS_COUNT]; +extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200]; +extern u32 gBattleTypeFlags; +extern u16 gLastUsedMovesByBanks[BATTLE_BANKS_COUNT]; +extern u32 gHitMarker; +extern u8 gEffectBank; +extern u16 gBattlePartyID[BATTLE_BANKS_COUNT]; +extern u8 gBank1; +extern u16 gChosenMovesByBanks[]; +extern u8 gBattleMoveFlags; +extern s32 gTakenDmg[BATTLE_BANKS_COUNT]; +extern u8 gTakenDmgBanks[BATTLE_BANKS_COUNT]; + +extern const struct BattleMove gBattleMoves[]; + +// scripts +extern const u8 gUnknown_082DAE2A[]; +extern const u8 gUnknown_082DAE1F[]; +extern const u8 gUnknown_082DB089[]; +extern const u8 gUnknown_082DB098[]; +extern const u8 gUnknown_082DB0AF[]; +extern const u8 gUnknown_082DB0A0[]; +extern const u8 gUnknown_082DB185[]; +extern const u8 gUnknown_082DB181[]; +extern const u8 gUnknown_082DB812[]; +extern const u8 gUnknown_082DB076[]; +extern const u8 BattleScript_NoMovesLeft[]; +extern const u8 gUnknown_082DACFA[]; +extern const u8 gUnknown_082DAD0B[]; +extern const u8 gUnknown_082DACC9[]; +extern const u8 gUnknown_082DAC47[]; +extern const u8 gUnknown_082DACE0[]; +extern const u8 gUnknown_082DACD2[]; +extern const u8 BattleScript_WishComesTrue[]; +extern const u8 gUnknown_082DACC9[]; +extern const u8 gUnknown_082DAC2C[]; +extern const u8 BattleScript_IngrainTurnHeal[]; +extern const u8 BattleScript_LeechSeedTurnDrain[]; +extern const u8 BattleScript_PoisonTurnDmg[]; +extern const u8 BattleScript_BurnTurnDmg[]; +extern const u8 BattleScript_NightmareTurnDmg[]; +extern const u8 BattleScript_CurseTurnDmg[]; +extern const u8 BattleScript_WrapTurnDmg[]; +extern const u8 BattleScript_WrapEnds[]; +extern const u8 gUnknown_082DB234[]; +extern const u8 gUnknown_082DB2A6[]; +extern const u8 BattleScript_ThrashConfuses[]; +extern const u8 BattleScript_DisabledNoMore[]; +extern const u8 BattleScript_EncoredNoMore[]; +extern const u8 BattleScript_YawnMakesAsleep[]; +extern const u8 gUnknown_082DAFE4[]; +extern const u8 gUnknown_082DB8F3[]; +extern const u8 gUnknown_082DAF05[]; +extern const u8 gUnknown_082DAF20[]; +extern const u8 gUnknown_082DA7C4[]; +extern const u8 gUnknown_082DA7CD[]; +extern const u8 BattleScript_MoveUsedWokeUp[]; +extern const u8 BattleScript_MoveUsedIsAsleep[]; +extern const u8 BattleScript_MoveUsedIsFrozen[]; +extern const u8 BattleScript_MoveUsedUnfroze[]; +extern const u8 BattleScript_MoveUsedLoafingAround[]; +extern const u8 BattleScript_MoveUsedMustRecharge[]; +extern const u8 BattleScript_MoveUsedFlinched[]; +extern const u8 BattleScript_MoveUsedIsDisabled[]; +extern const u8 BattleScript_MoveUsedIsTaunted[]; +extern const u8 BattleScript_MoveUsedIsImprisoned[]; +extern const u8 BattleScript_MoveUsedIsConfused[]; +extern const u8 BattleScript_MoveUsedIsConfusedNoMore[]; +extern const u8 BattleScript_MoveUsedIsParalyzed[]; +extern const u8 BattleScript_MoveUsedIsParalyzedCantAttack[]; +extern const u8 BattleScript_MoveUsedIsInLove[]; +extern const u8 BattleScript_BideStoringEnergy[]; +extern const u8 BattleScript_BideAttack[]; +extern const u8 BattleScript_BideNoEnergyToAttack[]; + +extern void CancelMultiTurnMoves(u8 bank); +extern u8 b_first_side(u8, u8, u8); +extern void sub_803CEDC(u8, u8); +extern void b_call_bc_move_exec(const u8 *); +extern void BattleTurnPassed(void); +extern void EmitSetAttributes(u8 a, u8 request, u8 c, u8 bytes, void *data); +extern void SetMoveEffect(bool8 primary, u8 certainArg); +extern bool8 UproarWakeUpCheck(u8 bank); +extern void MarkBufferBankForExecution(u8 bank); +extern u8 sub_803F90C(u8 bank); +extern u8 GetBankIdentity(u8); +extern void sub_803F9EC(); +extern bool8 sub_80423F4(u8 bank, u8, u8); +extern s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideFlags, u16 powerOverride, u8 typeOverride, u8 bankAtk, u8 bankDef); + +u8 IsImprisoned(u8 bank, u16 move); +u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn); +u8 GetMoveTarget(u16 move, u8 useMoveTarget); + +void b_movescr_stack_push(const u8* bsPtr) +{ + BATTLESCRIPTS_STACK->ptr[BATTLESCRIPTS_STACK->size++] = bsPtr; +} + +void b_movescr_stack_push_cursor(void) +{ + BATTLESCRIPTS_STACK->ptr[BATTLESCRIPTS_STACK->size++] = gBattlescriptCurrInstr; +} + +void b_movescr_stack_pop_cursor(void) +{ + gBattlescriptCurrInstr = BATTLESCRIPTS_STACK->ptr[--BATTLESCRIPTS_STACK->size]; +} + +u8 sub_803FB4C(void) // msg, can't select a move +{ + u8 limitations = 0; + u16 move = gBattleMons[gActiveBank].moves[gBattleBufferB[gActiveBank][2]]; + u8 holdEffect; + u16* choicedMove = &gBattleStruct->choicedMove[gActiveBank]; + + if (gDisableStructs[gActiveBank].disabledMove == move && move != 0) + { + gBattleScripting.bank = gActiveBank; + gCurrentMove = move; + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + { + gUnknown_02024230[gActiveBank] = gUnknown_082DAE2A; + gProtectStructs[gActiveBank].flag_x10 = 1; + } + else + { + gUnknown_02024220[gActiveBank] = gUnknown_082DAE1F; + limitations = 1; + } + } + + if (move == gLastUsedMovesByBanks[gActiveBank] && move != MOVE_STRUGGLE && (gBattleMons[gActiveBank].status2 & STATUS2_TORMENT)) + { + CancelMultiTurnMoves(gActiveBank); + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + { + gUnknown_02024230[gActiveBank] = gUnknown_082DB098; + gProtectStructs[gActiveBank].flag_x10 = 1; + } + else + { + gUnknown_02024220[gActiveBank] = gUnknown_082DB089; + limitations++; + } + } + + if (gDisableStructs[gActiveBank].tauntTimer1 != 0 && gBattleMoves[move].power == 0) + { + gCurrentMove = move; + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + { + gUnknown_02024230[gActiveBank] = gUnknown_082DB0AF; + gProtectStructs[gActiveBank].flag_x10 = 1; + } + else + { + gUnknown_02024220[gActiveBank] = gUnknown_082DB0A0; + limitations++; + } + } + + if (IsImprisoned(gActiveBank, move)) + { + gCurrentMove = move; + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + { + gUnknown_02024230[gActiveBank] = gUnknown_082DB185; + gProtectStructs[gActiveBank].flag_x10 = 1; + } + else + { + gUnknown_02024220[gActiveBank] = gUnknown_082DB181; + limitations++; + } + } + + if (gBattleMons[gActiveBank].item == ITEM_ENIGMA_BERRY) + holdEffect = gEnigmaBerries[gActiveBank].holdEffect; + else + holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBank].item); + + gStringBank = gActiveBank; + + if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != move) + { + gCurrentMove = *choicedMove; + gLastUsedItem = gBattleMons[gActiveBank].item; + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + { + gProtectStructs[gActiveBank].flag_x10 = 1; + } + else + { + gUnknown_02024220[gActiveBank] = gUnknown_082DB812; + limitations++; + } + } + + if (gBattleMons[gActiveBank].pp[gBattleBufferB[gActiveBank][2]] == 0) + { + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + { + gProtectStructs[gActiveBank].flag_x10 = 1; + } + else + { + gUnknown_02024220[gActiveBank] = gUnknown_082DB076; + limitations++; + } + } + + return limitations; +} + +#define MOVE_LIMITATION_ZEROMOVE (1 << 0) +#define MOVE_LIMITATION_PP (1 << 1) +#define MOVE_LIMITATION_DISABLED (1 << 2) +#define MOVE_LIMITATION_TORMENTED (1 << 3) +#define MOVE_LIMITATION_TAUNT (1 << 4) +#define MOVE_LIMITATION_IMPRISION (1 << 5) + +u8 CheckMoveLimitations(u8 bank, u8 unusableMoves, u8 check) +{ + u8 holdEffect; + u16* choicedMove = &gBattleStruct->choicedMove[bank]; + s32 i; + + if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY) + holdEffect = gEnigmaBerries[bank].holdEffect; + else + holdEffect = ItemId_GetHoldEffect(gBattleMons[bank].item); + + gStringBank = bank; + + for (i = 0; i < BATTLE_BANKS_COUNT; i++) + { + if (gBattleMons[bank].moves[i] == 0 && check & MOVE_LIMITATION_ZEROMOVE) + unusableMoves |= gBitTable[i]; + if (gBattleMons[bank].pp[i] == 0 && check & MOVE_LIMITATION_PP) + unusableMoves |= gBitTable[i]; + if (gBattleMons[bank].moves[i] == gDisableStructs[bank].disabledMove && check & MOVE_LIMITATION_DISABLED) + unusableMoves |= gBitTable[i]; + if (gBattleMons[bank].moves[i] == gLastUsedMovesByBanks[bank] && check & MOVE_LIMITATION_TORMENTED && gBattleMons[bank].status2 & STATUS2_TORMENT) + unusableMoves |= gBitTable[i]; + if (gDisableStructs[bank].tauntTimer1 && check & MOVE_LIMITATION_TAUNT && gBattleMoves[gBattleMons[bank].moves[i]].power == 0) + unusableMoves |= gBitTable[i]; + if (IsImprisoned(bank, gBattleMons[bank].moves[i]) && check & MOVE_LIMITATION_IMPRISION) + unusableMoves |= gBitTable[i]; + if (gDisableStructs[bank].encoreTimer1 && gDisableStructs[bank].encoredMove != gBattleMons[bank].moves[i]) + unusableMoves |= gBitTable[i]; + if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[bank].moves[i]) + unusableMoves |= gBitTable[i]; + } + return unusableMoves; +} + +bool8 AreAllMovesUnusable(void) +{ + u8 unusable; + unusable = CheckMoveLimitations(gActiveBank, 0, 0xFF); + + if (unusable == 0xF) // all moves are unusable + { + gProtectStructs[gActiveBank].onlyStruggle = 1; + gUnknown_02024220[gActiveBank] = BattleScript_NoMovesLeft; + } + else + { + gProtectStructs[gActiveBank].onlyStruggle = 0; + } + + return (unusable == 0xF); +} + +u8 IsImprisoned(u8 bank, u16 move) +{ + s32 i; + u8 imprisionedMoves = 0; + u8 bankSide = GetBankSide(bank); + + for (i = 0; i < gNoOfAllBanks; i++) + { + if (bankSide != GetBankSide(i) && gStatuses3[i] & STATUS3_IMPRISIONED) + { + s32 j; + for (j = 0; j < 4; j++) + { + if (move == gBattleMons[i].moves[j]) + break; + } + if (j < 4) + imprisionedMoves++; + } + } + + return imprisionedMoves; +} + +u8 UpdateTurnCounters(void) +{ + u8 effect = 0; + s32 i; + + for (gBankAttacker = 0; gBankAttacker < gNoOfAllBanks && gAbsentBankFlags & gBitTable[gBankAttacker]; gBankAttacker++) + { + } + for (gBankTarget = 0; gBankTarget < gNoOfAllBanks && gAbsentBankFlags & gBitTable[gBankTarget]; gBankTarget++) + { + } + + do + { + u8 sideBank; + + switch (gBattleStruct->turncountersTracker) + { + case 0: + for (i = 0; i < gNoOfAllBanks; i++) + { + gTurnOrder[i] = i; + } + for (i = 0; i < gNoOfAllBanks - 1; i++) + { + s32 j; + for (j = i + 1; j < gNoOfAllBanks; j++) + { + if (b_first_side(gTurnOrder[i], gTurnOrder[j], 0)) + sub_803CEDC(i, j); + } + } + + // It's stupid, but won't match without it + { + u8* var = &gBattleStruct->turncountersTracker; + (*var)++; + gBattleStruct->turnSideTracker = 0; + } + // fall through + case 1: + while (gBattleStruct->turnSideTracker < 2) + { + sideBank = gBattleStruct->turnSideTracker; + gActiveBank = gBankAttacker = gSideTimers[sideBank].reflectBank; + if (gSideAffecting[sideBank] & SIDE_STATUS_REFLECT) + { + if (--gSideTimers[sideBank].reflectTimer == 0) + { + gSideAffecting[sideBank] &= ~SIDE_STATUS_REFLECT; + b_call_bc_move_exec(gUnknown_082DACFA); + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = MOVE_REFLECT; + gBattleTextBuff1[3] = MOVE_REFLECT >> 8; + gBattleTextBuff1[4] = EOS; + effect++; + } + } + gBattleStruct->turnSideTracker++; + if (effect) + break; + } + if (!effect) + { + gBattleStruct->turncountersTracker++; + gBattleStruct->turnSideTracker = 0; + } + break; + case 2: + while (gBattleStruct->turnSideTracker < 2) + { + sideBank = gBattleStruct->turnSideTracker; + gActiveBank = gBankAttacker = gSideTimers[sideBank].lightscreenBank; + if (gSideAffecting[sideBank] & SIDE_STATUS_LIGHTSCREEN) + { + if (--gSideTimers[sideBank].lightscreenTimer == 0) + { + gSideAffecting[sideBank] &= ~SIDE_STATUS_LIGHTSCREEN; + b_call_bc_move_exec(gUnknown_082DACFA); + gBattleCommunication[MULTISTRING_CHOOSER] = sideBank; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = MOVE_LIGHT_SCREEN; + gBattleTextBuff1[3] = MOVE_LIGHT_SCREEN >> 8; + gBattleTextBuff1[4] = EOS; + effect++; + } + } + gBattleStruct->turnSideTracker++; + if (effect) + break; + } + if (!effect) + { + gBattleStruct->turncountersTracker++; + gBattleStruct->turnSideTracker = 0; + } + break; + case 3: + while (gBattleStruct->turnSideTracker < 2) + { + sideBank = gBattleStruct->turnSideTracker; + gActiveBank = gBankAttacker = gSideTimers[sideBank].mistBank; + if (gSideTimers[sideBank].mistTimer != 0 + && --gSideTimers[sideBank].mistTimer == 0) + { + gSideAffecting[sideBank] &= ~SIDE_STATUS_MIST; + b_call_bc_move_exec(gUnknown_082DACFA); + gBattleCommunication[MULTISTRING_CHOOSER] = sideBank; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = MOVE_MIST; + gBattleTextBuff1[3] = MOVE_MIST >> 8; + gBattleTextBuff1[4] = EOS; + effect++; + } + gBattleStruct->turnSideTracker++; + if (effect) + break; + } + if (!effect) + { + gBattleStruct->turncountersTracker++; + gBattleStruct->turnSideTracker = 0; + } + break; + case 4: + while (gBattleStruct->turnSideTracker < 2) + { + sideBank = gBattleStruct->turnSideTracker; + gActiveBank = gBankAttacker = gSideTimers[sideBank].safeguardBank; + if (gSideAffecting[sideBank] & SIDE_STATUS_SAFEGUARD) + { + if (--gSideTimers[sideBank].safeguardTimer == 0) + { + gSideAffecting[sideBank] &= ~SIDE_STATUS_SAFEGUARD; + b_call_bc_move_exec(gUnknown_082DAD0B); + effect++; + } + } + gBattleStruct->turnSideTracker++; + if (effect) + break; + } + if (!effect) + { + gBattleStruct->turncountersTracker++; + gBattleStruct->turnSideTracker = 0; + } + break; + case 5: + while (gBattleStruct->turnSideTracker < gNoOfAllBanks) + { + gActiveBank = gTurnOrder[gBattleStruct->turnSideTracker]; + if (gWishFutureKnock.wishCounter[gActiveBank] != 0 + && --gWishFutureKnock.wishCounter[gActiveBank] == 0 + && gBattleMons[gActiveBank].hp != 0) + { + gBankTarget = gActiveBank; + b_call_bc_move_exec(BattleScript_WishComesTrue); + effect++; + } + gBattleStruct->turnSideTracker++; + if (effect) + break; + } + if (!effect) + { + gBattleStruct->turncountersTracker++; + } + break; + case 6: + if (gBattleWeather & WEATHER_RAIN_ANY) + { + if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)) + { + if (--gWishFutureKnock.weatherDuration == 0) + { + gBattleWeather &= ~WEATHER_RAIN_TEMPORARY; + gBattleWeather &= ~WEATHER_RAIN_DOWNPOUR; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else if (gBattleWeather & WEATHER_RAIN_DOWNPOUR) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else if (gBattleWeather & WEATHER_RAIN_DOWNPOUR) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + b_call_bc_move_exec(gUnknown_082DAC2C); + effect++; + } + gBattleStruct->turncountersTracker++; + break; + case 7: + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + { + if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT) && --gWishFutureKnock.weatherDuration == 0) + { + gBattleWeather &= ~WEATHER_SANDSTORM_TEMPORARY; + gBattlescriptCurrInstr = gUnknown_082DACC9; + } + else + gBattlescriptCurrInstr = gUnknown_082DAC47; + + gBattleScripting.animArg1 = 0xC; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + b_call_bc_move_exec(gBattlescriptCurrInstr); + effect++; + } + gBattleStruct->turncountersTracker++; + break; + case 8: + if (gBattleWeather & WEATHER_SUN_ANY) + { + if (!(gBattleWeather & WEATHER_SUN_PERMANENT) && --gWishFutureKnock.weatherDuration == 0) + { + gBattleWeather &= ~WEATHER_SUN_TEMPORARY; + gBattlescriptCurrInstr = gUnknown_082DACE0; + } + else + gBattlescriptCurrInstr = gUnknown_082DACD2; + + b_call_bc_move_exec(gBattlescriptCurrInstr); + effect++; + } + gBattleStruct->turncountersTracker++; + break; + case 9: + if (gBattleWeather & WEATHER_HAIL) + { + if (--gWishFutureKnock.weatherDuration == 0) + { + gBattleWeather &= ~WEATHER_HAIL; + gBattlescriptCurrInstr = gUnknown_082DACC9; + } + else + gBattlescriptCurrInstr = gUnknown_082DAC47; + + gBattleScripting.animArg1 = 0xD; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + b_call_bc_move_exec(gBattlescriptCurrInstr); + effect++; + } + gBattleStruct->turncountersTracker++; + break; + case 10: + effect++; + break; + } + } while (effect == 0); + return (gBattleMainFunc != BattleTurnPassed); +} + +#define TURNBASED_MAX_CASE 19 + +u8 TurnBasedEffects(void) +{ + u8 effect = 0; + + gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20); + while (gBattleStruct->turnEffectsBank < gNoOfAllBanks && gBattleStruct->turnEffectsTracker <= TURNBASED_MAX_CASE) + { + gActiveBank = gBankAttacker = gTurnOrder[gBattleStruct->turnEffectsBank]; + if (gAbsentBankFlags & gBitTable[gActiveBank]) + { + gBattleStruct->turnEffectsBank++; + } + else + { + switch (gBattleStruct->turnEffectsTracker) + { + case 0: // ingrain + if ((gStatuses3[gActiveBank] & STATUS3_ROOTED) + && gBattleMons[gActiveBank].hp != gBattleMons[gActiveBank].maxHP + && gBattleMons[gActiveBank].hp != 0) + { + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + b_call_bc_move_exec(BattleScript_IngrainTurnHeal); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 1: // end turn abilities + if (AbilityBattleEffects(ABILITYEFFECT_ENDTURN, gActiveBank, 0, 0, 0)) + effect++; + gBattleStruct->turnEffectsTracker++; + break; + case 2: // item effects + if (ItemBattleEffects(1, gActiveBank, 0)) + effect++; + gBattleStruct->turnEffectsTracker++; + break; + case 18: // item effects again + if (ItemBattleEffects(1, gActiveBank, 1)) + effect++; + gBattleStruct->turnEffectsTracker++; + break; + case 3: // leech seed + if ((gStatuses3[gActiveBank] & STATUS3_LEECHSEED) + && gBattleMons[gStatuses3[gActiveBank] & STATUS3_LEECHSEED_BANK].hp != 0 + && gBattleMons[gActiveBank].hp != 0) + { + gBankTarget = gStatuses3[gActiveBank] & STATUS3_LEECHSEED_BANK; //funny how the 'target' is actually the bank that receives HP + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleScripting.animArg1 = gBankTarget; + gBattleScripting.animArg2 = gBankAttacker; + b_call_bc_move_exec(BattleScript_LeechSeedTurnDrain); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 4: // poison + if ((gBattleMons[gActiveBank].status1 & STATUS_POISON) && gBattleMons[gActiveBank].hp != 0) + { + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + b_call_bc_move_exec(BattleScript_PoisonTurnDmg); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 5: // toxic poison + if ((gBattleMons[gActiveBank].status1 & STATUS_TOXIC_POISON) && gBattleMons[gActiveBank].hp != 0) + { + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if ((gBattleMons[gActiveBank].status1 & 0xF00) != 0xF00) //not 16 turns + gBattleMons[gActiveBank].status1 += 0x100; + gBattleMoveDamage *= (gBattleMons[gActiveBank].status1 & 0xF00) >> 8; + b_call_bc_move_exec(BattleScript_PoisonTurnDmg); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 6: // burn + if ((gBattleMons[gActiveBank].status1 & STATUS_BURN) && gBattleMons[gActiveBank].hp != 0) + { + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + b_call_bc_move_exec(BattleScript_BurnTurnDmg); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 7: // spooky nightmares + if ((gBattleMons[gActiveBank].status2 & STATUS2_NIGHTMARE) && gBattleMons[gActiveBank].hp != 0) + { + // R/S does not perform this sleep check, which causes the nighmare effect to + // persist even after the affected Pokemon has been awakened by Shed Skin + if (gBattleMons[gActiveBank].status1 & STATUS_SLEEP) + { + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + b_call_bc_move_exec(BattleScript_NightmareTurnDmg); + effect++; + } + else + { + gBattleMons[gActiveBank].status2 &= ~STATUS2_NIGHTMARE; + } + } + gBattleStruct->turnEffectsTracker++; + break; + case 8: // curse + if ((gBattleMons[gActiveBank].status2 & STATUS2_CURSED) && gBattleMons[gActiveBank].hp != 0) + { + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + b_call_bc_move_exec(BattleScript_CurseTurnDmg); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 9: // wrap + if ((gBattleMons[gActiveBank].status2 & STATUS2_WRAPPED) && gBattleMons[gActiveBank].hp != 0) + { + gBattleMons[gActiveBank].status2 -= 0x2000; + if (gBattleMons[gActiveBank].status2 & STATUS2_WRAPPED) // damaged by wrap + { + // This is the only way I could get this array access to match. + gBattleScripting.animArg1 = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 0); + gBattleScripting.animArg2 = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 1); + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 0); + gBattleTextBuff1[3] = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 1); + gBattleTextBuff1[4] = EOS; + gBattlescriptCurrInstr = BattleScript_WrapTurnDmg; + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + else // broke free + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 0); + gBattleTextBuff1[3] = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 1); + gBattleTextBuff1[4] = EOS; + gBattlescriptCurrInstr = BattleScript_WrapEnds; + } + b_call_bc_move_exec(gBattlescriptCurrInstr); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 10: // uproar + if (gBattleMons[gActiveBank].status2 & STATUS2_UPROAR) + { + for (gBankAttacker = 0; gBankAttacker < gNoOfAllBanks; gBankAttacker++) + { + if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) + && gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF) + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + b_call_bc_move_exec(gUnknown_082DB234); + gActiveBank = gBankAttacker; + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + break; + } + } + if (gBankAttacker != gNoOfAllBanks) + { + effect = 2; // a pokemon was awaken + break; + } + else + { + gBankAttacker = gActiveBank; + gBattleMons[gActiveBank].status2 -= 0x10; // uproar timer goes down + if (sub_803F90C(gActiveBank)) + { + CancelMultiTurnMoves(gActiveBank); + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else if (gBattleMons[gActiveBank].status2 & STATUS2_UPROAR) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattleMons[gActiveBank].status2 |= STATUS2_MULTIPLETURNS; + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + CancelMultiTurnMoves(gActiveBank); + } + b_call_bc_move_exec(gUnknown_082DB2A6); + effect = 1; + } + } + if (effect != 2) + gBattleStruct->turnEffectsTracker++; + break; + case 11: // thrash + if (gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE) + { + gBattleMons[gActiveBank].status2 -= 0x400; + if (sub_803F90C(gActiveBank)) + CancelMultiTurnMoves(gActiveBank); + else if (!(gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE) + && (gBattleMons[gActiveBank].status2 & STATUS2_MULTIPLETURNS)) + { + gBattleMons[gActiveBank].status2 &= ~(STATUS2_MULTIPLETURNS); + if (!(gBattleMons[gActiveBank].status2 & STATUS2_CONFUSION)) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x47; + SetMoveEffect(1, 0); + if (gBattleMons[gActiveBank].status2 & STATUS2_CONFUSION) + b_call_bc_move_exec(BattleScript_ThrashConfuses); + effect++; + } + } + } + gBattleStruct->turnEffectsTracker++; + break; + case 12: // disable + if (gDisableStructs[gActiveBank].disableTimer1 != 0) + { + int i; + for (i = 0; i < 4; i++) + { + if (gDisableStructs[gActiveBank].disabledMove == gBattleMons[gActiveBank].moves[i]) + break; + } + if (i == 4) // pokemon does not have the disabled move anymore + { + gDisableStructs[gActiveBank].disabledMove = 0; + gDisableStructs[gActiveBank].disableTimer1 = 0; + } + else if (--gDisableStructs[gActiveBank].disableTimer1 == 0) // disable ends + { + gDisableStructs[gActiveBank].disabledMove = 0; + b_call_bc_move_exec(BattleScript_DisabledNoMore); + effect++; + } + } + gBattleStruct->turnEffectsTracker++; + break; + case 13: // encore + if (gDisableStructs[gActiveBank].encoreTimer1 != 0) + { + if (gBattleMons[gActiveBank].moves[gDisableStructs[gActiveBank].encoredMovePos] != gDisableStructs[gActiveBank].encoredMove) // pokemon does not have the encored move anymore + { + gDisableStructs[gActiveBank].encoredMove = 0; + gDisableStructs[gActiveBank].encoreTimer1 = 0; + } + else if (--gDisableStructs[gActiveBank].encoreTimer1 == 0 + || gBattleMons[gActiveBank].pp[gDisableStructs[gActiveBank].encoredMovePos] == 0) + { + gDisableStructs[gActiveBank].encoredMove = 0; + gDisableStructs[gActiveBank].encoreTimer1 = 0; + b_call_bc_move_exec(BattleScript_EncoredNoMore); + effect++; + } + } + gBattleStruct->turnEffectsTracker++; + break; + case 14: // lock-on decrement + if (gStatuses3[gActiveBank] & STATUS3_ALWAYS_HITS) + gStatuses3[gActiveBank] -= 0x8; + gBattleStruct->turnEffectsTracker++; + break; + case 15: // charge + if (gDisableStructs[gActiveBank].chargeTimer1 && --gDisableStructs[gActiveBank].chargeTimer1 == 0) + gStatuses3[gActiveBank] &= ~STATUS3_CHARGED_UP; + gBattleStruct->turnEffectsTracker++; + break; + case 16: // taunt + if (gDisableStructs[gActiveBank].tauntTimer1) + gDisableStructs[gActiveBank].tauntTimer1--; + gBattleStruct->turnEffectsTracker++; + break; + case 17: // yawn + if (gStatuses3[gActiveBank] & STATUS3_YAWN) + { + gStatuses3[gActiveBank] -= 0x800; + if (!(gStatuses3[gActiveBank] & STATUS3_YAWN) && !(gBattleMons[gActiveBank].status1 & STATUS_ANY) + && gBattleMons[gActiveBank].ability != ABILITY_VITAL_SPIRIT + && gBattleMons[gActiveBank].ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBank)) + { + CancelMultiTurnMoves(gActiveBank); + gBattleMons[gActiveBank].status1 |= (Random() & 3) + 2; + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + gEffectBank = gActiveBank; + b_call_bc_move_exec(BattleScript_YawnMakesAsleep); + effect++; + } + } + gBattleStruct->turnEffectsTracker++; + break; + case 19: // done + gBattleStruct->turnEffectsTracker = 0; + gBattleStruct->turnEffectsBank++; + break; + } + if (effect != 0) + return effect; + } + } + gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20); + return 0; +} + +bool8 sub_8041364(void) +{ + gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20); + + switch (gBattleStruct->unk1A0) + { + case 0: + while (gBattleStruct->unk1A1 < gNoOfAllBanks) + { + gActiveBank = gBattleStruct->unk1A1; + if (gAbsentBankFlags & gBitTable[gActiveBank]) + { + gBattleStruct->unk1A1++; + continue; + } + + gBattleStruct->unk1A1++; + if (gWishFutureKnock.futureSightCounter[gActiveBank] != 0 + && --gWishFutureKnock.futureSightCounter[gActiveBank] == 0 + && gBattleMons[gActiveBank].hp != 0) + { + if (gWishFutureKnock.futureSightMove[gActiveBank] == MOVE_FUTURE_SIGHT) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = gWishFutureKnock.futureSightMove[gActiveBank]; + gBattleTextBuff1[3] = gWishFutureKnock.futureSightMove[gActiveBank] >> 8; + gBattleTextBuff1[4] = EOS; + gBankTarget = gActiveBank; + gBankAttacker = gWishFutureKnock.futureSightAttacker[gActiveBank]; + gBattleMoveDamage = gWishFutureKnock.futureSightDmg[gActiveBank]; + gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF; + b_call_bc_move_exec(gUnknown_082DAFE4); + + if (gWishFutureKnock.futureSightCounter[gActiveBank] == 0 + && gWishFutureKnock.futureSightCounter[gActiveBank ^ 2] == 0) + { + gSideAffecting[GetBankIdentity(gBankTarget) & 1] &= ~SIDE_STATUS_FUTUREATTACK; + } + return 1; + } + } + // Why do I have to keep doing this to match? + { + u8* var = &gBattleStruct->unk1A0; + *var = 1; + gBattleStruct->unk1A1 = 0; + } + // fall through + case 1: + while (gBattleStruct->unk1A1 < gNoOfAllBanks) + { + gActiveBank = gBankAttacker = gTurnOrder[gBattleStruct->unk1A1]; + if (gAbsentBankFlags & gBitTable[gActiveBank]) + { + gBattleStruct->unk1A1++; + continue; + } + gBattleStruct->unk1A1++; + if (gStatuses3[gActiveBank] & STATUS3_PERISH_SONG) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 1; + gBattleTextBuff1[2] = 1; + gBattleTextBuff1[3] = 1; + gBattleTextBuff1[4] = gDisableStructs[gActiveBank].perishSong1; + gBattleTextBuff1[5] = EOS; + if (gDisableStructs[gActiveBank].perishSong1 == 0) + { + gStatuses3[gActiveBank] &= ~STATUS3_PERISH_SONG; + gBattleMoveDamage = gBattleMons[gActiveBank].hp; + gBattlescriptCurrInstr = gUnknown_082DAF05; + } + else + { + gDisableStructs[gActiveBank].perishSong1--; + gBattlescriptCurrInstr = gUnknown_082DAF20; + } + b_call_bc_move_exec(gBattlescriptCurrInstr); + return 1; + } + } + // Hm... + { + u8* var = &gBattleStruct->unk1A0; + *var = 2; + gBattleStruct->unk1A1 = 0; + } + // fall through + case 2: + if ((gBattleTypeFlags & BATTLE_TYPE_ARENA) + && gBattleStruct->unkDA == 2 + && gBattleMons[0].hp != 0 && gBattleMons[1].hp != 0) + { + s32 i; + + for (i = 0; i < 2; i++) + CancelMultiTurnMoves(i); + + gBattlescriptCurrInstr = gUnknown_082DB8F3; + b_call_bc_move_exec(gUnknown_082DB8F3); + gBattleStruct->unk1A0++; + return 1; + } + break; + } + + gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20); + + return 0; +} + +#define sub_8041728_MAX_CASE 7 + +bool8 sub_8041728(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + return FALSE; + do + { + int i; + switch (gBattleStruct->field_4D) + { + case 0: + gBattleStruct->field_4E = 0; + gBattleStruct->field_4D++; + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gAbsentBankFlags & gBitTable[i] && !sub_80423F4(i, 6, 6)) + gAbsentBankFlags &= ~(gBitTable[i]); + } + // fall through + case 1: + do + { + gBank1 = gBankTarget = gBattleStruct->field_4E; + if (gBattleMons[gBattleStruct->field_4E].hp == 0 + && !(gBattleStruct->unkDF & gBitTable[gBattlePartyID[gBattleStruct->field_4E]]) + && !(gAbsentBankFlags & gBitTable[gBattleStruct->field_4E])) + { + b_call_bc_move_exec(gUnknown_082DA7C4); + gBattleStruct->field_4D = 2; + return TRUE; + } + } while (++gBattleStruct->field_4E != gNoOfAllBanks); + gBattleStruct->field_4D = 3; + break; + case 2: + sub_803F9EC(gBank1); + if (++gBattleStruct->field_4E == gNoOfAllBanks) + gBattleStruct->field_4D = 3; + else + gBattleStruct->field_4D = 1; + break; + case 3: + gBattleStruct->field_4E = 0; + gBattleStruct->field_4D++; + // fall through + case 4: + do + { + gBank1 = gBankTarget = gBattleStruct->field_4E; //or should banks be switched? + if (gBattleMons[gBattleStruct->field_4E].hp == 0 + && !(gAbsentBankFlags & gBitTable[gBattleStruct->field_4E])) + { + b_call_bc_move_exec(gUnknown_082DA7CD); + gBattleStruct->field_4D = 5; + return TRUE; + } + } while (++gBattleStruct->field_4E != gNoOfAllBanks); + gBattleStruct->field_4D = 6; + break; + case 5: + if (++gBattleStruct->field_4E == gNoOfAllBanks) + gBattleStruct->field_4D = 6; + else + gBattleStruct->field_4D = 4; + break; + case 6: + if (AbilityBattleEffects(9, 0, 0, 0, 0) || AbilityBattleEffects(0xB, 0, 0, 0, 0) || ItemBattleEffects(1, 0, 1) || AbilityBattleEffects(6, 0, 0, 0, 0)) + return TRUE; + gBattleStruct->field_4D++; + break; + case 7: + break; + } + } while (gBattleStruct->field_4D != sub_8041728_MAX_CASE); + return FALSE; +} + +void b_clear_atk_up_if_hit_flag_unless_enraged(void) +{ + int i; + for (i = 0; i < gNoOfAllBanks; i++) + { + if ((gBattleMons[i].status2 & STATUS2_RAGE) && gChosenMovesByBanks[i] != MOVE_RAGE) + gBattleMons[i].status2 &= ~(STATUS2_RAGE); + } +} + +#define ATKCANCELLER_MAX_CASE 14 + +u8 AtkCanceller_UnableToUseMove(void) +{ + u8 effect = 0; + s32* bideDmg = &gBattleScripting.bideDmg; + do + { + switch (gBattleStruct->atkCancellerTracker) + { + case 0: // flags clear + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_DESTINY_BOND); + gStatuses3[gBankAttacker] &= ~(STATUS3_GRUDGE); + gBattleStruct->atkCancellerTracker++; + break; + case 1: // check being asleep + if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) + { + if (UproarWakeUpCheck(gBankAttacker)) + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + b_movescr_stack_push_cursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; + effect = 2; + } + else + { + u8 toSub; + if (gBattleMons[gBankAttacker].ability == ABILITY_EARLY_BIRD) + toSub = 2; + else + toSub = 1; + if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) < toSub) + gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); + else + gBattleMons[gBankAttacker].status1 -= toSub; + if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) + { + if (gCurrentMove != MOVE_SNORE && gCurrentMove != MOVE_SLEEP_TALK) + { + gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 2; + } + } + else + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + b_movescr_stack_push_cursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; + effect = 2; + } + } + } + gBattleStruct->atkCancellerTracker++; + break; + case 2: // check being frozen + if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE) + { + if (Random() % 5) + { + if (gBattleMoves[gCurrentMove].effect != EFFECT_THAW_HIT) // unfreezing via a move effect happens in case 13 + { + gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen; + gHitMarker |= HITMARKER_NO_ATTACKSTRING; + } + else + { + gBattleStruct->atkCancellerTracker++; + break; + } + } + else // unfreeze + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + effect = 2; + } + gBattleStruct->atkCancellerTracker++; + break; + case 3: // truant + if (gBattleMons[gBankAttacker].ability == ABILITY_TRUANT && gDisableStructs[gBankAttacker].truantCounter) + { + CancelMultiTurnMoves(gBankAttacker); + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; + gBattleMoveFlags |= MOVESTATUS_MISSED; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 4: // recharge + if (gBattleMons[gBankAttacker].status2 & STATUS2_RECHARGE) + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_RECHARGE); + gDisableStructs[gBankAttacker].rechargeCounter = 0; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 5: // flinch + if (gBattleMons[gBankAttacker].status2 & STATUS2_FLINCHED) + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_FLINCHED); + gProtectStructs[gBankAttacker].flinchImmobility = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 6: // disabled move + if (gDisableStructs[gBankAttacker].disabledMove == gCurrentMove && gDisableStructs[gBankAttacker].disabledMove != 0) + { + gProtectStructs[gBankAttacker].usedDisabledMove = 1; + gBattleScripting.bank = gBankAttacker; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 7: // taunt + if (gDisableStructs[gBankAttacker].tauntTimer1 && gBattleMoves[gCurrentMove].power == 0) + { + gProtectStructs[gBankAttacker].usedTauntedMove = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 8: // imprisoned + if (IsImprisoned(gBankAttacker, gCurrentMove)) + { + gProtectStructs[gBankAttacker].usedImprisionedMove = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 9: // confusion + if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION) + { + gBattleMons[gBankAttacker].status2--; + if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION) + { + if (Random() & 1) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + b_movescr_stack_push_cursor(); + } + else // confusion dmg + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBankTarget = gBankAttacker; + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankAttacker], MOVE_POUND, 0, 40, 0, gBankAttacker, gBankAttacker); + gProtectStructs[gBankAttacker].confusionSelfDmg = 1; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + } + gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused; + } + else // snapped out of confusion + { + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore; + } + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 10: // paralysis + if ((gBattleMons[gBankAttacker].status1 & STATUS_PARALYSIS) && (Random() % 4) == 0) + { + gProtectStructs[gBankAttacker].prlzImmobility = 1; + // This is removed in Emerald for some reason + //CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 11: // infatuation + if (gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) + { + gBattleScripting.bank = CountTrailingZeroBits((gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) >> 0x10); + if (Random() & 1) + b_movescr_stack_push_cursor(); + else + { + b_movescr_stack_push(BattleScript_MoveUsedIsParalyzedCantAttack); + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gProtectStructs[gBankAttacker].loveImmobility = 1; + CancelMultiTurnMoves(gBankAttacker); + } + gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 12: // bide + if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE) + { + gBattleMons[gBankAttacker].status2 -= 0x100; + if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE) + gBattlescriptCurrInstr = BattleScript_BideStoringEnergy; + else + { + // This is removed in Emerald for some reason + //gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS); + if (gTakenDmg[gBankAttacker]) + { + gCurrentMove = MOVE_BIDE; + *bideDmg = gTakenDmg[gBankAttacker] * 2; + gBankTarget = gTakenDmgBanks[gBankAttacker]; + if (gAbsentBankFlags & gBitTable[gBankTarget]) + gBankTarget = GetMoveTarget(MOVE_BIDE, 1); + gBattlescriptCurrInstr = BattleScript_BideAttack; + } + else + gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack; + } + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 13: // move thawing + if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE) + { + if (gBattleMoves[gCurrentMove].effect == EFFECT_THAW_HIT) + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + effect = 2; + } + gBattleStruct->atkCancellerTracker++; + break; + case 14: // last case + break; + } + + } while (gBattleStruct->atkCancellerTracker != ATKCANCELLER_MAX_CASE && effect == 0); + + if (effect == 2) + { + gActiveBank = gBankAttacker; + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + } + return effect; +} diff --git a/src/battle_ai.c b/src/battle_ai.c index 76bf4156d..3b696b84e 100644 --- a/src/battle_ai.c +++ b/src/battle_ai.c @@ -87,7 +87,7 @@ static u8 BattleAI_ChooseMoveOrAction_Singles(void); static u8 BattleAI_ChooseMoveOrAction_Doubles(void); static void RecordLastUsedMoveByTarget(void); static void BattleAI_DoAIProcessing(void); -static void AIStackPushVar(u8 *); +static void AIStackPushVar(const u8 *); static bool8 AIStackPop(void); static void BattleAICmd_if_random_less_than(void); @@ -192,7 +192,7 @@ static void BattleAICmd_if_holds_item(void); // ewram -EWRAM_DATA u8 *gAIScriptPtr = NULL; +EWRAM_DATA const u8 *gAIScriptPtr = NULL; EWRAM_DATA static u8 sBank_AI = 0; // const rom data @@ -2902,7 +2902,7 @@ static void BattleAICmd_if_flash_fired(void) gAIScriptPtr += 6; } -static void AIStackPushVar(u8 *var) +static void AIStackPushVar(const u8 *var) { gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size++] = var; } diff --git a/src/hall_of_fame.c b/src/hall_of_fame.c new file mode 100644 index 000000000..d9fd40b84 --- /dev/null +++ b/src/hall_of_fame.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "hall_of_fame.h" + + -- cgit v1.2.3 From 6439551e1a1effa0282145627aaef934a1b4b797 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 08:20:42 -0400 Subject: Another chunk of functions, including some expanded from macros --- src/field_map_obj.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index cd840ba70..bffce24ac 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4194,3 +4194,64 @@ bool8 npc_obj_ministep_stop_on_arrival(struct MapObject *mapObject, struct Sprit } return FALSE; } + +void sub_8093AF0(struct MapObject *mapObject, struct Sprite *sprite, u8 direction) +{ + s16 x; + s16 y; + + x = mapObject->coords2.x; + y = mapObject->coords2.y; + FieldObjectSetDirection(mapObject, direction); + MoveCoords(direction, &x, &y); + npc_coords_shift(mapObject, x, y); + sub_80976DC(sprite, direction); + sprite->animPaused = FALSE; + mapObject->mapobj_bit_2 = TRUE; + sprite->data2 = 1; +} + +void sub_8093B60(struct MapObject *mapObject, struct Sprite *sprite, u8 direction) +{ + sub_8093AF0(mapObject, sprite, direction); + npc_apply_anim_looping(mapObject, sprite, get_go_image_anim_num(mapObject->mapobj_unk_18)); +} + +bool8 an_walk_any_2(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_80976EC(sprite)) + { + npc_coords_shift_still(mapObject); + mapObject->mapobj_bit_3 = TRUE; + sprite->animPaused = TRUE; + return TRUE; + } + return FALSE; +} + +#define an_walk_any_2_macro(name, dirn) \ +static bool8 name##_2(struct MapObject *, struct Sprite *);\ +bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + sub_8093B60(mapObject, sprite, dirn);\ + return name##_2(mapObject, sprite);\ +}\ +static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + if (an_walk_any_2(mapObject, sprite))\ + {\ + sprite->data2 = 2;\ + return TRUE;\ + }\ + return FALSE;\ +} + +an_walk_any_2_macro(sub_8093BC4, 7) +an_walk_any_2_macro(sub_8093C04, 8) +an_walk_any_2_macro(sub_8093C44, 5) +an_walk_any_2_macro(sub_8093C84, 6) +an_walk_any_2_macro(sub_8093CC4, 1) +an_walk_any_2_macro(sub_8093D04, 2) +an_walk_any_2_macro(sub_8093D44, 3) +an_walk_any_2_macro(sub_8093D84, 4) + -- cgit v1.2.3 From 501baffc48a505231e650f67576a844f4d0d74c9 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 08:26:27 -0400 Subject: Yet another chunk of highly similar functions --- src/field_map_obj.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index bffce24ac..648f6bd46 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4246,6 +4246,23 @@ static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ return FALSE;\ } +#define npc_obj_ministep_stop_on_arrival_macro(name, dirn, speed) \ +static bool8 name##_2(struct MapObject *, struct Sprite *);\ +bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + do_go_anim(mapObject, sprite, dirn, speed);\ + return name##_2(mapObject, sprite);\ +}\ +static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))\ + {\ + sprite->data2 = 2;\ + return TRUE;\ + }\ + return FALSE;\ +} + an_walk_any_2_macro(sub_8093BC4, 7) an_walk_any_2_macro(sub_8093C04, 8) an_walk_any_2_macro(sub_8093C44, 5) @@ -4254,4 +4271,12 @@ an_walk_any_2_macro(sub_8093CC4, 1) an_walk_any_2_macro(sub_8093D04, 2) an_walk_any_2_macro(sub_8093D44, 3) an_walk_any_2_macro(sub_8093D84, 4) +npc_obj_ministep_stop_on_arrival_macro(sub_8093DC4, 7, 0) +npc_obj_ministep_stop_on_arrival_macro(sub_8093E04, 8, 0) +npc_obj_ministep_stop_on_arrival_macro(sub_8093E44, 5, 0) +npc_obj_ministep_stop_on_arrival_macro(sub_8093E84, 6, 0) +npc_obj_ministep_stop_on_arrival_macro(sub_8093EC4, 1, 0) +npc_obj_ministep_stop_on_arrival_macro(sub_8093F04, 2, 0) +npc_obj_ministep_stop_on_arrival_macro(sub_8093F44, 3, 0) +npc_obj_ministep_stop_on_arrival_macro(sub_8093F84, 4, 0) -- cgit v1.2.3 From ed6e95fbd72e1619fda2de6b96d336f37ef8b300 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 08:30:36 -0400 Subject: Avoid using duplicate macros --- src/field_map_obj.c | 55 ++++++++++++++++++----------------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 648f6bd46..9446f5c67 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4229,16 +4229,16 @@ bool8 an_walk_any_2(struct MapObject *mapObject, struct Sprite *sprite) return FALSE; } -#define an_walk_any_2_macro(name, dirn) \ +#define an_walk_any_2_macro(name, fn1, fn2, ...) \ static bool8 name##_2(struct MapObject *, struct Sprite *);\ bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ {\ - sub_8093B60(mapObject, sprite, dirn);\ + fn1(mapObject, sprite, __VA_ARGS__);\ return name##_2(mapObject, sprite);\ }\ static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ {\ - if (an_walk_any_2(mapObject, sprite))\ + if (fn2(mapObject, sprite))\ {\ sprite->data2 = 2;\ return TRUE;\ @@ -4246,37 +4246,20 @@ static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ return FALSE;\ } -#define npc_obj_ministep_stop_on_arrival_macro(name, dirn, speed) \ -static bool8 name##_2(struct MapObject *, struct Sprite *);\ -bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ -{\ - do_go_anim(mapObject, sprite, dirn, speed);\ - return name##_2(mapObject, sprite);\ -}\ -static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ -{\ - if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))\ - {\ - sprite->data2 = 2;\ - return TRUE;\ - }\ - return FALSE;\ -} - -an_walk_any_2_macro(sub_8093BC4, 7) -an_walk_any_2_macro(sub_8093C04, 8) -an_walk_any_2_macro(sub_8093C44, 5) -an_walk_any_2_macro(sub_8093C84, 6) -an_walk_any_2_macro(sub_8093CC4, 1) -an_walk_any_2_macro(sub_8093D04, 2) -an_walk_any_2_macro(sub_8093D44, 3) -an_walk_any_2_macro(sub_8093D84, 4) -npc_obj_ministep_stop_on_arrival_macro(sub_8093DC4, 7, 0) -npc_obj_ministep_stop_on_arrival_macro(sub_8093E04, 8, 0) -npc_obj_ministep_stop_on_arrival_macro(sub_8093E44, 5, 0) -npc_obj_ministep_stop_on_arrival_macro(sub_8093E84, 6, 0) -npc_obj_ministep_stop_on_arrival_macro(sub_8093EC4, 1, 0) -npc_obj_ministep_stop_on_arrival_macro(sub_8093F04, 2, 0) -npc_obj_ministep_stop_on_arrival_macro(sub_8093F44, 3, 0) -npc_obj_ministep_stop_on_arrival_macro(sub_8093F84, 4, 0) +an_walk_any_2_macro(sub_8093BC4, sub_8093B60, an_walk_any_2, 7) +an_walk_any_2_macro(sub_8093C04, sub_8093B60, an_walk_any_2, 8) +an_walk_any_2_macro(sub_8093C44, sub_8093B60, an_walk_any_2, 5) +an_walk_any_2_macro(sub_8093C84, sub_8093B60, an_walk_any_2, 6) +an_walk_any_2_macro(sub_8093CC4, sub_8093B60, an_walk_any_2, 1) +an_walk_any_2_macro(sub_8093D04, sub_8093B60, an_walk_any_2, 2) +an_walk_any_2_macro(sub_8093D44, sub_8093B60, an_walk_any_2, 3) +an_walk_any_2_macro(sub_8093D84, sub_8093B60, an_walk_any_2, 4) +an_walk_any_2_macro(sub_8093DC4, do_go_anim, npc_obj_ministep_stop_on_arrival, 7, 0) +an_walk_any_2_macro(sub_8093E04, do_go_anim, npc_obj_ministep_stop_on_arrival, 8, 0) +an_walk_any_2_macro(sub_8093E44, do_go_anim, npc_obj_ministep_stop_on_arrival, 5, 0) +an_walk_any_2_macro(sub_8093E84, do_go_anim, npc_obj_ministep_stop_on_arrival, 6, 0) +an_walk_any_2_macro(sub_8093EC4, do_go_anim, npc_obj_ministep_stop_on_arrival, 1, 0) +an_walk_any_2_macro(sub_8093F04, do_go_anim, npc_obj_ministep_stop_on_arrival, 2, 0) +an_walk_any_2_macro(sub_8093F44, do_go_anim, npc_obj_ministep_stop_on_arrival, 3, 0) +an_walk_any_2_macro(sub_8093F84, do_go_anim, npc_obj_ministep_stop_on_arrival, 4, 0) -- cgit v1.2.3 From bf9a00250ba8f3d986b4829c0728ba620b58ec1c Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 08:38:00 -0400 Subject: maybe_shadow_1 which may or may not be a shadow --- src/field_map_obj.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 9446f5c67..5852f220c 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4263,3 +4263,28 @@ an_walk_any_2_macro(sub_8093F04, do_go_anim, npc_obj_ministep_stop_on_arrival, 2 an_walk_any_2_macro(sub_8093F44, do_go_anim, npc_obj_ministep_stop_on_arrival, 3, 0) an_walk_any_2_macro(sub_8093F84, do_go_anim, npc_obj_ministep_stop_on_arrival, 4, 0) +void sub_8093FC4(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 speed, u8 a5) +{ + s16 displacements[ARRAY_COUNT(gUnknown_0850DFBC)]; + s16 x; + s16 y; + + memcpy(displacements, gUnknown_0850DFBC, sizeof gUnknown_0850DFBC); + x = 0; + y = 0; + FieldObjectSetDirection(mapObject, direction); + sub_8092F88(direction, &x, &y, displacements[speed], displacements[speed]); + npc_coords_shift(mapObject, mapObject->coords2.x + x, mapObject->coords2.y + y); + sub_809783C(sprite, direction, speed, a5); + sprite->data2 = 1; + sprite->animPaused = 0; + mapObject->mapobj_bit_2 = 1; + mapObject->mapobj_bit_4 = 1; +} + +void maybe_shadow_1(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 speed, u8 a4) +{ + sub_8093FC4(mapObject, sprite, direction, speed, a4); + npc_apply_anim_looping(mapObject, sprite, get_go_image_anim_num(mapObject->mapobj_unk_18)); + DoShadowFieldEffect(mapObject); +} -- cgit v1.2.3 From 8ee004b9b16f621e2ea9d4dffe5cfb34d3a1c38a Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 08:45:24 -0400 Subject: sub_80940C4 which may or may not be a meme --- src/field_map_obj.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 5852f220c..3e3bbfa6f 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4288,3 +4288,31 @@ void maybe_shadow_1(struct MapObject *mapObject, struct Sprite *sprite, u8 direc npc_apply_anim_looping(mapObject, sprite, get_go_image_anim_num(mapObject->mapobj_unk_18)); DoShadowFieldEffect(mapObject); } + +u8 sub_80940C4(struct MapObject *mapObject, struct Sprite *sprite, u8 callback(struct Sprite *)) +{ + s16 displacements[ARRAY_COUNT(gUnknown_0850DFC2)]; + s16 x; + s16 y; + u8 result; + + memcpy(displacements, gUnknown_0850DFC2, sizeof gUnknown_0850DFC2); + result = callback(sprite); + if (result == 1 && displacements[sprite->data4] != 0) + { + x = 0; + y = 0; + sub_8092F88(mapObject->placeholder18, &x, &y, displacements[sprite->data4], displacements[sprite->data4]); + npc_coords_shift(mapObject, mapObject->coords2.x + x, mapObject->coords2.y + y); + mapObject->mapobj_bit_2 = TRUE; + mapObject->mapobj_bit_4 = TRUE; + } + else if (result == 0xFF) + { + npc_coords_shift_still(mapObject); + mapObject->mapobj_bit_3 = TRUE; + mapObject->mapobj_bit_5 = TRUE; + sprite->animPaused = TRUE; + } + return result; +} -- cgit v1.2.3 From c7592bc87c4b0f7007817784025046c304ca43c5 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sun, 17 Sep 2017 15:19:15 +0200 Subject: finish porting cam's port --- src/battle_3.c | 4072 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 4055 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index 34e45ca74..09c401a5c 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -13,6 +13,7 @@ #include "text.h" #include "string_util.h" #include "battle_message.h" +#include "battle_ai.h" extern const u8* gBattlescriptCurrInstr; extern const u8* gUnknown_02024220[BATTLE_BANKS_COUNT]; @@ -45,6 +46,7 @@ extern u16 gChosenMovesByBanks[]; extern u8 gBattleMoveFlags; extern s32 gTakenDmg[BATTLE_BANKS_COUNT]; extern u8 gTakenDmgBanks[BATTLE_BANKS_COUNT]; +extern u8 gLastUsedAbility; extern const struct BattleMove gBattleMoves[]; @@ -107,6 +109,37 @@ extern const u8 BattleScript_MoveUsedIsInLove[]; extern const u8 BattleScript_BideStoringEnergy[]; extern const u8 BattleScript_BideAttack[]; extern const u8 BattleScript_BideNoEnergyToAttack[]; +extern const u8 gUnknown_082DACE7[]; +extern const u8 BattleScript_DrizzleActivates[]; +extern const u8 BattleScript_SandstreamActivates[]; +extern const u8 BattleScript_DroughtActivates[]; +extern const u8 BattleScript_CastformChange[]; +extern const u8 BattleScript_RainDishActivates[]; +extern const u8 BattleScript_ShedSkinActivates[]; +extern const u8 BattleScript_SpeedBoostActivates[]; +extern const u8 BattleScript_SoundproofProtected[]; +extern const u8 BattleScript_MoveHPDrain[]; +extern const u8 BattleScript_MoveHPDrain_PPLoss[]; +extern const u8 BattleScript_FlashFireBoost[]; +extern const u8 BattleScript_FlashFireBoost_PPLoss[]; +extern const u8 BattleScript_ColorChangeActivates[]; +extern const u8 BattleScript_RoughSkinActivates[]; +extern const u8 BattleScript_ApplySecondaryEffect[]; +extern const u8 BattleScript_CuteCharmActivates[]; +extern const u8 gUnknown_082DB68C[]; +extern const u8 BattleScript_SynchronizeActivates[]; +extern const u8 gUnknown_082DB4B8[]; +extern const u8 gUnknown_082DB4C1[]; +extern const u8 BattleScript_TraceActivates[]; + +extern const u8 gStatusConditionString_PoisonJpn[]; +extern const u8 gStatusConditionString_SleepJpn[]; +extern const u8 gStatusConditionString_ParalysisJpn[]; +extern const u8 gStatusConditionString_BurnJpn[]; +extern const u8 gStatusConditionString_IceJpn[]; +extern const u8 gStatusConditionString_ConfusionJpn[]; +extern const u8 gStatusConditionString_LoveJpn[]; +extern const u16 gSoundMovesTable[]; extern void CancelMultiTurnMoves(u8 bank); extern u8 b_first_side(u8, u8, u8); @@ -122,10 +155,15 @@ extern u8 GetBankIdentity(u8); extern void sub_803F9EC(); extern bool8 sub_80423F4(u8 bank, u8, u8); extern s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideFlags, u16 powerOverride, u8 typeOverride, u8 bankAtk, u8 bankDef); +extern u8 GetBankByPlayerAI(u8); +extern u8 sub_806D864(u8); +extern u8 sub_806D82C(u8); +extern u8 weather_get_current(void); u8 IsImprisoned(u8 bank, u16 move); u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn); u8 GetMoveTarget(u16 move, u8 useMoveTarget); +void b_push_move_exec(const u8* BS_ptr); void b_movescr_stack_push(const u8* bsPtr) { @@ -916,19 +954,19 @@ bool8 sub_8041364(void) { gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20); - switch (gBattleStruct->unk1A0) + switch (gBattleStruct->field_1A0) { case 0: - while (gBattleStruct->unk1A1 < gNoOfAllBanks) + while (gBattleStruct->field_1A1 < gNoOfAllBanks) { - gActiveBank = gBattleStruct->unk1A1; + gActiveBank = gBattleStruct->field_1A1; if (gAbsentBankFlags & gBitTable[gActiveBank]) { - gBattleStruct->unk1A1++; + gBattleStruct->field_1A1++; continue; } - gBattleStruct->unk1A1++; + gBattleStruct->field_1A1++; if (gWishFutureKnock.futureSightCounter[gActiveBank] != 0 && --gWishFutureKnock.futureSightCounter[gActiveBank] == 0 && gBattleMons[gActiveBank].hp != 0) @@ -959,21 +997,21 @@ bool8 sub_8041364(void) } // Why do I have to keep doing this to match? { - u8* var = &gBattleStruct->unk1A0; + u8* var = &gBattleStruct->field_1A0; *var = 1; - gBattleStruct->unk1A1 = 0; + gBattleStruct->field_1A1 = 0; } // fall through case 1: - while (gBattleStruct->unk1A1 < gNoOfAllBanks) + while (gBattleStruct->field_1A1 < gNoOfAllBanks) { - gActiveBank = gBankAttacker = gTurnOrder[gBattleStruct->unk1A1]; + gActiveBank = gBankAttacker = gTurnOrder[gBattleStruct->field_1A1]; if (gAbsentBankFlags & gBitTable[gActiveBank]) { - gBattleStruct->unk1A1++; + gBattleStruct->field_1A1++; continue; } - gBattleStruct->unk1A1++; + gBattleStruct->field_1A1++; if (gStatuses3[gActiveBank] & STATUS3_PERISH_SONG) { gBattleTextBuff1[0] = 0xFD; @@ -999,14 +1037,14 @@ bool8 sub_8041364(void) } // Hm... { - u8* var = &gBattleStruct->unk1A0; + u8* var = &gBattleStruct->field_1A0; *var = 2; - gBattleStruct->unk1A1 = 0; + gBattleStruct->field_1A1 = 0; } // fall through case 2: if ((gBattleTypeFlags & BATTLE_TYPE_ARENA) - && gBattleStruct->unkDA == 2 + && gBattleStruct->field_DA == 2 && gBattleMons[0].hp != 0 && gBattleMons[1].hp != 0) { s32 i; @@ -1016,7 +1054,7 @@ bool8 sub_8041364(void) gBattlescriptCurrInstr = gUnknown_082DB8F3; b_call_bc_move_exec(gUnknown_082DB8F3); - gBattleStruct->unk1A0++; + gBattleStruct->field_1A0++; return 1; } break; @@ -1052,7 +1090,7 @@ bool8 sub_8041728(void) { gBank1 = gBankTarget = gBattleStruct->field_4E; if (gBattleMons[gBattleStruct->field_4E].hp == 0 - && !(gBattleStruct->unkDF & gBitTable[gBattlePartyID[gBattleStruct->field_4E]]) + && !(gBattleStruct->field_DF & gBitTable[gBattlePartyID[gBattleStruct->field_4E]]) && !(gAbsentBankFlags & gBitTable[gBattleStruct->field_4E])) { b_call_bc_move_exec(gUnknown_082DA7C4); @@ -1094,7 +1132,7 @@ bool8 sub_8041728(void) gBattleStruct->field_4D = 4; break; case 6: - if (AbilityBattleEffects(9, 0, 0, 0, 0) || AbilityBattleEffects(0xB, 0, 0, 0, 0) || ItemBattleEffects(1, 0, 1) || AbilityBattleEffects(6, 0, 0, 0, 0)) + if (AbilityBattleEffects(ABILITYEFFECT_INTIMIDATE1, 0, 0, 0, 0) || AbilityBattleEffects(ABILITYEFFECT_TRACE, 0, 0, 0, 0) || ItemBattleEffects(1, 0, 1) || AbilityBattleEffects(ABILITYEFFECT_FORECAST, 0, 0, 0, 0)) return TRUE; gBattleStruct->field_4D++; break; @@ -1385,3 +1423,4003 @@ u8 AtkCanceller_UnableToUseMove(void) } return effect; } + +bool8 sub_80423F4(u8 bank, u8 r1, u8 r2) +{ + struct Pokemon* party; + u8 r7; + u8 r6; + s32 i; + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + return FALSE; + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) + { + if (GetBankSide(bank) == 0) + party = gPlayerParty; + else + party = gEnemyParty; + r6 = ((bank & 2) >> 1); + for (i = r6 * 3; i < r6 * 3 + 3; i++) + { + if (GetMonData(&party[i], MON_DATA_HP) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) + break; + } + return (i == r6 * 3 + 3); + } + else if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (gBattleTypeFlags & BATTLE_TYPE_x800000) + { + if (GetBankSide(bank) == SIDE_PLAYER) + { + party = gPlayerParty; + r7 = sub_806D864(bank); + r6 = sub_806D82C(r7); + } + else + { + // FIXME: Compiler insists on moving r4 into r1 before doing the eor + #ifndef NONMATCHING + register u32 var asm("r1"); + #else + u32 var; + #endif // NONMATCHING + + party = gEnemyParty; + var = bank ^ 1; + r6 = (var == 0) ? 0 : 1; + } + } + else + { + r7 = sub_806D864(bank); + if (GetBankSide(bank) == 0) + party = gPlayerParty; + else + party = gEnemyParty; + r6 = sub_806D82C(r7); + } + for (i = r6 * 3; i < r6 * 3 + 3; i++) + { + if (GetMonData(&party[i], MON_DATA_HP) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) + break; + } + return (i == r6 * 3 + 3); + } + else if ((gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) && GetBankSide(bank) == 1) + { + party = gEnemyParty; + + if (bank == 1) + r6 = 0; + else + r6 = 3; + for (i = r6; i < r6 + 3; i++) + { + if (GetMonData(&party[i], MON_DATA_HP) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) + break; + } + return (i == r6 + 3); + } + else + { + if (GetBankSide(bank) == 1) + { + r7 = GetBankByPlayerAI(1); + r6 = GetBankByPlayerAI(3); + party = gEnemyParty; + } + else + { + r7 = GetBankByPlayerAI(0); + r6 = GetBankByPlayerAI(2); + party = gPlayerParty; + } + if (r1 == 6) + r1 = gBattlePartyID[r7]; + if (r2 == 6) + r2 = gBattlePartyID[r6]; + for (i = 0; i < 6; i++) + { + if (GetMonData(&party[i], MON_DATA_HP) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG + // FIXME: Using index[array] instead of array[index] is BAD! + && i != r1 && i != r2 && i != r7[gBattleStruct->field_5C] && i != r6[gBattleStruct->field_5C]) + break; + } + return (i == 6); + } +} + +enum +{ + CASTFORM_NO_CHANGE, //0 + CASTFORM_TO_NORMAL, //1 + CASTFORM_TO_FIRE, //2 + CASTFORM_TO_WATER, //3 + CASTFORM_TO_ICE, //4 +}; + +u8 CastformDataTypeChange(u8 bank) +{ + u8 formChange = 0; + if (gBattleMons[bank].species != SPECIES_CASTFORM || gBattleMons[bank].ability != ABILITY_FORECAST || gBattleMons[bank].hp == 0) + return CASTFORM_NO_CHANGE; + if (!WEATHER_HAS_EFFECT && gBattleMons[bank].type1 != TYPE_NORMAL && gBattleMons[bank].type2 != TYPE_NORMAL) + { + gBattleMons[bank].type1 = TYPE_NORMAL; + gBattleMons[bank].type2 = TYPE_NORMAL; + return CASTFORM_TO_NORMAL; + } + if (!WEATHER_HAS_EFFECT) + return CASTFORM_NO_CHANGE; + if (!(gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SUN_ANY | WEATHER_HAIL)) && gBattleMons[bank].type1 != TYPE_NORMAL && gBattleMons[bank].type2 != TYPE_NORMAL) + { + gBattleMons[bank].type1 = TYPE_NORMAL; + gBattleMons[bank].type2 = TYPE_NORMAL; + formChange = CASTFORM_TO_NORMAL; + } + if (gBattleWeather & WEATHER_SUN_ANY && gBattleMons[bank].type1 != TYPE_FIRE && gBattleMons[bank].type2 != TYPE_FIRE) + { + gBattleMons[bank].type1 = TYPE_FIRE; + gBattleMons[bank].type2 = TYPE_FIRE; + formChange = CASTFORM_TO_FIRE; + } + if (gBattleWeather & WEATHER_RAIN_ANY && gBattleMons[bank].type1 != TYPE_WATER && gBattleMons[bank].type2 != TYPE_WATER) + { + gBattleMons[bank].type1 = TYPE_WATER; + gBattleMons[bank].type2 = TYPE_WATER; + formChange = CASTFORM_TO_WATER; + } + if (gBattleWeather & WEATHER_HAIL && gBattleMons[bank].type1 != TYPE_ICE && gBattleMons[bank].type2 != TYPE_ICE) + { + gBattleMons[bank].type1 = TYPE_ICE; + gBattleMons[bank].type2 = TYPE_ICE; + formChange = CASTFORM_TO_ICE; + } + return formChange; +} + +// We meet again, ABE. +#ifdef NONMATCHING +u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) +{ + u8 effect = 0; + struct Pokemon* pokeAtk; + struct Pokemon* pokeDef; + u16 speciesAtk; + u16 speciesDef; + u32 pidAtk; + u32 pidDef; + + if (gBankAttacker >= gNoOfAllBanks) + gBankAttacker = bank; + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + pokeAtk = &gPlayerParty[gBattlePartyID[gBankAttacker]]; + else + pokeAtk = &gEnemyParty[gBattlePartyID[gBankAttacker]]; + + if (gBankTarget >= gNoOfAllBanks) + gBankTarget = bank; + if (GetBankSide(gBankTarget) == SIDE_PLAYER) + pokeDef = &gPlayerParty[gBattlePartyID[gBankTarget]]; + else + pokeDef = &gEnemyParty[gBattlePartyID[gBankTarget]]; + + speciesAtk = GetMonData(pokeAtk, MON_DATA_SPECIES); + pidAtk = GetMonData(pokeAtk, MON_DATA_PERSONALITY); + + speciesDef = GetMonData(pokeDef, MON_DATA_SPECIES); + pidDef = GetMonData(pokeDef, MON_DATA_PERSONALITY); + + if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) // why isn't that check done at the beginning? + { + int i; // r4 + u16 move; + // Hmm... + #define moveType moveArg + //u16 moveType; + u8 side; + + if (special) + gLastUsedAbility = special; + else + gLastUsedAbility = gBattleMons[bank].ability; + + if (moveArg) + move = moveArg; + else + move = gCurrentMove; + + if (gBattleStruct->dynamicMoveType) + moveType = gBattleStruct->dynamicMoveType & 0x3F; + else + moveType = gBattleMoves[move].type; + + switch (caseID) + { + case ABILITYEFFECT_ON_SWITCHIN: // 0 + //_08042A18 + if (gBankAttacker >= gNoOfAllBanks) + gBankAttacker = bank; + switch (gLastUsedAbility) + { + case 0xFF: //weather from overworld + //_08042A86 + switch (weather_get_current()) + { + case 3: + case 5: + case 13: + if (!(gBattleWeather & WEATHER_RAIN_ANY)) + { + gBattleWeather = (WEATHER_RAIN_TEMPORARY | WEATHER_RAIN_PERMANENT); + gBattleScripting.animArg1 = 0xA; + gBattleScripting.bank = bank; + effect++; + } + break; + case 8: + if (!(gBattleWeather & WEATHER_SANDSTORM_ANY)) + { + gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY); + gBattleScripting.animArg1 = 0xC; + gBattleScripting.bank = bank; + effect++; + } + break; + case 12: + if (!(gBattleWeather & WEATHER_SUN_ANY)) + { + gBattleWeather = (WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY); + gBattleScripting.animArg1 = 0xB; + gBattleScripting.bank = bank; + effect++; + } + break; + } + if (effect) + { + gBattleCommunication[MULTISTRING_CHOOSER] = weather_get_current(); + b_push_move_exec(gUnknown_082DACE7); + } + break; + case ABILITY_DRIZZLE: + //_08042B78 + if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)) + { + gBattleWeather = (WEATHER_RAIN_PERMANENT | WEATHER_RAIN_TEMPORARY); + b_push_move_exec(BattleScript_DrizzleActivates); + gBattleScripting.bank = bank; + effect++; + } + break; + case ABILITY_SAND_STREAM: + //_08042BA8 + if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT)) + { + gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY); + b_push_move_exec(BattleScript_SandstreamActivates); + gBattleScripting.bank = bank; + effect++; + } + break; + case ABILITY_DROUGHT: + //_08042BD8 + if (!(gBattleWeather & WEATHER_SUN_PERMANENT)) + { + gBattleWeather = (WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY); + b_push_move_exec(BattleScript_DroughtActivates); + gBattleScripting.bank = bank; + effect++; + } + break; + case ABILITY_INTIMIDATE: + //_08042C08 + if (!(gSpecialStatuses[bank].intimidatedPoke)) + { + gStatuses3[bank] |= STATUS3_INTIMIDATE_POKES; + gSpecialStatuses[bank].intimidatedPoke = 1; + } + break; + case ABILITY_FORECAST: + //_08042C3C + effect = CastformDataTypeChange(bank); + if (effect != 0) + { + b_push_move_exec(BattleScript_CastformChange); + gBattleScripting.bank = bank; + gBattleStruct->formToChangeInto = effect - 1; + } + break; + case ABILITY_TRACE: + if (!(gSpecialStatuses[bank].traced)) + { + gStatuses3[bank] |= STATUS3_TRACE; + gSpecialStatuses[bank].traced = 1; + } + break; + case ABILITY_CLOUD_NINE: + case ABILITY_AIR_LOCK: + { + u8 i; + + for (i = 0; i < gNoOfAllBanks; i++) + { + // TODO: i should be in r6 here + //asm("":::"r4","r5"); + effect = CastformDataTypeChange(i); + if (effect != 0) + { + b_push_move_exec(BattleScript_CastformChange); + gBattleScripting.bank = i; + gBattleStruct->formToChangeInto = effect - 1; + break; + } + } + } + break; + } + break; + case ABILITYEFFECT_ENDTURN: // 1 + //_08042CDC + if (gBattleMons[bank].hp != 0) + { + gBankAttacker = bank; + switch (gLastUsedAbility) + { + case ABILITY_RAIN_DISH: + //_08042D22 + if (WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY) + && gBattleMons[bank].maxHP > gBattleMons[bank].hp) + { + gLastUsedAbility = ABILITY_RAIN_DISH; //why + b_push_move_exec(BattleScript_RainDishActivates); + gBattleMoveDamage = gBattleMons[bank].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + effect++; + } + break; + case ABILITY_SHED_SKIN: + //_08042DA0 + if ((gBattleMons[bank].status1 & STATUS_ANY) && (Random() % 3) == 0) + { + if (gBattleMons[bank].status1 & (STATUS_POISON | STATUS_TOXIC_POISON)) + StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); + if (gBattleMons[bank].status1 & STATUS_SLEEP) + StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); + if (gBattleMons[bank].status1 & STATUS_BURN) + StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); + if (gBattleMons[bank].status1 & STATUS_FREEZE) + StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); + gBattleMons[bank].status1 = 0; + gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); // fix nighmare glitch + gBattleScripting.bank = gActiveBank = bank; + b_push_move_exec(BattleScript_ShedSkinActivates); + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); + MarkBufferBankForExecution(gActiveBank); + effect++; + } + break; + case ABILITY_SPEED_BOOST: + //_08042E84 + if (gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC && gDisableStructs[bank].isFirstTurn != 2) + { + gBattleMons[bank].statStages[STAT_STAGE_SPEED]++; + gBattleScripting.animArg1 = 0x11; + gBattleScripting.animArg2 = 0; + b_push_move_exec(BattleScript_SpeedBoostActivates); + gBattleScripting.bank = bank; + effect++; + } + break; + case ABILITY_TRUANT: + gDisableStructs[gBankAttacker].truantCounter ^= 1; + break; + } + } + break; + case ABILITYEFFECT_MOVES_BLOCK: // 2 + //_08042EF8 + if (gLastUsedAbility == ABILITY_SOUNDPROOF) + { + for (i = 0; gSoundMovesTable[i] != 0xFFFF; i++) + { + if (gSoundMovesTable[i] == move) + break; + } + if (gSoundMovesTable[i] != 0xFFFF) + { + if (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS) + gHitMarker |= HITMARKER_NO_PPDEDUCT; + gBattlescriptCurrInstr = BattleScript_SoundproofProtected; + effect = 1; + } + } + break; + case ABILITYEFFECT_ABSORBING: // 3 + if (move) + { + switch (gLastUsedAbility) + { + case ABILITY_VOLT_ABSORB: + if (moveType == TYPE_ELECTRIC && gBattleMoves[move].power != 0) + { + if (gProtectStructs[gBankAttacker].notFirstStrike) + gBattlescriptCurrInstr = BattleScript_MoveHPDrain; + else + gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss; + effect = 1; + } + break; + case ABILITY_WATER_ABSORB: + if (moveType == TYPE_WATER && gBattleMoves[move].power != 0) + { + if (gProtectStructs[gBankAttacker].notFirstStrike) + gBattlescriptCurrInstr = BattleScript_MoveHPDrain; + else + gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss; + effect = 1; + } + break; + case ABILITY_FLASH_FIRE: + //_0804305C + if (moveType == TYPE_FIRE && !(gBattleMons[bank].status1 & STATUS_FREEZE)) + { + if (!(gBattleResources->flags->flags[bank] & UNKNOWN_FLAG_FLASH_FIRE)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + if (gProtectStructs[gBankAttacker].notFirstStrike) + gBattlescriptCurrInstr = BattleScript_FlashFireBoost; + else + gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss; + gBattleResources->flags->flags[bank] |= UNKNOWN_FLAG_FLASH_FIRE; + effect = 2; + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + if (gProtectStructs[gBankAttacker].notFirstStrike) + gBattlescriptCurrInstr = BattleScript_FlashFireBoost; + else + gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss; + effect = 2; + } + } + break; + } + if (effect == 1) + { + if (gBattleMons[bank].maxHP == gBattleMons[bank].hp) + { + if ((gProtectStructs[gBankAttacker].notFirstStrike)) + gBattlescriptCurrInstr = BattleScript_MoveHPDrain; + else + gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss; + } + else + { + gBattleMoveDamage = gBattleMons[bank].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + } + } + } + break; + case ABILITYEFFECT_CONTACT: // 4 + //_080431AC + switch (gLastUsedAbility) + { + case ABILITY_COLOR_CHANGE: + //_08043288 + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT) + && move != MOVE_STRUGGLE + && gBattleMoves[move].power != 0 + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && gBattleMons[bank].type1 != moveType + && gBattleMons[bank].type2 != moveType + && gBattleMons[bank].hp != 0) + { + gBattleMons[bank].type1 = moveType; + gBattleMons[bank].type2 = moveType; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 3; + gBattleTextBuff1[2] = moveType; + gBattleTextBuff1[3] = 0xFF; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_ColorChangeActivates; + effect++; + } + break; + case ABILITY_ROUGH_SKIN: + //_08043350 + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)) + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_RoughSkinActivates; + effect++; + } + break; + case ABILITY_EFFECT_SPORE: + //_08043410 + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) + && (Random() % 10) == 0) + { + do + { + gBattleCommunication[MOVE_EFFECT_BYTE] = Random() & 3; + } while (gBattleCommunication[MOVE_EFFECT_BYTE] == 0); + if (gBattleCommunication[MOVE_EFFECT_BYTE] == 3) + gBattleCommunication[MOVE_EFFECT_BYTE] += 2; + gBattleCommunication[MOVE_EFFECT_BYTE] += 0x40; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + break; + case ABILITY_POISON_POINT: + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) + && (Random() % 3) == 0) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x42; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + break; + case ABILITY_STATIC: + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) + && (Random() % 3) == 0) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x45; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + break; + case ABILITY_FLAME_BODY: + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (Random() % 3) == 0) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x43; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + break; + case ABILITY_CUTE_CHARM: + //_0804379C + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && gBattleMons[gBankTarget].hp != 0 + && (Random() % 3) == 0 + && gBattleMons[gBankAttacker].ability != ABILITY_OBLIVIOUS + && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) + && !(gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) + && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != 0xFF + && GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) != 0xFF) + { + gBattleMons[gBankAttacker].status2 |= (gBitTable[gBankTarget] << 0x10); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_CuteCharmActivates; + effect++; + } + break; + } + break; + case ABILITYEFFECT_IMMUNITY: // 5 + { + #define i bank + for (i = 0; i < gNoOfAllBanks; i++) + { + switch (gBattleMons[i].ability) + { + case ABILITY_IMMUNITY: + if (gBattleMons[i].status1 & (STATUS_POISON | STATUS_TOXIC_POISON | 0xF00)) // TODO: what is 0xF00? + { + StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); + effect = 1; + } + break; + case ABILITY_OWN_TEMPO: + //_08043A7C + if (gBattleMons[i].status2 & STATUS2_CONFUSION) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); + effect = 2; + } + break; + case ABILITY_LIMBER: + if (gBattleMons[i].status1 & STATUS_PARALYSIS) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); + effect = 1; + } + break; + case ABILITY_INSOMNIA: + case ABILITY_VITAL_SPIRIT: + if (gBattleMons[i].status1 & STATUS_SLEEP) + { + gBattleMons[i].status2 &= ~(STATUS2_NIGHTMARE); + StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); + effect = 1; + } + break; + case ABILITY_WATER_VEIL: + if (gBattleMons[i].status1 & STATUS_BURN) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); + effect = 1; + } + break; + case ABILITY_MAGMA_ARMOR: + if (gBattleMons[i].status1 & STATUS_FREEZE) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); + effect = 1; + } + break; + case ABILITY_OBLIVIOUS: + //_08043B70 + if (gBattleMons[i].status2 & STATUS2_INFATUATION) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); + effect = 3; + } + break; + } + if (effect) + { + switch (effect) + { + case 1: // status cleared + gBattleMons[i].status1 = 0; + break; + case 2: // get rid of confusion + gBattleMons[i].status2 &= ~(STATUS2_CONFUSION); + break; + case 3: // get rid of infatuation + gBattleMons[i].status2 &= ~(STATUS2_INFATUATION); + break; + } + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = gUnknown_082DB68C; + gBattleScripting.bank = i; + gActiveBank = i; + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + return effect; + } + } + #undef i + } + break; + case ABILITYEFFECT_FORECAST: // 6 + { + #define i bank + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleMons[i].ability == ABILITY_FORECAST) + { + effect = CastformDataTypeChange(i); + if (effect) + { + b_push_move_exec(BattleScript_CastformChange); + gBattleScripting.bank = i; + gBattleStruct->formToChangeInto = effect - 1; + return effect; + } + } + } + #undef i + } + break; + case ABILITYEFFECT_SYNCHRONIZE: // 7 + //_08043CBC + if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT)) + { + gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); + gBattleStruct->synchronizeMoveEffect &= 0x3F; + if (gBattleStruct->synchronizeMoveEffect == 6) + gBattleStruct->synchronizeMoveEffect = 2; + gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleStruct->synchronizeMoveEffect + 0x40; + gBattleScripting.bank = gBankTarget; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_SynchronizeActivates; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + break; + case ABILITYEFFECT_ATK_SYNCHRONIZE: // 8 + if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT)) + { + gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); + gBattleStruct->synchronizeMoveEffect &= 0x3F; + if (gBattleStruct->synchronizeMoveEffect == 6) + gBattleStruct->synchronizeMoveEffect = 2; + gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleStruct->synchronizeMoveEffect; + gBattleScripting.bank = gBankAttacker; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_SynchronizeActivates; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + break; + case ABILITYEFFECT_INTIMIDATE1: // 9 + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleMons[i].ability == ABILITY_INTIMIDATE && gStatuses3[i] & STATUS3_INTIMIDATE_POKES) + { + gLastUsedAbility = ABILITY_INTIMIDATE; + gStatuses3[i] &= ~(STATUS3_INTIMIDATE_POKES); + b_push_move_exec(gUnknown_082DB4B8); + gBattleStruct->intimidateBank = i; + effect++; + break; + } + } + break; + case ABILITYEFFECT_TRACE: // 11 + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleMons[i].ability == ABILITY_TRACE && (gStatuses3[i] & STATUS3_TRACE)) + { + u8 opposite = (GetBankIdentity(i) ^ 1) & 1; + u8 target1 = GetBankByPlayerAI(opposite); + u8 target2 = GetBankByPlayerAI(opposite + 2); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + if (gBattleMons[target1].ability != 0 && gBattleMons[target1].hp != 0 + && gBattleMons[target2].ability != 0 && gBattleMons[target2].hp != 0) + { + gActiveBank = GetBankByPlayerAI(((Random() & 1) * 2) | opposite); + gBattleMons[i].ability = gBattleMons[gActiveBank].ability; + gLastUsedAbility = gBattleMons[gActiveBank].ability; + effect++; + } + else if (gBattleMons[target1].ability != 0 && gBattleMons[target1].hp != 0) + { + gActiveBank = target1; + gBattleMons[i].ability = gBattleMons[gActiveBank].ability; + gLastUsedAbility = gBattleMons[gActiveBank].ability; + effect++; + } + else if (gBattleMons[target2].ability != 0 && gBattleMons[target2].hp != 0) + { + gActiveBank = target2; + gBattleMons[i].ability = gBattleMons[gActiveBank].ability; + gLastUsedAbility = gBattleMons[gActiveBank].ability; + effect++; + } + } + else + { + gActiveBank = target1; + if (gBattleMons[target1].ability && gBattleMons[target1].hp) + { + gBattleMons[i].ability = gBattleMons[target1].ability; + gLastUsedAbility = gBattleMons[target1].ability; + effect++; + } + } + if (effect) + { + b_push_move_exec(BattleScript_TraceActivates); + gStatuses3[i] &= ~(STATUS3_TRACE); + gBattleScripting.bank = i; + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 4; + gBattleTextBuff1[2] = gActiveBank; + gBattleTextBuff1[3] = gBattlePartyID[gActiveBank]; + gBattleTextBuff1[4] = EOS; + + gBattleTextBuff2[0] = 0xFD; + gBattleTextBuff2[1] = 9; + gBattleTextBuff2[2] = gLastUsedAbility; + gBattleTextBuff2[3] = EOS; + break; + } + } + } + break; + case ABILITYEFFECT_INTIMIDATE2: // 10 + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleMons[i].ability == ABILITY_INTIMIDATE && (gStatuses3[i] & STATUS3_INTIMIDATE_POKES)) + { + gLastUsedAbility = ABILITY_INTIMIDATE; + gStatuses3[i] &= ~(STATUS3_INTIMIDATE_POKES); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = gUnknown_082DB4C1; + gBattleStruct->intimidateBank = i; + effect++; + break; + } + } + break; + case ABILITYEFFECT_CHECK_OTHER_SIDE: // 12 + side = GetBankSide(bank); + for (i = 0; i < gNoOfAllBanks; i++) + { + if (GetBankSide(i) != side && gBattleMons[i].ability == ability) + { + gLastUsedAbility = ability; + effect = i + 1; + } + } + break; + case ABILITYEFFECT_CHECK_BANK_SIDE: // 13 + side = GetBankSide(bank); + for (i = 0; i < gNoOfAllBanks; i++) + { + if (GetBankSide(i) == side && gBattleMons[i].ability == ability) + { + gLastUsedAbility = ability; + effect = i + 1; + } + } + break; + case ABILITYEFFECT_FIELD_SPORT: // 14 + switch (gLastUsedAbility) + { + case 0xFD: + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gStatuses3[i] & STATUS3_MUDSPORT) + effect = i + 1; + } + break; + case 0xFE: + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gStatuses3[i] & STATUS3_WATERSPORT) + effect = i + 1; + } + break; + default: + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleMons[i].ability == ability) + { + gLastUsedAbility = ability; + effect = i + 1; + } + } + break; + } + break; + case ABILITYEFFECT_CHECK_ON_FIELD: // 19 + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleMons[i].ability == ability && gBattleMons[i].hp != 0) + { + gLastUsedAbility = ability; + effect = i + 1; + } + } + break; + case ABILITYEFFECT_CHECK_FIELD_EXCEPT_BANK: // 15 + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleMons[i].ability == ability && i != bank) + { + gLastUsedAbility = ability; + effect = i + 1; + } + } + break; + case ABILITYEFFECT_COUNT_OTHER_SIZE: // 16 + side = GetBankSide(bank); + for (i = 0; i < gNoOfAllBanks; i++) + { + if (GetBankSide(i) != side && gBattleMons[i].ability == ability) + { + gLastUsedAbility = ability; + effect++; + } + } + break; + case ABILITYEFFECT_COUNT_BANK_SIDE: // 17 + side = GetBankSide(bank); + for (i = 0; i < gNoOfAllBanks; i++) + { + if (GetBankSide(i) == side && gBattleMons[i].ability == ability) + { + gLastUsedAbility = ability; + effect++; + } + } + break; + case ABILITYEFFECT_COUNT_ON_FIELD: // 18 + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleMons[i].ability == ability && i != bank) + { + gLastUsedAbility = ability; + effect++; + } + } + break; + } + if (effect && caseID < 0xC && gLastUsedAbility != 0xFF) + RecordAbilityBattle(bank, gLastUsedAbility); + } + + return effect; +} +#else +__attribute__((naked)) +u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) +{ + asm( + "\n\ + .syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x28\n\ + ldr r4, [sp, 0x48]\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + str r0, [sp, 0x4]\n\ + lsls r1, 24\n\ + lsrs r1, 24\n\ + mov r10, r1\n\ + lsls r2, 24\n\ + lsrs r6, r2, 24\n\ + lsls r3, 24\n\ + lsrs r3, 24\n\ + mov r8, r3\n\ + lsls r4, 16\n\ + lsrs r4, 16\n\ + movs r0, 0\n\ + mov r9, r0\n\ + ldr r5, =gBankAttacker\n\ + ldr r1, =gNoOfAllBanks\n\ + ldrb r0, [r5]\n\ + ldrb r1, [r1]\n\ + cmp r0, r1\n\ + bcc _08042864\n\ + mov r1, r10\n\ + strb r1, [r5]\n\ +_08042864:\n\ + ldrb r0, [r5]\n\ + bl GetBankSide\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _08042894\n\ + ldr r1, =gBattlePartyID\n\ + ldrb r0, [r5]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + ldrh r1, [r0]\n\ + movs r0, 0x64\n\ + muls r1, r0\n\ + ldr r0, =gPlayerParty\n\ + b _080428A4\n\ + .pool\n\ +_08042894:\n\ + ldr r1, =gBattlePartyID\n\ + ldrb r0, [r5]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + ldrh r1, [r0]\n\ + movs r0, 0x64\n\ + muls r1, r0\n\ + ldr r0, =gEnemyParty\n\ +_080428A4:\n\ + adds r7, r1, r0\n\ + ldr r5, =gBankTarget\n\ + ldr r1, =gNoOfAllBanks\n\ + ldrb r0, [r5]\n\ + ldrb r1, [r1]\n\ + cmp r0, r1\n\ + bcc _080428B6\n\ + mov r2, r10\n\ + strb r2, [r5]\n\ +_080428B6:\n\ + ldrb r0, [r5]\n\ + bl GetBankSide\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _080428E8\n\ + ldr r1, =gBattlePartyID\n\ + ldrb r0, [r5]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + ldrh r1, [r0]\n\ + movs r0, 0x64\n\ + muls r1, r0\n\ + ldr r0, =gPlayerParty\n\ + b _080428F8\n\ + .pool\n\ +_080428E8:\n\ + ldr r1, =gBattlePartyID\n\ + ldrb r0, [r5]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + ldrh r1, [r0]\n\ + movs r0, 0x64\n\ + muls r1, r0\n\ + ldr r0, =gEnemyParty\n\ +_080428F8:\n\ + adds r5, r1, r0\n\ + adds r0, r7, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + str r0, [sp, 0x8]\n\ + adds r0, r7, 0\n\ + movs r1, 0\n\ + bl GetMonData\n\ + str r0, [sp, 0x10]\n\ + adds r0, r5, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + str r0, [sp, 0xC]\n\ + adds r0, r5, 0\n\ + movs r1, 0\n\ + bl GetMonData\n\ + str r0, [sp, 0x14]\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804293A\n\ + bl _0804443A\n\ +_0804293A:\n\ + mov r3, r8\n\ + cmp r3, 0\n\ + beq _08042958\n\ + ldr r0, =gLastUsedAbility\n\ + strb r3, [r0]\n\ + adds r7, r0, 0\n\ + b _0804296E\n\ + .pool\n\ +_08042958:\n\ + ldr r2, =gLastUsedAbility\n\ + ldr r1, =gBattleMons\n\ + movs r0, 0x58\n\ + mov r5, r10\n\ + muls r5, r0\n\ + adds r0, r5, 0\n\ + adds r0, r1\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + strb r0, [r2]\n\ + adds r7, r2, 0\n\ +_0804296E:\n\ + cmp r4, 0\n\ + beq _08042980\n\ + adds r5, r4, 0\n\ + b _08042984\n\ + .pool\n\ +_08042980:\n\ + ldr r0, =gCurrentMove\n\ + ldrh r5, [r0]\n\ +_08042984:\n\ + ldr r1, =gBattleStruct\n\ + ldr r0, [r1]\n\ + ldrb r0, [r0, 0x13]\n\ + mov r8, r1\n\ + cmp r0, 0\n\ + beq _080429A0\n\ + movs r3, 0x3F\n\ + ands r3, r0\n\ + b _080429AC\n\ + .pool\n\ +_080429A0:\n\ + ldr r1, =gBattleMoves\n\ + lsls r0, r5, 1\n\ + adds r0, r5\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r3, [r0, 0x2]\n\ +_080429AC:\n\ + ldr r0, [sp, 0x4]\n\ + cmp r0, 0x13\n\ + bls _080429B6\n\ + bl _0804441E\n\ +_080429B6:\n\ + lsls r0, 2\n\ + ldr r1, =_080429C8\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .pool\n\ + .align 2, 0\n\ +_080429C8:\n\ + .4byte _08042A18\n\ + .4byte _08042CDC\n\ + .4byte _08042EF8\n\ + .4byte _08042F8C\n\ + .4byte _080431AC\n\ + .4byte _08043908\n\ + .4byte _08043C6C\n\ + .4byte _08043CBC\n\ + .4byte _08043D40\n\ + .4byte _08043DC4\n\ + .4byte _08043FE4\n\ + .4byte _08043E08\n\ + .4byte _08044028\n\ + .4byte _08044084\n\ + .4byte _080440E0\n\ + .4byte _080441DC\n\ + .4byte _08044220\n\ + .4byte _0804427C\n\ + .4byte _080443EC\n\ + .4byte _08044196\n\ +_08042A18:\n\ + ldr r2, =gBankAttacker\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r1, [r2]\n\ + adds r5, r0, 0\n\ + ldrb r3, [r5]\n\ + cmp r1, r3\n\ + bcc _08042A2A\n\ + mov r0, r10\n\ + strb r0, [r2]\n\ +_08042A2A:\n\ + ldrb r0, [r7]\n\ + cmp r0, 0x2D\n\ + bne _08042A32\n\ + b _08042BA8\n\ +_08042A32:\n\ + cmp r0, 0x2D\n\ + bgt _08042A64\n\ + cmp r0, 0xD\n\ + bne _08042A3C\n\ + b _08042CA4\n\ +_08042A3C:\n\ + cmp r0, 0xD\n\ + bgt _08042A54\n\ + cmp r0, 0x2\n\ + bne _08042A46\n\ + b _08042B78\n\ +_08042A46:\n\ + bl _0804441E\n\ + .pool\n\ +_08042A54:\n\ + cmp r0, 0x16\n\ + bne _08042A5A\n\ + b _08042C08\n\ +_08042A5A:\n\ + cmp r0, 0x24\n\ + bne _08042A60\n\ + b _08042C68\n\ +_08042A60:\n\ + bl _0804441E\n\ +_08042A64:\n\ + cmp r0, 0x46\n\ + bne _08042A6A\n\ + b _08042BD8\n\ +_08042A6A:\n\ + cmp r0, 0x46\n\ + bgt _08042A78\n\ + cmp r0, 0x3B\n\ + bne _08042A74\n\ + b _08042C3C\n\ +_08042A74:\n\ + bl _0804441E\n\ +_08042A78:\n\ + cmp r0, 0x4D\n\ + bne _08042A7E\n\ + b _08042CA4\n\ +_08042A7E:\n\ + cmp r0, 0xFF\n\ + beq _08042A86\n\ + bl _0804441E\n\ +_08042A86:\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 17\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08042B4C\n\ + bl weather_get_current\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + subs r0, 0x3\n\ + cmp r0, 0xA\n\ + bhi _08042B4C\n\ + lsls r0, 2\n\ + ldr r1, =_08042AB4\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .pool\n\ + .align 2, 0\n\ +_08042AB4:\n\ + .4byte _08042AE0\n\ + .4byte _08042B4C\n\ + .4byte _08042AE0\n\ + .4byte _08042B4C\n\ + .4byte _08042B4C\n\ + .4byte _08042B04\n\ + .4byte _08042B4C\n\ + .4byte _08042B4C\n\ + .4byte _08042B4C\n\ + .4byte _08042B28\n\ + .4byte _08042AE0\n\ +_08042AE0:\n\ + ldr r2, =gBattleWeather\n\ + ldrh r1, [r2]\n\ + movs r0, 0x7\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08042B4C\n\ + movs r0, 0x5\n\ + strh r0, [r2]\n\ + ldr r1, =gBattleScripting\n\ + movs r0, 0xA\n\ + strb r0, [r1, 0x10]\n\ + mov r2, r10\n\ + strb r2, [r1, 0x17]\n\ + b _08042B42\n\ + .pool\n\ +_08042B04:\n\ + ldr r3, =gBattleWeather\n\ + ldrh r1, [r3]\n\ + movs r2, 0x18\n\ + adds r0, r2, 0\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08042B4C\n\ + strh r2, [r3]\n\ + ldr r1, =gBattleScripting\n\ + movs r0, 0xC\n\ + strb r0, [r1, 0x10]\n\ + mov r3, r10\n\ + strb r3, [r1, 0x17]\n\ + b _08042B42\n\ + .pool\n\ +_08042B28:\n\ + ldr r3, =gBattleWeather\n\ + ldrh r1, [r3]\n\ + movs r2, 0x60\n\ + adds r0, r2, 0\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08042B4C\n\ + strh r2, [r3]\n\ + ldr r1, =gBattleScripting\n\ + movs r0, 0xB\n\ + strb r0, [r1, 0x10]\n\ + mov r5, r10\n\ + strb r5, [r1, 0x17]\n\ +_08042B42:\n\ + mov r0, r9\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_08042B4C:\n\ + mov r0, r9\n\ + cmp r0, 0\n\ + bne _08042B56\n\ + bl _0804443A\n\ +_08042B56:\n\ + bl weather_get_current\n\ + ldr r1, =gBattleCommunication\n\ + strb r0, [r1, 0x5]\n\ + ldr r0, =gUnknown_082DACE7\n\ + bl b_push_move_exec\n\ + bl _0804441E\n\ + .pool\n\ +_08042B78:\n\ + ldr r2, =gBattleWeather\n\ + ldrh r1, [r2]\n\ + movs r0, 0x4\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08042B88\n\ + bl _0804441E\n\ +_08042B88:\n\ + movs r0, 0x5\n\ + strh r0, [r2]\n\ + ldr r0, =BattleScript_DrizzleActivates\n\ + bl b_push_move_exec\n\ + ldr r0, =gBattleScripting\n\ + mov r1, r10\n\ + strb r1, [r0, 0x17]\n\ + bl _080443D0\n\ + .pool\n\ +_08042BA8:\n\ + ldr r2, =gBattleWeather\n\ + ldrh r1, [r2]\n\ + movs r0, 0x10\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08042BB8\n\ + bl _0804441E\n\ +_08042BB8:\n\ + movs r0, 0x18\n\ + strh r0, [r2]\n\ + ldr r0, =BattleScript_SandstreamActivates\n\ + bl b_push_move_exec\n\ + ldr r0, =gBattleScripting\n\ + mov r2, r10\n\ + strb r2, [r0, 0x17]\n\ + bl _080443D0\n\ + .pool\n\ +_08042BD8:\n\ + ldr r2, =gBattleWeather\n\ + ldrh r1, [r2]\n\ + movs r0, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08042BE8\n\ + bl _0804441E\n\ +_08042BE8:\n\ + movs r0, 0x60\n\ + strh r0, [r2]\n\ + ldr r0, =BattleScript_DroughtActivates\n\ + bl b_push_move_exec\n\ + ldr r0, =gBattleScripting\n\ + mov r3, r10\n\ + strb r3, [r0, 0x17]\n\ + bl _080443D0\n\ + .pool\n\ +_08042C08:\n\ + ldr r0, =gSpecialStatuses\n\ + mov r5, r10\n\ + lsls r2, r5, 2\n\ + adds r1, r2, r5\n\ + lsls r1, 2\n\ + adds r3, r1, r0\n\ + ldrb r0, [r3]\n\ + lsls r0, 28\n\ + cmp r0, 0\n\ + bge _08042C20\n\ + bl _0804441E\n\ +_08042C20:\n\ + ldr r1, =gStatuses3\n\ + adds r1, r2, r1\n\ + ldr r0, [r1]\n\ + movs r2, 0x80\n\ + lsls r2, 12\n\ + orrs r0, r2\n\ + str r0, [r1]\n\ + ldrb r0, [r3]\n\ + movs r1, 0x8\n\ + b _08042C92\n\ + .pool\n\ +_08042C3C:\n\ + mov r0, r10\n\ + bl CastformDataTypeChange\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ + cmp r0, 0\n\ + bne _08042C50\n\ + bl _0804443A\n\ +_08042C50:\n\ + ldr r0, =BattleScript_CastformChange\n\ + bl b_push_move_exec\n\ + ldr r0, =gBattleScripting\n\ + mov r1, r10\n\ + strb r1, [r0, 0x17]\n\ + bl _080442E2\n\ + .pool\n\ +_08042C68:\n\ + ldr r0, =gSpecialStatuses\n\ + mov r3, r10\n\ + lsls r2, r3, 2\n\ + adds r1, r2, r3\n\ + lsls r1, 2\n\ + adds r3, r1, r0\n\ + ldrb r0, [r3]\n\ + lsls r0, 27\n\ + cmp r0, 0\n\ + bge _08042C80\n\ + bl _0804441E\n\ +_08042C80:\n\ + ldr r1, =gStatuses3\n\ + adds r1, r2, r1\n\ + ldr r0, [r1]\n\ + movs r2, 0x80\n\ + lsls r2, 13\n\ + orrs r0, r2\n\ + str r0, [r1]\n\ + ldrb r0, [r3]\n\ + movs r1, 0x10\n\ +_08042C92:\n\ + orrs r0, r1\n\ + strb r0, [r3]\n\ + bl _0804441E\n\ + .pool\n\ +_08042CA4:\n\ + movs r6, 0\n\ + ldrb r5, [r5]\n\ + cmp r6, r5\n\ + bcc _08042CB0\n\ + bl _0804441E\n\ +_08042CB0:\n\ + adds r0, r6, 0\n\ + bl CastformDataTypeChange\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ + cmp r0, 0\n\ + beq _08042CC4\n\ + bl _080442D8\n\ +_08042CC4:\n\ + adds r0, r6, 0x1\n\ + lsls r0, 24\n\ + lsrs r6, r0, 24\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r6, r0\n\ + bcc _08042CB0\n\ + bl _0804441E\n\ + .pool\n\ +_08042CDC:\n\ + ldr r5, =gBattleMons\n\ + mov r8, r5\n\ + movs r0, 0x58\n\ + mov r6, r10\n\ + muls r6, r0\n\ + adds r4, r6, r5\n\ + ldrh r0, [r4, 0x28]\n\ + cmp r0, 0\n\ + bne _08042CF2\n\ + bl _0804441E\n\ +_08042CF2:\n\ + ldr r0, =gBankAttacker\n\ + mov r1, r10\n\ + strb r1, [r0]\n\ + ldrb r5, [r7]\n\ + cmp r5, 0x2C\n\ + beq _08042D22\n\ + cmp r5, 0x2C\n\ + bgt _08042D14\n\ + cmp r5, 0x3\n\ + bne _08042D08\n\ + b _08042E84\n\ +_08042D08:\n\ + bl _0804441E\n\ + .pool\n\ +_08042D14:\n\ + cmp r5, 0x36\n\ + bne _08042D1A\n\ + b _08042ED0\n\ +_08042D1A:\n\ + cmp r5, 0x3D\n\ + beq _08042DA0\n\ + bl _0804441E\n\ +_08042D22:\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0x13\n\ + movs r1, 0\n\ + movs r2, 0xD\n\ + movs r3, 0\n\ + bl AbilityBattleEffects\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0\n\ + beq _08042D3E\n\ + bl _0804441E\n\ +_08042D3E:\n\ + str r0, [sp]\n\ + movs r0, 0x13\n\ + movs r1, 0\n\ + movs r2, 0x4D\n\ + movs r3, 0\n\ + bl AbilityBattleEffects\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08042D56\n\ + bl _0804441E\n\ +_08042D56:\n\ + ldr r0, =gBattleWeather\n\ + ldrh r1, [r0]\n\ + movs r0, 0x7\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08042D66\n\ + bl _0804441E\n\ +_08042D66:\n\ + ldrh r0, [r4, 0x2C]\n\ + ldrh r2, [r4, 0x28]\n\ + cmp r0, r2\n\ + bhi _08042D72\n\ + bl _0804441E\n\ +_08042D72:\n\ + strb r5, [r7]\n\ + ldr r0, =BattleScript_RainDishActivates\n\ + bl b_push_move_exec\n\ + ldr r1, =gBattleMoveDamage\n\ + ldrh r0, [r4, 0x2C]\n\ + lsrs r0, 4\n\ + str r0, [r1]\n\ + cmp r0, 0\n\ + bne _08042D8A\n\ + movs r0, 0x1\n\ + str r0, [r1]\n\ +_08042D8A:\n\ + ldr r0, [r1]\n\ + negs r0, r0\n\ + str r0, [r1]\n\ + bl _080443D0\n\ + .pool\n\ +_08042DA0:\n\ + mov r0, r8\n\ + adds r0, 0x4C\n\ + adds r5, r6, r0\n\ + ldrb r0, [r5]\n\ + cmp r0, 0\n\ + bne _08042DB0\n\ + bl _0804441E\n\ +_08042DB0:\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x3\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + lsrs r4, r0, 16\n\ + cmp r4, 0\n\ + beq _08042DCA\n\ + bl _0804441E\n\ +_08042DCA:\n\ + ldr r0, [r5]\n\ + movs r1, 0x88\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08042DDC\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_PoisonJpn\n\ + bl StringCopy\n\ +_08042DDC:\n\ + ldr r0, [r5]\n\ + movs r1, 0x7\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08042DEE\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_SleepJpn\n\ + bl StringCopy\n\ +_08042DEE:\n\ + ldr r0, [r5]\n\ + movs r1, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08042E00\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_ParalysisJpn\n\ + bl StringCopy\n\ +_08042E00:\n\ + ldr r0, [r5]\n\ + movs r1, 0x10\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08042E12\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_BurnJpn\n\ + bl StringCopy\n\ +_08042E12:\n\ + ldr r0, [r5]\n\ + movs r1, 0x20\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08042E24\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_IceJpn\n\ + bl StringCopy\n\ +_08042E24:\n\ + str r4, [r5]\n\ + mov r1, r8\n\ + adds r1, 0x50\n\ + adds r1, r6, r1\n\ + ldr r0, [r1]\n\ + ldr r2, =0xf7ffffff\n\ + ands r0, r2\n\ + str r0, [r1]\n\ + ldr r0, =gBattleScripting\n\ + ldr r4, =gActiveBank\n\ + mov r3, r10\n\ + strb r3, [r4]\n\ + strb r3, [r0, 0x17]\n\ + ldr r0, =BattleScript_ShedSkinActivates\n\ + bl b_push_move_exec\n\ + str r5, [sp]\n\ + movs r0, 0\n\ + movs r1, 0x28\n\ + movs r2, 0\n\ + movs r3, 0x4\n\ + bl EmitSetAttributes\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + bl _080443D0\n\ + .pool\n\ +_08042E84:\n\ + ldrb r2, [r4, 0x1B]\n\ + movs r0, 0x1B\n\ + ldrsb r0, [r4, r0]\n\ + cmp r0, 0xB\n\ + ble _08042E92\n\ + bl _0804441E\n\ +_08042E92:\n\ + ldr r0, =gDisableStructs\n\ + mov r5, r10\n\ + lsls r1, r5, 3\n\ + subs r1, r5\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x16]\n\ + cmp r0, 0x2\n\ + bne _08042EA8\n\ + bl _0804441E\n\ +_08042EA8:\n\ + adds r0, r2, 0x1\n\ + movs r1, 0\n\ + strb r0, [r4, 0x1B]\n\ + ldr r4, =gBattleScripting\n\ + movs r0, 0x11\n\ + strb r0, [r4, 0x10]\n\ + strb r1, [r4, 0x11]\n\ + ldr r0, =BattleScript_SpeedBoostActivates\n\ + bl b_push_move_exec\n\ + strb r5, [r4, 0x17]\n\ + bl _080443D0\n\ + .pool\n\ +_08042ED0:\n\ + ldr r2, =gDisableStructs\n\ + ldrb r0, [r0]\n\ + lsls r1, r0, 3\n\ + subs r1, r0\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + ldrb r3, [r1, 0x18]\n\ + lsls r0, r3, 31\n\ + lsrs r0, 31\n\ + movs r2, 0x1\n\ + eors r2, r0\n\ + movs r0, 0x2\n\ + negs r0, r0\n\ + ands r0, r3\n\ + orrs r0, r2\n\ + strb r0, [r1, 0x18]\n\ + bl _0804441E\n\ + .pool\n\ +_08042EF8:\n\ + ldrb r0, [r7]\n\ + cmp r0, 0x2B\n\ + beq _08042F02\n\ + bl _0804441E\n\ +_08042F02:\n\ + movs r4, 0\n\ + ldr r0, =gSoundMovesTable\n\ + ldrh r2, [r0]\n\ + ldr r3, =0x0000ffff\n\ + adds r1, r0, 0\n\ + cmp r2, r3\n\ + bne _08042F14\n\ + bl _0804441E\n\ +_08042F14:\n\ + cmp r2, r5\n\ + beq _08042F2C\n\ + adds r2, r1, 0\n\ +_08042F1A:\n\ + adds r2, 0x2\n\ + adds r4, 0x1\n\ + ldrh r0, [r2]\n\ + cmp r0, r3\n\ + bne _08042F28\n\ + bl _0804441E\n\ +_08042F28:\n\ + cmp r0, r5\n\ + bne _08042F1A\n\ +_08042F2C:\n\ + lsls r0, r4, 1\n\ + adds r0, r1\n\ + ldrh r1, [r0]\n\ + ldr r0, =0x0000ffff\n\ + cmp r1, r0\n\ + bne _08042F3C\n\ + bl _0804441E\n\ +_08042F3C:\n\ + ldr r1, =gBattleMons\n\ + ldr r0, =gBankAttacker\n\ + ldrb r2, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r1, 0x50\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 5\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08042F62\n\ + ldr r0, =gHitMarker\n\ + ldr r1, [r0]\n\ + movs r2, 0x80\n\ + lsls r2, 4\n\ + orrs r1, r2\n\ + str r1, [r0]\n\ +_08042F62:\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_SoundproofProtected\n\ + str r0, [r1]\n\ + movs r0, 0x1\n\ + mov r9, r0\n\ + bl _08044424\n\ + .pool\n\ +_08042F8C:\n\ + cmp r5, 0\n\ + bne _08042F94\n\ + bl _0804441E\n\ +_08042F94:\n\ + ldrb r0, [r7]\n\ + cmp r0, 0xB\n\ + beq _08043004\n\ + cmp r0, 0xB\n\ + bgt _08042FA4\n\ + cmp r0, 0xA\n\ + beq _08042FAA\n\ + b _08043126\n\ +_08042FA4:\n\ + cmp r0, 0x12\n\ + beq _0804305C\n\ + b _08043126\n\ +_08042FAA:\n\ + cmp r3, 0xD\n\ + beq _08042FB0\n\ + b _08043126\n\ +_08042FB0:\n\ + ldr r0, =gBattleMoves\n\ + lsls r1, r5, 1\n\ + adds r1, r5\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + cmp r0, 0\n\ + bne _08042FC2\n\ + b _08043126\n\ +_08042FC2:\n\ + ldr r1, =gProtectStructs\n\ + ldr r0, =gBankAttacker\n\ + ldrb r0, [r0]\n\ + lsls r0, 4\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x2]\n\ + lsls r0, 28\n\ + cmp r0, 0\n\ + bge _08042FF0\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_MoveHPDrain\n\ + b _08042FF4\n\ + .pool\n\ +_08042FF0:\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_MoveHPDrain_PPLoss\n\ +_08042FF4:\n\ + str r0, [r1]\n\ + movs r1, 0x1\n\ + b _08043124\n\ + .pool\n\ +_08043004:\n\ + cmp r3, 0xB\n\ + beq _0804300A\n\ + b _08043126\n\ +_0804300A:\n\ + ldr r0, =gBattleMoves\n\ + lsls r1, r5, 1\n\ + adds r1, r5\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + cmp r0, 0\n\ + bne _0804301C\n\ + b _08043126\n\ +_0804301C:\n\ + ldr r1, =gProtectStructs\n\ + ldr r0, =gBankAttacker\n\ + ldrb r0, [r0]\n\ + lsls r0, 4\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x2]\n\ + lsls r0, 28\n\ + cmp r0, 0\n\ + bge _08043048\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_MoveHPDrain\n\ + b _0804304C\n\ + .pool\n\ +_08043048:\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_MoveHPDrain_PPLoss\n\ +_0804304C:\n\ + str r0, [r1]\n\ + movs r2, 0x1\n\ + mov r9, r2\n\ + b _08043126\n\ + .pool\n\ +_0804305C:\n\ + cmp r3, 0xA\n\ + bne _08043126\n\ + ldr r1, =gBattleMons\n\ + movs r0, 0x58\n\ + mov r3, r10\n\ + muls r3, r0\n\ + adds r0, r3, 0\n\ + adds r1, 0x4C\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x20\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08043126\n\ + ldr r2, =gBattleResources\n\ + ldr r0, [r2]\n\ + ldr r0, [r0, 0x4]\n\ + mov r5, r10\n\ + lsls r1, r5, 2\n\ + adds r0, r1\n\ + ldr r3, [r0]\n\ + movs r4, 0x1\n\ + ands r3, r4\n\ + adds r5, r1, 0\n\ + cmp r3, 0\n\ + bne _080430EC\n\ + ldr r0, =gBattleCommunication\n\ + strb r3, [r0, 0x5]\n\ + ldr r1, =gProtectStructs\n\ + ldr r0, =gBankAttacker\n\ + ldrb r0, [r0]\n\ + lsls r0, 4\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x2]\n\ + lsls r0, 28\n\ + cmp r0, 0\n\ + bge _080430C8\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_FlashFireBoost\n\ + b _080430CC\n\ + .pool\n\ +_080430C8:\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_FlashFireBoost_PPLoss\n\ +_080430CC:\n\ + str r0, [r1]\n\ + ldr r0, [r2]\n\ + ldr r1, [r0, 0x4]\n\ + adds r1, r5\n\ + ldr r0, [r1]\n\ + movs r2, 0x1\n\ + orrs r0, r2\n\ + str r0, [r1]\n\ + movs r0, 0x2\n\ + mov r9, r0\n\ + b _08043126\n\ + .pool\n\ +_080430EC:\n\ + ldr r0, =gBattleCommunication\n\ + strb r4, [r0, 0x5]\n\ + ldr r1, =gProtectStructs\n\ + ldr r0, =gBankAttacker\n\ + ldrb r0, [r0]\n\ + lsls r0, 4\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x2]\n\ + lsls r0, 28\n\ + cmp r0, 0\n\ + bge _0804311C\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_FlashFireBoost\n\ + b _08043120\n\ + .pool\n\ +_0804311C:\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_FlashFireBoost_PPLoss\n\ +_08043120:\n\ + str r0, [r1]\n\ + movs r1, 0x2\n\ +_08043124:\n\ + mov r9, r1\n\ +_08043126:\n\ + mov r2, r9\n\ + cmp r2, 0x1\n\ + beq _08043130\n\ + bl _0804441E\n\ +_08043130:\n\ + ldr r1, =gBattleMons\n\ + movs r0, 0x58\n\ + mov r3, r10\n\ + muls r3, r0\n\ + adds r0, r3, 0\n\ + adds r1, r0, r1\n\ + ldrh r0, [r1, 0x2C]\n\ + ldrh r5, [r1, 0x28]\n\ + cmp r0, r5\n\ + bne _0804318C\n\ + ldr r1, =gProtectStructs\n\ + ldr r0, =gBankAttacker\n\ + ldrb r0, [r0]\n\ + lsls r0, 4\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x2]\n\ + lsls r0, 28\n\ + cmp r0, 0\n\ + bge _08043178\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =gUnknown_082DB592\n\ + str r0, [r1]\n\ + bl _0804441E\n\ + .pool\n\ +_08043178:\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =gUnknown_082DB591\n\ + str r0, [r1]\n\ + bl _0804441E\n\ + .pool\n\ +_0804318C:\n\ + ldr r2, =gBattleMoveDamage\n\ + ldrh r0, [r1, 0x2C]\n\ + lsrs r0, 2\n\ + str r0, [r2]\n\ + cmp r0, 0\n\ + bne _0804319C\n\ + mov r0, r9\n\ + str r0, [r2]\n\ +_0804319C:\n\ + ldr r0, [r2]\n\ + negs r0, r0\n\ + str r0, [r2]\n\ + bl _0804441E\n\ + .pool\n\ +_080431AC:\n\ + ldrb r0, [r7]\n\ + subs r0, 0x9\n\ + cmp r0, 0x2F\n\ + bls _080431B8\n\ + bl _0804441E\n\ +_080431B8:\n\ + lsls r0, 2\n\ + ldr r1, =_080431C8\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .pool\n\ + .align 2, 0\n\ +_080431C8:\n\ + .4byte _080435E4\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _08043288\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _08043350\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _08043410\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _08043508\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _080436C0\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804441E\n\ + .4byte _0804379C\n\ +_08043288:\n\ + ldr r0, =gBattleMoveFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08043298\n\ + bl _0804441E\n\ +_08043298:\n\ + cmp r5, 0xA5\n\ + bne _080432A0\n\ + bl _0804441E\n\ +_080432A0:\n\ + ldr r0, =gBattleMoves\n\ + lsls r1, r5, 1\n\ + adds r1, r5\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + cmp r0, 0\n\ + bne _080432B4\n\ + bl _0804441E\n\ +_080432B4:\n\ + ldr r2, =gSpecialStatuses\n\ + ldr r0, =gBankTarget\n\ + ldrb r1, [r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r1, r0, 2\n\ + adds r0, r2, 0\n\ + adds r0, 0x8\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _080432DC\n\ + adds r0, r2, 0\n\ + adds r0, 0xC\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _080432DC\n\ + bl _0804441E\n\ +_080432DC:\n\ + ldr r1, =gBattleMons\n\ + movs r0, 0x58\n\ + mov r2, r10\n\ + muls r2, r0\n\ + adds r0, r2, 0\n\ + adds r1, r0, r1\n\ + adds r4, r1, 0\n\ + adds r4, 0x21\n\ + ldrb r0, [r4]\n\ + cmp r0, r3\n\ + bne _080432F6\n\ + bl _0804441E\n\ +_080432F6:\n\ + adds r2, r1, 0\n\ + adds r2, 0x22\n\ + ldrb r0, [r2]\n\ + cmp r0, r3\n\ + bne _08043304\n\ + bl _0804441E\n\ +_08043304:\n\ + ldrh r0, [r1, 0x28]\n\ + cmp r0, 0\n\ + bne _0804330E\n\ + bl _0804441E\n\ +_0804330E:\n\ + strb r3, [r4]\n\ + strb r3, [r2]\n\ + ldr r1, =gBattleTextBuff1\n\ + movs r0, 0xFD\n\ + strb r0, [r1]\n\ + movs r0, 0x3\n\ + strb r0, [r1, 0x1]\n\ + strb r3, [r1, 0x2]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x3]\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_ColorChangeActivates\n\ + str r0, [r1]\n\ + bl _080443D0\n\ + .pool\n\ +_08043350:\n\ + ldr r0, =gBattleMoveFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08043360\n\ + bl _0804441E\n\ +_08043360:\n\ + ldr r1, =gBattleMons\n\ + ldr r0, =gBankAttacker\n\ + ldrb r2, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r3, r0, r1\n\ + ldrh r0, [r3, 0x28]\n\ + cmp r0, 0\n\ + bne _08043376\n\ + bl _0804441E\n\ +_08043376:\n\ + ldr r0, =gProtectStructs\n\ + lsls r1, r2, 4\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + lsls r0, 31\n\ + cmp r0, 0\n\ + beq _08043388\n\ + bl _0804441E\n\ +_08043388:\n\ + ldr r2, =gSpecialStatuses\n\ + ldr r0, =gBankTarget\n\ + ldrb r1, [r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r1, r0, 2\n\ + adds r0, r2, 0\n\ + adds r0, 0x8\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _080433B0\n\ + adds r0, r2, 0\n\ + adds r0, 0xC\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _080433B0\n\ + bl _0804441E\n\ +_080433B0:\n\ + ldr r1, =gBattleMoves\n\ + lsls r0, r5, 1\n\ + adds r0, r5\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r1, [r0, 0x8]\n\ + movs r2, 0x1\n\ + adds r0, r2, 0\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _080433CA\n\ + bl _0804441E\n\ +_080433CA:\n\ + ldr r1, =gBattleMoveDamage\n\ + ldrh r0, [r3, 0x2C]\n\ + lsrs r0, 4\n\ + str r0, [r1]\n\ + cmp r0, 0\n\ + bne _080433D8\n\ + str r2, [r1]\n\ +_080433D8:\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_RoughSkinActivates\n\ + str r0, [r1]\n\ + bl _080443D0\n\ + .pool\n\ +_08043410:\n\ + ldr r0, =gBattleMoveFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08043420\n\ + bl _0804441E\n\ +_08043420:\n\ + ldr r1, =gBattleMons\n\ + ldr r0, =gBankAttacker\n\ + ldrb r2, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r0, r1\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + bne _08043436\n\ + bl _0804441E\n\ +_08043436:\n\ + ldr r0, =gProtectStructs\n\ + lsls r1, r2, 4\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + lsls r0, 31\n\ + cmp r0, 0\n\ + beq _08043448\n\ + bl _0804441E\n\ +_08043448:\n\ + ldr r2, =gSpecialStatuses\n\ + ldr r0, =gBankTarget\n\ + ldrb r1, [r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r1, r0, 2\n\ + adds r0, r2, 0\n\ + adds r0, 0x8\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08043470\n\ + adds r0, r2, 0\n\ + adds r0, 0xC\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08043470\n\ + bl _0804441E\n\ +_08043470:\n\ + ldr r1, =gBattleMoves\n\ + lsls r0, r5, 1\n\ + adds r0, r5\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r1, [r0, 0x8]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08043488\n\ + bl _0804441E\n\ +_08043488:\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0xA\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + cmp r0, 0\n\ + beq _080434A0\n\ + bl _0804441E\n\ +_080434A0:\n\ + ldr r5, =gBattleCommunication\n\ + movs r4, 0x3\n\ +_080434A4:\n\ + bl Random\n\ + ands r0, r4\n\ + strb r0, [r5, 0x3]\n\ + cmp r0, 0\n\ + beq _080434A4\n\ + ldr r1, =gBattleCommunication\n\ + ldrb r0, [r1, 0x3]\n\ + cmp r0, 0x3\n\ + bne _080434BC\n\ + adds r0, 0x2\n\ + strb r0, [r1, 0x3]\n\ +_080434BC:\n\ + ldrb r0, [r1, 0x3]\n\ + adds r0, 0x40\n\ + strb r0, [r1, 0x3]\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_ApplySecondaryEffect\n\ + str r0, [r1]\n\ + ldr r2, =gHitMarker\n\ + ldr r0, [r2]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + bl _080443D0\n\ + .pool\n\ +_08043508:\n\ + ldr r0, =gBattleMoveFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08043518\n\ + bl _0804441E\n\ +_08043518:\n\ + ldr r1, =gBattleMons\n\ + ldr r0, =gBankAttacker\n\ + ldrb r2, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r0, r1\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + bne _0804352E\n\ + bl _0804441E\n\ +_0804352E:\n\ + ldr r0, =gProtectStructs\n\ + lsls r1, r2, 4\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + lsls r0, 31\n\ + cmp r0, 0\n\ + beq _08043540\n\ + bl _0804441E\n\ +_08043540:\n\ + ldr r2, =gSpecialStatuses\n\ + ldr r0, =gBankTarget\n\ + ldrb r1, [r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r1, r0, 2\n\ + adds r0, r2, 0\n\ + adds r0, 0x8\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08043568\n\ + adds r0, r2, 0\n\ + adds r0, 0xC\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08043568\n\ + bl _0804441E\n\ +_08043568:\n\ + ldr r1, =gBattleMoves\n\ + lsls r0, r5, 1\n\ + adds r0, r5\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r1, [r0, 0x8]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08043580\n\ + bl _0804441E\n\ +_08043580:\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x3\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + cmp r0, 0\n\ + beq _08043598\n\ + bl _0804441E\n\ +_08043598:\n\ + ldr r1, =gBattleCommunication\n\ + movs r0, 0x42\n\ + strb r0, [r1, 0x3]\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_ApplySecondaryEffect\n\ + str r0, [r1]\n\ + ldr r2, =gHitMarker\n\ + ldr r0, [r2]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + bl _080443D0\n\ + .pool\n\ +_080435E4:\n\ + ldr r0, =gBattleMoveFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _080435F4\n\ + bl _0804441E\n\ +_080435F4:\n\ + ldr r1, =gBattleMons\n\ + ldr r0, =gBankAttacker\n\ + ldrb r2, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r0, r1\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + bne _0804360A\n\ + bl _0804441E\n\ +_0804360A:\n\ + ldr r0, =gProtectStructs\n\ + lsls r1, r2, 4\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + lsls r0, 31\n\ + cmp r0, 0\n\ + beq _0804361C\n\ + bl _0804441E\n\ +_0804361C:\n\ + ldr r2, =gSpecialStatuses\n\ + ldr r0, =gBankTarget\n\ + ldrb r1, [r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r1, r0, 2\n\ + adds r0, r2, 0\n\ + adds r0, 0x8\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08043644\n\ + adds r0, r2, 0\n\ + adds r0, 0xC\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08043644\n\ + bl _0804441E\n\ +_08043644:\n\ + ldr r1, =gBattleMoves\n\ + lsls r0, r5, 1\n\ + adds r0, r5\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r1, [r0, 0x8]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0804365C\n\ + bl _0804441E\n\ +_0804365C:\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x3\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + cmp r0, 0\n\ + beq _08043674\n\ + bl _0804441E\n\ +_08043674:\n\ + ldr r1, =gBattleCommunication\n\ + movs r0, 0x45\n\ + strb r0, [r1, 0x3]\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_ApplySecondaryEffect\n\ + str r0, [r1]\n\ + ldr r2, =gHitMarker\n\ + ldr r0, [r2]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + bl _080443D0\n\ + .pool\n\ +_080436C0:\n\ + ldr r0, =gBattleMoveFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _080436D0\n\ + bl _0804441E\n\ +_080436D0:\n\ + ldr r1, =gBattleMons\n\ + ldr r0, =gBankAttacker\n\ + ldrb r2, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r0, r1\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + bne _080436E6\n\ + bl _0804441E\n\ +_080436E6:\n\ + ldr r0, =gProtectStructs\n\ + lsls r1, r2, 4\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + lsls r0, 31\n\ + cmp r0, 0\n\ + beq _080436F8\n\ + bl _0804441E\n\ +_080436F8:\n\ + ldr r1, =gBattleMoves\n\ + lsls r0, r5, 1\n\ + adds r0, r5\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r1, [r0, 0x8]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08043710\n\ + bl _0804441E\n\ +_08043710:\n\ + ldr r2, =gSpecialStatuses\n\ + ldr r0, =gBankTarget\n\ + ldrb r1, [r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r1, r0, 2\n\ + adds r0, r2, 0\n\ + adds r0, 0x8\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08043738\n\ + adds r0, r2, 0\n\ + adds r0, 0xC\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08043738\n\ + bl _0804441E\n\ +_08043738:\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x3\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + cmp r0, 0\n\ + beq _08043750\n\ + bl _0804441E\n\ +_08043750:\n\ + ldr r1, =gBattleCommunication\n\ + movs r0, 0x43\n\ + strb r0, [r1, 0x3]\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_ApplySecondaryEffect\n\ + str r0, [r1]\n\ + ldr r2, =gHitMarker\n\ + ldr r0, [r2]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + bl _080443D0\n\ + .pool\n\ +_0804379C:\n\ + ldr r0, =gBattleMoveFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _080437AC\n\ + bl _0804441E\n\ +_080437AC:\n\ + ldr r6, =gBattleMons\n\ + ldr r3, =gBankAttacker\n\ + mov r8, r3\n\ + ldrb r1, [r3]\n\ + movs r7, 0x58\n\ + adds r0, r1, 0\n\ + muls r0, r7\n\ + adds r0, r6\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + bne _080437C6\n\ + bl _0804441E\n\ +_080437C6:\n\ + ldr r0, =gProtectStructs\n\ + lsls r1, 4\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + lsls r0, 31\n\ + cmp r0, 0\n\ + beq _080437D8\n\ + bl _0804441E\n\ +_080437D8:\n\ + ldr r1, =gBattleMoves\n\ + lsls r0, r5, 1\n\ + adds r0, r5\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r1, [r0, 0x8]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _080437F0\n\ + bl _0804441E\n\ +_080437F0:\n\ + ldr r3, =gSpecialStatuses\n\ + ldr r5, =gBankTarget\n\ + ldrb r1, [r5]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r2, r0, 2\n\ + adds r0, r3, 0\n\ + adds r0, 0x8\n\ + adds r0, r2, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08043818\n\ + adds r0, r3, 0\n\ + adds r0, 0xC\n\ + adds r0, r2, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08043818\n\ + bl _0804441E\n\ +_08043818:\n\ + adds r0, r1, 0\n\ + muls r0, r7\n\ + adds r0, r6\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + bne _08043828\n\ + bl _0804441E\n\ +_08043828:\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x3\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + cmp r0, 0\n\ + beq _08043840\n\ + bl _0804441E\n\ +_08043840:\n\ + mov r1, r8\n\ + ldrb r0, [r1]\n\ + muls r0, r7\n\ + adds r0, r6\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0xC\n\ + bne _08043854\n\ + bl _0804441E\n\ +_08043854:\n\ + ldr r0, [sp, 0x8]\n\ + ldr r1, [sp, 0x10]\n\ + bl GetGenderFromSpeciesAndPersonality\n\ + adds r4, r0, 0\n\ + ldr r0, [sp, 0xC]\n\ + ldr r1, [sp, 0x14]\n\ + bl GetGenderFromSpeciesAndPersonality\n\ + lsls r4, 24\n\ + lsls r0, 24\n\ + cmp r4, r0\n\ + bne _08043872\n\ + bl _0804441E\n\ +_08043872:\n\ + mov r2, r8\n\ + ldrb r0, [r2]\n\ + muls r0, r7\n\ + adds r4, r6, 0\n\ + adds r4, 0x50\n\ + adds r0, r4\n\ + ldr r0, [r0]\n\ + movs r1, 0xF0\n\ + lsls r1, 12\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804388E\n\ + bl _0804441E\n\ +_0804388E:\n\ + ldr r0, [sp, 0x8]\n\ + ldr r1, [sp, 0x10]\n\ + bl GetGenderFromSpeciesAndPersonality\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0xFF\n\ + bne _080438A2\n\ + bl _0804441E\n\ +_080438A2:\n\ + ldr r0, [sp, 0xC]\n\ + ldr r1, [sp, 0x14]\n\ + bl GetGenderFromSpeciesAndPersonality\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0xFF\n\ + bne _080438B6\n\ + bl _0804441E\n\ +_080438B6:\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + adds r2, r0, 0\n\ + muls r2, r7\n\ + adds r2, r4\n\ + ldr r1, =gBitTable\n\ + ldrb r0, [r5]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r1, [r0]\n\ + lsls r1, 16\n\ + ldr r0, [r2]\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_CuteCharmActivates\n\ + str r0, [r1]\n\ + bl _080443D0\n\ + .pool\n\ +_08043908:\n\ + movs r5, 0\n\ + mov r10, r5\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r10, r0\n\ + bcc _08043918\n\ + bl _0804441E\n\ +_08043918:\n\ + ldr r1, =gBattleMons\n\ + movs r0, 0x58\n\ + mov r2, r10\n\ + muls r2, r0\n\ + adds r0, r2, 0\n\ + adds r0, r1\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + subs r0, 0x7\n\ + adds r2, r1, 0\n\ + cmp r0, 0x41\n\ + bls _08043932\n\ + b _08043B96\n\ +_08043932:\n\ + lsls r0, 2\n\ + ldr r1, =_08043948\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .pool\n\ + .align 2, 0\n\ +_08043948:\n\ + .4byte _08043AAC\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B70\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043AD4\n\ + .4byte _08043B96\n\ + .4byte _08043A50\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043A7C\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B40\n\ + .4byte _08043B10\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043B96\n\ + .4byte _08043AD4\n\ +_08043A50:\n\ + movs r0, 0x58\n\ + mov r3, r10\n\ + muls r3, r0\n\ + adds r0, r3, 0\n\ + adds r1, r2, 0\n\ + adds r1, 0x4C\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + ldr r1, =0x00000f88\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08043A6A\n\ + b _08043B96\n\ +_08043A6A:\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_PoisonJpn\n\ + b _08043B5C\n\ + .pool\n\ +_08043A7C:\n\ + movs r0, 0x58\n\ + mov r1, r10\n\ + muls r1, r0\n\ + adds r0, r1, 0\n\ + adds r1, r2, 0\n\ + adds r1, 0x50\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x7\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08043A96\n\ + b _08043B96\n\ +_08043A96:\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_ConfusionJpn\n\ + bl StringCopy\n\ + movs r2, 0x2\n\ + mov r9, r2\n\ + b _08043B9C\n\ + .pool\n\ +_08043AAC:\n\ + movs r0, 0x58\n\ + mov r3, r10\n\ + muls r3, r0\n\ + adds r0, r3, 0\n\ + adds r1, r2, 0\n\ + adds r1, 0x4C\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08043B96\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_ParalysisJpn\n\ + b _08043B5C\n\ + .pool\n\ +_08043AD4:\n\ + movs r0, 0x58\n\ + mov r3, r10\n\ + muls r3, r0\n\ + adds r0, r2, 0\n\ + adds r0, 0x4C\n\ + adds r0, r3, r0\n\ + ldr r0, [r0]\n\ + movs r1, 0x7\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08043B96\n\ + adds r2, 0x50\n\ + adds r2, r3, r2\n\ + ldr r0, [r2]\n\ + ldr r1, =0xf7ffffff\n\ + ands r0, r1\n\ + str r0, [r2]\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_SleepJpn\n\ + bl StringCopy\n\ + movs r0, 0x1\n\ + mov r9, r0\n\ + b _08043B9C\n\ + .pool\n\ +_08043B10:\n\ + movs r0, 0x58\n\ + mov r1, r10\n\ + muls r1, r0\n\ + adds r0, r1, 0\n\ + adds r1, r2, 0\n\ + adds r1, 0x4C\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x10\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08043B96\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_BurnJpn\n\ + bl StringCopy\n\ + movs r2, 0x1\n\ + mov r9, r2\n\ + b _08043B9C\n\ + .pool\n\ +_08043B40:\n\ + movs r0, 0x58\n\ + mov r3, r10\n\ + muls r3, r0\n\ + adds r0, r3, 0\n\ + adds r1, r2, 0\n\ + adds r1, 0x4C\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x20\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08043B96\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_IceJpn\n\ +_08043B5C:\n\ + bl StringCopy\n\ + movs r5, 0x1\n\ + mov r9, r5\n\ + b _08043B9C\n\ + .pool\n\ +_08043B70:\n\ + movs r0, 0x58\n\ + mov r1, r10\n\ + muls r1, r0\n\ + adds r0, r1, 0\n\ + adds r1, r2, 0\n\ + adds r1, 0x50\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0xF0\n\ + lsls r1, 12\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08043B96\n\ + ldr r0, =gBattleTextBuff1\n\ + ldr r1, =gStatusConditionString_LoveJpn\n\ + bl StringCopy\n\ + movs r2, 0x3\n\ + mov r9, r2\n\ +_08043B96:\n\ + mov r3, r9\n\ + cmp r3, 0\n\ + beq _08043C50\n\ +_08043B9C:\n\ + mov r5, r9\n\ + cmp r5, 0x2\n\ + beq _08043BD0\n\ + cmp r5, 0x2\n\ + bgt _08043BB4\n\ + cmp r5, 0x1\n\ + beq _08043BBC\n\ + b _08043BFC\n\ + .pool\n\ +_08043BB4:\n\ + mov r0, r9\n\ + cmp r0, 0x3\n\ + beq _08043BE8\n\ + b _08043BFC\n\ +_08043BBC:\n\ + ldr r1, =gBattleMons\n\ + movs r0, 0x58\n\ + mov r2, r10\n\ + muls r2, r0\n\ + adds r1, 0x4C\n\ + adds r2, r1\n\ + movs r0, 0\n\ + b _08043BFA\n\ + .pool\n\ +_08043BD0:\n\ + ldr r1, =gBattleMons\n\ + movs r0, 0x58\n\ + mov r2, r10\n\ + muls r2, r0\n\ + adds r1, 0x50\n\ + adds r2, r1\n\ + ldr r0, [r2]\n\ + movs r1, 0x8\n\ + negs r1, r1\n\ + b _08043BF8\n\ + .pool\n\ +_08043BE8:\n\ + ldr r1, =gBattleMons\n\ + movs r0, 0x58\n\ + mov r2, r10\n\ + muls r2, r0\n\ + adds r1, 0x50\n\ + adds r2, r1\n\ + ldr r0, [r2]\n\ + ldr r1, =0xfff0ffff\n\ +_08043BF8:\n\ + ands r0, r1\n\ +_08043BFA:\n\ + str r0, [r2]\n\ +_08043BFC:\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =gUnknown_082DB68C\n\ + str r0, [r1]\n\ + ldr r0, =gBattleScripting\n\ + mov r1, r10\n\ + strb r1, [r0, 0x17]\n\ + ldr r4, =gActiveBank\n\ + strb r1, [r4]\n\ + ldrb r1, [r4]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + ldr r1, =gBattleMons + 0x4C\n\ + adds r0, r1\n\ + str r0, [sp]\n\ + movs r0, 0\n\ + movs r1, 0x28\n\ + movs r2, 0\n\ + movs r3, 0x4\n\ + bl EmitSetAttributes\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + bl _0804443A\n\ + .pool\n\ +_08043C50:\n\ + mov r0, r10\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r10, r0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r10, r0\n\ + bcs _08043C64\n\ + b _08043918\n\ +_08043C64:\n\ + bl _0804441E\n\ + .pool\n\ +_08043C6C:\n\ + movs r2, 0\n\ + mov r10, r2\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r10, r0\n\ + bcc _08043C7A\n\ + b _0804441E\n\ +_08043C7A:\n\ + ldr r4, =gBattleMons\n\ +_08043C7C:\n\ + movs r0, 0x58\n\ + mov r3, r10\n\ + muls r3, r0\n\ + adds r0, r3, 0\n\ + adds r0, r4\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x3B\n\ + bne _08043CA0\n\ + mov r0, r10\n\ + bl CastformDataTypeChange\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ + cmp r0, 0\n\ + beq _08043CA0\n\ + b _080442FC\n\ +_08043CA0:\n\ + mov r0, r10\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r10, r0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r10, r0\n\ + bcc _08043C7C\n\ + b _0804441E\n\ + .pool\n\ +_08043CBC:\n\ + ldrb r0, [r7]\n\ + cmp r0, 0x1C\n\ + beq _08043CC4\n\ + b _0804441E\n\ +_08043CC4:\n\ + ldr r4, =gHitMarker\n\ + ldr r1, [r4]\n\ + movs r0, 0x80\n\ + lsls r0, 7\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08043CD4\n\ + b _0804441E\n\ +_08043CD4:\n\ + ldr r0, =0xffffbfff\n\ + ands r1, r0\n\ + str r1, [r4]\n\ + mov r5, r8\n\ + ldr r1, [r5]\n\ + adds r1, 0xB2\n\ + ldrb r2, [r1]\n\ + movs r0, 0x3F\n\ + ands r0, r2\n\ + strb r0, [r1]\n\ + ldr r0, [r5]\n\ + adds r1, r0, 0\n\ + adds r1, 0xB2\n\ + ldrb r0, [r1]\n\ + cmp r0, 0x6\n\ + bne _08043CF8\n\ + movs r0, 0x2\n\ + strb r0, [r1]\n\ +_08043CF8:\n\ + ldr r1, =gBattleCommunication\n\ + mov r2, r8\n\ + ldr r0, [r2]\n\ + adds r0, 0xB2\n\ + ldrb r0, [r0]\n\ + adds r0, 0x40\n\ + strb r0, [r1, 0x3]\n\ + ldr r1, =gBattleScripting\n\ + ldr r0, =gBankTarget\n\ + ldrb r0, [r0]\n\ + strb r0, [r1, 0x17]\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_SynchronizeActivates\n\ + str r0, [r1]\n\ + ldr r0, [r4]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + orrs r0, r1\n\ + str r0, [r4]\n\ + b _080443D0\n\ + .pool\n\ +_08043D40:\n\ + ldrb r0, [r7]\n\ + cmp r0, 0x1C\n\ + beq _08043D48\n\ + b _0804441E\n\ +_08043D48:\n\ + ldr r4, =gHitMarker\n\ + ldr r1, [r4]\n\ + movs r0, 0x80\n\ + lsls r0, 7\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08043D58\n\ + b _0804441E\n\ +_08043D58:\n\ + ldr r0, =0xffffbfff\n\ + ands r1, r0\n\ + str r1, [r4]\n\ + mov r3, r8\n\ + ldr r1, [r3]\n\ + adds r1, 0xB2\n\ + ldrb r2, [r1]\n\ + movs r0, 0x3F\n\ + ands r0, r2\n\ + strb r0, [r1]\n\ + ldr r0, [r3]\n\ + adds r1, r0, 0\n\ + adds r1, 0xB2\n\ + ldrb r0, [r1]\n\ + cmp r0, 0x6\n\ + bne _08043D7C\n\ + movs r0, 0x2\n\ + strb r0, [r1]\n\ +_08043D7C:\n\ + ldr r1, =gBattleCommunication\n\ + mov r3, r8\n\ + ldr r0, [r3]\n\ + adds r0, 0xB2\n\ + ldrb r0, [r0]\n\ + strb r0, [r1, 0x3]\n\ + ldr r1, =gBattleScripting\n\ + ldr r0, =gBankAttacker\n\ + ldrb r0, [r0]\n\ + strb r0, [r1, 0x17]\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =BattleScript_SynchronizeActivates\n\ + str r0, [r1]\n\ + ldr r0, [r4]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + orrs r0, r1\n\ + str r0, [r4]\n\ + b _080443D0\n\ + .pool\n\ +_08043DC4:\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r1, [r0]\n\ + cmp r4, r1\n\ + blt _08043DD0\n\ + b _0804441E\n\ +_08043DD0:\n\ + ldr r0, =gBattleMons\n\ + adds r5, r1, 0\n\ + ldr r2, =gStatuses3\n\ + adds r3, r0, 0\n\ + adds r3, 0x20\n\ + movs r6, 0x80\n\ + lsls r6, 12\n\ +_08043DDE:\n\ + ldrb r1, [r3]\n\ + cmp r1, 0x16\n\ + bne _08043DEE\n\ + ldr r0, [r2]\n\ + ands r0, r6\n\ + cmp r0, 0\n\ + beq _08043DEE\n\ + b _08044324\n\ +_08043DEE:\n\ + adds r2, 0x4\n\ + adds r3, 0x58\n\ + adds r4, 0x1\n\ + cmp r4, r5\n\ + blt _08043DDE\n\ + b _0804441E\n\ + .pool\n\ +_08043E08:\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _08043E14\n\ + b _0804441E\n\ +_08043E14:\n\ + ldr r5, =gActiveBank\n\ + mov r8, r5\n\ + ldr r0, =gBattleMons\n\ + adds r0, 0x20\n\ + str r0, [sp, 0x1C]\n\ + movs r1, 0\n\ + str r1, [sp, 0x20]\n\ +_08043E22:\n\ + ldr r2, [sp, 0x1C]\n\ + ldrb r0, [r2]\n\ + cmp r0, 0x24\n\ + beq _08043E2C\n\ + b _08043FBE\n\ +_08043E2C:\n\ + ldr r0, =gStatuses3\n\ + ldr r3, [sp, 0x20]\n\ + adds r0, r3, r0\n\ + ldr r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 13\n\ + ands r1, r0\n\ + str r3, [sp, 0x18]\n\ + cmp r1, 0\n\ + bne _08043E42\n\ + b _08043FBE\n\ +_08043E42:\n\ + lsls r0, r4, 24\n\ + lsrs r0, 24\n\ + bl GetBankIdentity\n\ + movs r1, 0x1\n\ + adds r5, r0, 0\n\ + eors r5, r1\n\ + ands r5, r1\n\ + adds r0, r5, 0\n\ + bl GetBankByPlayerAI\n\ + lsls r0, 24\n\ + lsrs r6, r0, 24\n\ + adds r0, r5, 0x2\n\ + bl GetBankByPlayerAI\n\ + lsls r0, 24\n\ + lsrs r7, r0, 24\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r2, 0x1\n\ + ands r0, r2\n\ + cmp r0, 0\n\ + bne _08043E74\n\ + b _08043F84\n\ +_08043E74:\n\ + movs r1, 0x58\n\ + adds r0, r6, 0\n\ + muls r0, r1\n\ + ldr r3, =gBattleMons\n\ + adds r1, r0, r3\n\ + adds r0, r1, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _08043F40\n\ + ldrh r0, [r1, 0x28]\n\ + cmp r0, 0\n\ + beq _08043EFC\n\ + movs r1, 0x58\n\ + adds r0, r7, 0\n\ + muls r0, r1\n\ + adds r1, r0, r3\n\ + adds r0, r1, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _08043EFC\n\ + ldrh r0, [r1, 0x28]\n\ + cmp r0, 0\n\ + beq _08043EFC\n\ + str r2, [sp, 0x24]\n\ + bl Random\n\ + ldr r2, [sp, 0x24]\n\ + adds r1, r2, 0\n\ + ands r1, r0\n\ + lsls r1, 1\n\ + orrs r5, r1\n\ + adds r0, r5, 0\n\ + bl GetBankByPlayerAI\n\ + mov r2, r8\n\ + strb r0, [r2]\n\ + ldrb r0, [r2]\n\ + movs r3, 0x58\n\ + muls r0, r3\n\ + ldr r5, =gBattleMons\n\ + adds r0, r5\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + ldr r1, [sp, 0x1C]\n\ + strb r0, [r1]\n\ + ldrb r0, [r2]\n\ + muls r0, r3\n\ + adds r0, r5\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + ldr r2, =gLastUsedAbility\n\ + strb r0, [r2]\n\ + b _08043FAC\n\ + .pool\n\ +_08043EFC:\n\ + ldr r3, =gBattleMons\n\ + movs r2, 0x58\n\ + adds r0, r6, 0\n\ + muls r0, r2\n\ + adds r1, r0, r3\n\ + adds r0, r1, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _08043F40\n\ + ldrh r0, [r1, 0x28]\n\ + cmp r0, 0\n\ + beq _08043F40\n\ + mov r5, r8\n\ + strb r6, [r5]\n\ + adds r1, r4, 0\n\ + muls r1, r2\n\ + adds r1, r3\n\ + ldrb r0, [r5]\n\ + muls r0, r2\n\ + adds r0, r3\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + adds r1, 0x20\n\ + strb r0, [r1]\n\ + ldrb r0, [r5]\n\ + muls r0, r2\n\ + adds r0, r3\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + b _08043FA8\n\ + .pool\n\ +_08043F40:\n\ + ldr r3, =gBattleMons\n\ + movs r2, 0x58\n\ + adds r0, r7, 0\n\ + muls r0, r2\n\ + adds r1, r0, r3\n\ + adds r0, r1, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _08043FB6\n\ + ldrh r0, [r1, 0x28]\n\ + cmp r0, 0\n\ + beq _08043FB6\n\ + mov r5, r8\n\ + strb r7, [r5]\n\ + adds r1, r4, 0\n\ + muls r1, r2\n\ + adds r1, r3\n\ + ldrb r0, [r5]\n\ + muls r0, r2\n\ + adds r0, r3\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + adds r1, 0x20\n\ + strb r0, [r1]\n\ + ldrb r0, [r5]\n\ + muls r0, r2\n\ + adds r0, r3\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + b _08043FA8\n\ + .pool\n\ +_08043F84:\n\ + mov r2, r8\n\ + strb r6, [r2]\n\ + movs r3, 0x58\n\ + adds r0, r6, 0\n\ + muls r0, r3\n\ + ldr r5, =gBattleMons\n\ + adds r0, r5\n\ + adds r2, r0, 0\n\ + adds r2, 0x20\n\ + ldrb r1, [r2]\n\ + cmp r1, 0\n\ + beq _08043FB6\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + beq _08043FB6\n\ + ldr r0, [sp, 0x1C]\n\ + strb r1, [r0]\n\ + ldrb r0, [r2]\n\ +_08043FA8:\n\ + ldr r1, =gLastUsedAbility\n\ + strb r0, [r1]\n\ +_08043FAC:\n\ + mov r0, r9\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_08043FB6:\n\ + mov r2, r9\n\ + cmp r2, 0\n\ + beq _08043FBE\n\ + b _08044340\n\ +_08043FBE:\n\ + ldr r3, [sp, 0x1C]\n\ + adds r3, 0x58\n\ + str r3, [sp, 0x1C]\n\ + ldr r5, [sp, 0x20]\n\ + adds r5, 0x4\n\ + str r5, [sp, 0x20]\n\ + adds r4, 0x1\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + bge _08043FD6\n\ + b _08043E22\n\ +_08043FD6:\n\ + b _0804441E\n\ + .pool\n\ +_08043FE4:\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r1, [r0]\n\ + cmp r4, r1\n\ + blt _08043FF0\n\ + b _0804441E\n\ +_08043FF0:\n\ + ldr r0, =gBattleMons\n\ + adds r5, r1, 0\n\ + ldr r2, =gStatuses3\n\ + adds r3, r0, 0\n\ + adds r3, 0x20\n\ + movs r6, 0x80\n\ + lsls r6, 12\n\ +_08043FFE:\n\ + ldrb r1, [r3]\n\ + cmp r1, 0x16\n\ + bne _0804400E\n\ + ldr r0, [r2]\n\ + ands r0, r6\n\ + cmp r0, 0\n\ + beq _0804400E\n\ + b _080443B4\n\ +_0804400E:\n\ + adds r2, 0x4\n\ + adds r3, 0x58\n\ + adds r4, 0x1\n\ + cmp r4, r5\n\ + blt _08043FFE\n\ + b _0804441E\n\ + .pool\n\ +_08044028:\n\ + mov r0, r10\n\ + bl GetBankSide\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _0804403E\n\ + b _0804441E\n\ +_0804403E:\n\ + ldr r7, =gBattleMons\n\ +_08044040:\n\ + lsls r0, r4, 24\n\ + lsrs r0, 24\n\ + bl GetBankSide\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + adds r3, r4, 0x1\n\ + cmp r0, r5\n\ + beq _0804406A\n\ + movs r0, 0x58\n\ + muls r0, r4\n\ + adds r0, r7\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, r6\n\ + bne _0804406A\n\ + ldr r0, =gLastUsedAbility\n\ + strb r6, [r0]\n\ + lsls r0, r3, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_0804406A:\n\ + adds r4, r3, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _08044040\n\ + b _0804441E\n\ + .pool\n\ +_08044084:\n\ + mov r0, r10\n\ + bl GetBankSide\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _0804409A\n\ + b _0804441E\n\ +_0804409A:\n\ + ldr r7, =gBattleMons\n\ +_0804409C:\n\ + lsls r0, r4, 24\n\ + lsrs r0, 24\n\ + bl GetBankSide\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + adds r3, r4, 0x1\n\ + cmp r0, r5\n\ + bne _080440C6\n\ + movs r0, 0x58\n\ + muls r0, r4\n\ + adds r0, r7\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, r6\n\ + bne _080440C6\n\ + ldr r0, =gLastUsedAbility\n\ + strb r6, [r0]\n\ + lsls r0, r3, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_080440C6:\n\ + adds r4, r3, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _0804409C\n\ + b _0804441E\n\ + .pool\n\ +_080440E0:\n\ + ldrb r0, [r7]\n\ + cmp r0, 0xFD\n\ + beq _08044104\n\ + cmp r0, 0xFE\n\ + beq _0804413C\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + adds r5, r0, 0\n\ + ldrb r0, [r5]\n\ + cmp r4, r0\n\ + blt _080440F8\n\ + b _0804441E\n\ +_080440F8:\n\ + ldr r2, =gBattleMons\n\ + b _08044174\n\ + .pool\n\ +_08044104:\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _08044110\n\ + b _0804441E\n\ +_08044110:\n\ + ldr r5, =gStatuses3\n\ + movs r2, 0x80\n\ + lsls r2, 9\n\ + adds r1, r0, 0\n\ +_08044118:\n\ + lsls r0, r4, 2\n\ + adds r0, r5\n\ + ldr r0, [r0]\n\ + ands r0, r2\n\ + adds r3, r4, 0x1\n\ + cmp r0, 0\n\ + beq _0804412C\n\ + lsls r0, r3, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_0804412C:\n\ + adds r4, r3, 0\n\ + cmp r4, r1\n\ + blt _08044118\n\ + b _0804441E\n\ + .pool\n\ +_0804413C:\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _08044148\n\ + b _0804441E\n\ +_08044148:\n\ + ldr r5, =gStatuses3\n\ + movs r2, 0x80\n\ + lsls r2, 10\n\ + adds r1, r0, 0\n\ +_08044150:\n\ + lsls r0, r4, 2\n\ + adds r0, r5\n\ + ldr r0, [r0]\n\ + ands r0, r2\n\ + adds r3, r4, 0x1\n\ + cmp r0, 0\n\ + beq _08044164\n\ + lsls r0, r3, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_08044164:\n\ + adds r4, r3, 0\n\ + cmp r4, r1\n\ + blt _08044150\n\ + b _0804441E\n\ + .pool\n\ +_08044174:\n\ + movs r0, 0x58\n\ + muls r0, r4\n\ + adds r0, r2\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + adds r3, r4, 0x1\n\ + cmp r0, r6\n\ + bne _0804418C\n\ + strb r6, [r7]\n\ + lsls r0, r3, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_0804418C:\n\ + adds r4, r3, 0\n\ + ldrb r1, [r5]\n\ + cmp r4, r1\n\ + blt _08044174\n\ + b _0804441E\n\ +_08044196:\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _080441A2\n\ + b _0804441E\n\ +_080441A2:\n\ + ldr r2, =gBattleMons\n\ + mov r8, r2\n\ + adds r2, r0, 0\n\ + movs r5, 0x58\n\ +_080441AA:\n\ + adds r0, r4, 0\n\ + muls r0, r5\n\ + mov r3, r8\n\ + adds r1, r0, r3\n\ + adds r0, r1, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + adds r3, r4, 0x1\n\ + cmp r0, r6\n\ + bne _080441CC\n\ + ldrh r0, [r1, 0x28]\n\ + cmp r0, 0\n\ + beq _080441CC\n\ + strb r6, [r7]\n\ + lsls r0, r3, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_080441CC:\n\ + adds r4, r3, 0\n\ + cmp r4, r2\n\ + blt _080441AA\n\ + b _0804441E\n\ + .pool\n\ +_080441DC:\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _080441E8\n\ + b _0804441E\n\ +_080441E8:\n\ + ldr r7, =gBattleMons\n\ + adds r1, r0, 0\n\ + movs r5, 0x58\n\ + ldr r2, =gLastUsedAbility\n\ +_080441F0:\n\ + adds r0, r4, 0\n\ + muls r0, r5\n\ + adds r0, r7\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + adds r3, r4, 0x1\n\ + cmp r0, r6\n\ + bne _0804420C\n\ + cmp r4, r10\n\ + beq _0804420C\n\ + strb r6, [r2]\n\ + lsls r0, r3, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_0804420C:\n\ + adds r4, r3, 0\n\ + cmp r4, r1\n\ + blt _080441F0\n\ + b _0804441E\n\ + .pool\n\ +_08044220:\n\ + mov r0, r10\n\ + bl GetBankSide\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _08044236\n\ + b _0804441E\n\ +_08044236:\n\ + ldr r7, =gBattleMons\n\ +_08044238:\n\ + lsls r0, r4, 24\n\ + lsrs r0, 24\n\ + bl GetBankSide\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, r5\n\ + beq _08044264\n\ + movs r0, 0x58\n\ + muls r0, r4\n\ + adds r0, r7\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, r6\n\ + bne _08044264\n\ + ldr r0, =gLastUsedAbility\n\ + strb r6, [r0]\n\ + mov r0, r9\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_08044264:\n\ + adds r4, 0x1\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _08044238\n\ + b _0804441E\n\ + .pool\n\ +_0804427C:\n\ + mov r0, r10\n\ + bl GetBankSide\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _08044292\n\ + b _0804441E\n\ +_08044292:\n\ + ldr r7, =gBattleMons\n\ +_08044294:\n\ + lsls r0, r4, 24\n\ + lsrs r0, 24\n\ + bl GetBankSide\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, r5\n\ + bne _080442C0\n\ + movs r0, 0x58\n\ + muls r0, r4\n\ + adds r0, r7\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, r6\n\ + bne _080442C0\n\ + ldr r0, =gLastUsedAbility\n\ + strb r6, [r0]\n\ + mov r0, r9\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_080442C0:\n\ + adds r4, 0x1\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r0, [r0]\n\ + cmp r4, r0\n\ + blt _08044294\n\ + b _0804441E\n\ + .pool\n\ +_080442D8:\n\ + ldr r0, =BattleScript_CastformChange\n\ + bl b_push_move_exec\n\ + ldr r0, =gBattleScripting\n\ + strb r6, [r0, 0x17]\n\ +_080442E2:\n\ + ldr r0, =gBattleStruct\n\ + ldr r0, [r0]\n\ + adds r0, 0x7F\n\ + mov r1, r9\n\ + subs r1, 0x1\n\ + strb r1, [r0]\n\ + b _0804441E\n\ + .pool\n\ +_080442FC:\n\ + ldr r0, =BattleScript_CastformChange\n\ + bl b_push_move_exec\n\ + ldr r0, =gBattleScripting\n\ + mov r5, r10\n\ + strb r5, [r0, 0x17]\n\ + ldr r0, =gBattleStruct\n\ + ldr r0, [r0]\n\ + adds r0, 0x7F\n\ + mov r1, r9\n\ + subs r1, 0x1\n\ + strb r1, [r0]\n\ + b _0804443A\n\ + .pool\n\ +_08044324:\n\ + strb r1, [r7]\n\ + ldr r0, [r2]\n\ + ldr r1, =0xfff7ffff\n\ + ands r0, r1\n\ + str r0, [r2]\n\ + ldr r0, =gUnknown_082DB4B8\n\ + bl b_push_move_exec\n\ + b _080443C8\n\ + .pool\n\ +_08044340:\n\ + ldr r0, =BattleScript_TraceActivates\n\ + bl b_push_move_exec\n\ + ldr r1, =gStatuses3\n\ + ldr r0, [sp, 0x18]\n\ + adds r1, r0, r1\n\ + ldr r0, [r1]\n\ + ldr r2, =0xffefffff\n\ + ands r0, r2\n\ + str r0, [r1]\n\ + ldr r0, =gBattleScripting\n\ + strb r4, [r0, 0x17]\n\ + ldr r1, =gBattleTextBuff1\n\ + movs r4, 0xFD\n\ + strb r4, [r1]\n\ + movs r0, 0x4\n\ + strb r0, [r1, 0x1]\n\ + ldr r2, =gActiveBank\n\ + ldrb r0, [r2]\n\ + strb r0, [r1, 0x2]\n\ + ldr r3, =gBattlePartyID\n\ + ldrb r0, [r2]\n\ + lsls r0, 1\n\ + adds r0, r3\n\ + ldrh r0, [r0]\n\ + strb r0, [r1, 0x3]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x4]\n\ + ldr r1, =gBattleTextBuff2\n\ + strb r4, [r1]\n\ + movs r0, 0x9\n\ + strb r0, [r1, 0x1]\n\ + ldr r0, =gLastUsedAbility\n\ + ldrb r0, [r0]\n\ + strb r0, [r1, 0x2]\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + strb r0, [r1, 0x3]\n\ + b _0804441E\n\ + .pool\n\ +_080443B4:\n\ + strb r1, [r7]\n\ + ldr r0, [r2]\n\ + ldr r1, =0xfff7ffff\n\ + ands r0, r1\n\ + str r0, [r2]\n\ + bl b_movescr_stack_push_cursor\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, =gUnknown_082DB4C1\n\ + str r0, [r1]\n\ +_080443C8:\n\ + ldr r0, =gBattleStruct\n\ + ldr r0, [r0]\n\ + adds r0, 0xD8\n\ + strb r4, [r0]\n\ +_080443D0:\n\ + mov r0, r9\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ + b _0804441E\n\ + .pool\n\ +_080443EC:\n\ + movs r4, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r1, [r0]\n\ + cmp r4, r1\n\ + bge _0804441E\n\ + ldr r0, =gBattleMons\n\ + adds r2, r1, 0\n\ + adds r1, r0, 0\n\ + adds r1, 0x20\n\ + ldr r3, =gLastUsedAbility\n\ +_08044400:\n\ + ldrb r0, [r1]\n\ + cmp r0, r6\n\ + bne _08044416\n\ + cmp r4, r10\n\ + beq _08044416\n\ + strb r6, [r3]\n\ + mov r0, r9\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r9, r0\n\ +_08044416:\n\ + adds r1, 0x58\n\ + adds r4, 0x1\n\ + cmp r4, r2\n\ + blt _08044400\n\ +_0804441E:\n\ + mov r1, r9\n\ + cmp r1, 0\n\ + beq _0804443A\n\ +_08044424:\n\ + ldr r2, [sp, 0x4]\n\ + cmp r2, 0xB\n\ + bhi _0804443A\n\ + ldr r1, =gLastUsedAbility\n\ + ldrb r0, [r1]\n\ + cmp r0, 0xFF\n\ + beq _0804443A\n\ + adds r1, r0, 0\n\ + mov r0, r10\n\ + bl RecordAbilityBattle\n\ +_0804443A:\n\ + mov r0, r9\n\ + add sp, 0x28\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r1}\n\ + bx r1\n\ + .pool\n\ + .syntax divided"); +} +#endif // NONMATCHING -- cgit v1.2.3 From 9dc7839dd875cc06b582bd78f2263478a0571535 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 09:49:50 -0400 Subject: callers of sub_80940C4 --- src/field_map_obj.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 3e3bbfa6f..7ef901eec 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4316,3 +4316,13 @@ u8 sub_80940C4(struct MapObject *mapObject, struct Sprite *sprite, u8 callback(s } return result; } + +u8 sub_8094188(struct MapObject *mapObject, struct Sprite *sprite) +{ + return sub_80940C4(mapObject, sprite, sub_809785C); +} + +u8 sub_809419C(struct MapObject *mapObject, struct Sprite *sprite) +{ + return sub_80940C4(mapObject, sprite, sub_80978E4); +} -- cgit v1.2.3 From 99e0fe1f241dbdd780f7330ab5891574a8a21080 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 09:52:17 -0400 Subject: callers of callers of sub_80940C4 --- src/field_map_obj.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 7ef901eec..bc8c7512d 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4326,3 +4326,21 @@ u8 sub_809419C(struct MapObject *mapObject, struct Sprite *sprite) { return sub_80940C4(mapObject, sprite, sub_80978E4); } + +bool8 sub_80941B0(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_8094188(mapObject, sprite) == 0xFF) + { + return TRUE; + } + return FALSE; +} + +bool8 sub_80941C8(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_809419C(mapObject, sprite) == 0xFF) + { + return TRUE; + } + return FALSE; +} -- cgit v1.2.3 From 3fdb217ba3ba4d30a915fe0e7df85ebe09b226fb Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 09:55:17 -0400 Subject: sub_80941E0 --- src/field_map_obj.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index bc8c7512d..fb0d1c81b 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4344,3 +4344,17 @@ bool8 sub_80941C8(struct MapObject *mapObject, struct Sprite *sprite) } return FALSE; } + +bool8 sub_80941E0(struct MapObject *mapObject, struct Sprite *sprite) +{ + switch (sub_8094188(mapObject, sprite)) + { + case 255: + return TRUE; + case 1: + FieldObjectSetDirection(mapObject, GetOppositeDirection(mapObject->placeholder18)); + obj_npc_animation_step(mapObject, sprite, get_go_image_anim_num(mapObject->mapobj_unk_18)); + default: + return FALSE; + } +} -- cgit v1.2.3 From 3a7f771eabc3054029c73828ca3872b1157af01a Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 10:01:27 -0400 Subject: maybe_shadow_1 might be a meme --- src/field_map_obj.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index fb0d1c81b..dcf439b9b 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4358,3 +4358,26 @@ bool8 sub_80941E0(struct MapObject *mapObject, struct Sprite *sprite) return FALSE; } } + +#define maybe_shadow_1_macro(name, fn1, fn2, ...) \ +static bool8 name##_2(struct MapObject *, struct Sprite *);\ +bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + fn1(mapObject, sprite, __VA_ARGS__);\ + return name##_2(mapObject, sprite);\ +}\ +static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + if (fn2(mapObject, sprite))\ + {\ + mapObject->mapobj_bit_22 = FALSE;\ + sprite->data2 = 2;\ + return TRUE;\ + }\ + return FALSE;\ +} + +maybe_shadow_1_macro(sub_8094230, maybe_shadow_1, sub_80941B0, 1, 2, 0) +maybe_shadow_1_macro(sub_8094288, maybe_shadow_1, sub_80941B0, 2, 2, 0) +maybe_shadow_1_macro(sub_80942E0, maybe_shadow_1, sub_80941B0, 3, 2, 0) +maybe_shadow_1_macro(sub_8094338, maybe_shadow_1, sub_80941B0, 4, 2, 0) -- cgit v1.2.3 From cd958b1e4376058db61607e1cff4427d8a0175b8 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 10:07:43 -0400 Subject: special_anim_with_timer --- src/field_map_obj.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index dcf439b9b..9fedc7f0b 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4381,3 +4381,32 @@ maybe_shadow_1_macro(sub_8094230, maybe_shadow_1, sub_80941B0, 1, 2, 0) maybe_shadow_1_macro(sub_8094288, maybe_shadow_1, sub_80941B0, 2, 2, 0) maybe_shadow_1_macro(sub_80942E0, maybe_shadow_1, sub_80941B0, 3, 2, 0) maybe_shadow_1_macro(sub_8094338, maybe_shadow_1, sub_80941B0, 4, 2, 0) + +void sub_8094390(struct Sprite *sprite, u16 duration) +{ + sprite->data2 = 1; + sprite->data3 = duration; +} + +bool8 sub_8094398(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (-- sprite->data3 == 0) + { + sprite->data2 = 2; + return TRUE; + } + return FALSE; +} + +#define special_anim_with_timer(name, duration)\ +bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + sub_8094390(sprite, duration);\ + return sub_8094398(mapObject, sprite);\ +} + +special_anim_with_timer(sub_80943B4, 1) +special_anim_with_timer(sub_80943D4, 2) +special_anim_with_timer(sub_80943F4, 4) +special_anim_with_timer(sub_8094414, 8) +special_anim_with_timer(sub_8094434, 16) -- cgit v1.2.3 From 43b3195bc853ac9d88ae93d9a36060de8a2295ac Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 10:23:18 -0400 Subject: More special anims with timers --- src/field_map_obj.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 9fedc7f0b..e6a4c4181 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4410,3 +4410,63 @@ special_anim_with_timer(sub_80943D4, 2) special_anim_with_timer(sub_80943F4, 4) special_anim_with_timer(sub_8094414, 8) special_anim_with_timer(sub_8094434, 16) + +an_walk_any_2_macro(sub_8094454, do_go_anim, npc_obj_ministep_stop_on_arrival, 1, 1) +an_walk_any_2_macro(sub_8094494, do_go_anim, npc_obj_ministep_stop_on_arrival, 2, 1) +an_walk_any_2_macro(sub_80944D4, do_go_anim, npc_obj_ministep_stop_on_arrival, 3, 1) +an_walk_any_2_macro(sub_8094514, do_go_anim, npc_obj_ministep_stop_on_arrival, 4, 1) + +void sub_8094554(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 animNum, u16 duration) +{ + FieldObjectSetDirection(mapObject, direction); + npc_apply_anim_looping(mapObject, sprite, animNum); + sprite->animPaused = FALSE; + sprite->data2 = 1; + sprite->data3 = duration; +} + +bool8 sub_809459C(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (-- sprite->data3 == 0) + { + sprite->data2 = 2; + sprite->animPaused = TRUE; + return TRUE; + } + return FALSE; +} + +bool8 sub_80945C4(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sprite->data3 & 1) + { + sprite->animDelayCounter ++; + } + return sub_809459C(mapObject, sprite); +} + +#define special_anim_with_timer_2(name, direction, images, duration, timer) \ +bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + u8 animId;\ + animId = get_##images##_image_anim_num(direction);\ + sub_8094554(mapObject, sprite, direction, animId, duration);\ + return timer(mapObject, sprite);\ +} + +special_anim_with_timer_2(sub_8094600, DIR_SOUTH, go, 32, sub_80945C4) +special_anim_with_timer_2(sub_8094638, DIR_NORTH, go, 32, sub_80945C4) +special_anim_with_timer_2(sub_8094670, DIR_WEST, go, 32, sub_80945C4) +special_anim_with_timer_2(sub_80946A8, DIR_EAST, go, 32, sub_80945C4) +special_anim_with_timer_2(sub_80946E0, DIR_SOUTH, go, 16, sub_809459C) +special_anim_with_timer_2(sub_8094718, DIR_NORTH, go, 16, sub_809459C) +special_anim_with_timer_2(sub_8094750, DIR_WEST, go, 16, sub_809459C) +special_anim_with_timer_2(sub_8094788, DIR_EAST, go, 16, sub_809459C) +special_anim_with_timer_2(sub_80947C0, DIR_SOUTH, go_fast, 8, sub_809459C) +special_anim_with_timer_2(sub_80947F8, DIR_NORTH, go_fast, 8, sub_809459C) +special_anim_with_timer_2(sub_8094830, DIR_WEST, go_fast, 8, sub_809459C) +special_anim_with_timer_2(sub_8094868, DIR_EAST, go_fast, 8, sub_809459C) +special_anim_with_timer_2(sub_80948A0, DIR_SOUTH, go_faster, 4, sub_809459C) +special_anim_with_timer_2(sub_80948D8, DIR_NORTH, go_faster, 4, sub_809459C) +special_anim_with_timer_2(sub_8094910, DIR_WEST, go_faster, 4, sub_809459C) +special_anim_with_timer_2(sub_8094948, DIR_EAST, go_faster, 4, sub_809459C) -- cgit v1.2.3 From f8b08d3ee7f2836f86eed171b064ebb125d43400 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 10:25:48 -0400 Subject: more an_walk_any_2_macro functions --- src/field_map_obj.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index e6a4c4181..c4847ae4f 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4470,3 +4470,16 @@ special_anim_with_timer_2(sub_80948A0, DIR_SOUTH, go_faster, 4, sub_809459C) special_anim_with_timer_2(sub_80948D8, DIR_NORTH, go_faster, 4, sub_809459C) special_anim_with_timer_2(sub_8094910, DIR_WEST, go_faster, 4, sub_809459C) special_anim_with_timer_2(sub_8094948, DIR_EAST, go_faster, 4, sub_809459C) + +an_walk_any_2_macro(sub_8094980, do_go_anim, npc_obj_ministep_stop_on_arrival, 1, 2) +an_walk_any_2_macro(sub_80949C0, do_go_anim, npc_obj_ministep_stop_on_arrival, 2, 2) +an_walk_any_2_macro(sub_8094A00, do_go_anim, npc_obj_ministep_stop_on_arrival, 3, 2) +an_walk_any_2_macro(sub_8094A40, do_go_anim, npc_obj_ministep_stop_on_arrival, 4, 2) +an_walk_any_2_macro(sub_8094A80, do_go_anim, npc_obj_ministep_stop_on_arrival, 1, 3) +an_walk_any_2_macro(sub_8094AC0, do_go_anim, npc_obj_ministep_stop_on_arrival, 2, 3) +an_walk_any_2_macro(sub_8094B00, do_go_anim, npc_obj_ministep_stop_on_arrival, 3, 3) +an_walk_any_2_macro(sub_8094B40, do_go_anim, npc_obj_ministep_stop_on_arrival, 4, 3) +an_walk_any_2_macro(sub_8094B80, do_go_anim, npc_obj_ministep_stop_on_arrival, 1, 4) +an_walk_any_2_macro(sub_8094BC0, do_go_anim, npc_obj_ministep_stop_on_arrival, 2, 4) +an_walk_any_2_macro(sub_8094C00, do_go_anim, npc_obj_ministep_stop_on_arrival, 3, 4) +an_walk_any_2_macro(sub_8094C40, do_go_anim, npc_obj_ministep_stop_on_arrival, 4, 4) -- cgit v1.2.3 From 384ca4658b84168bc836a32ebd8b17ce70279555 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 10:29:57 -0400 Subject: yet more an_walk_any_2_macro functions --- src/field_map_obj.c | 66 ++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index c4847ae4f..5fd92199f 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4449,37 +4449,41 @@ bool8 sub_80945C4(struct MapObject *mapObject, struct Sprite *sprite) bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ {\ u8 animId;\ - animId = get_##images##_image_anim_num(direction);\ - sub_8094554(mapObject, sprite, direction, animId, duration);\ + animId = get_##images##_image_anim_num(DIR_##direction);\ + sub_8094554(mapObject, sprite, DIR_##direction, animId, duration);\ return timer(mapObject, sprite);\ } -special_anim_with_timer_2(sub_8094600, DIR_SOUTH, go, 32, sub_80945C4) -special_anim_with_timer_2(sub_8094638, DIR_NORTH, go, 32, sub_80945C4) -special_anim_with_timer_2(sub_8094670, DIR_WEST, go, 32, sub_80945C4) -special_anim_with_timer_2(sub_80946A8, DIR_EAST, go, 32, sub_80945C4) -special_anim_with_timer_2(sub_80946E0, DIR_SOUTH, go, 16, sub_809459C) -special_anim_with_timer_2(sub_8094718, DIR_NORTH, go, 16, sub_809459C) -special_anim_with_timer_2(sub_8094750, DIR_WEST, go, 16, sub_809459C) -special_anim_with_timer_2(sub_8094788, DIR_EAST, go, 16, sub_809459C) -special_anim_with_timer_2(sub_80947C0, DIR_SOUTH, go_fast, 8, sub_809459C) -special_anim_with_timer_2(sub_80947F8, DIR_NORTH, go_fast, 8, sub_809459C) -special_anim_with_timer_2(sub_8094830, DIR_WEST, go_fast, 8, sub_809459C) -special_anim_with_timer_2(sub_8094868, DIR_EAST, go_fast, 8, sub_809459C) -special_anim_with_timer_2(sub_80948A0, DIR_SOUTH, go_faster, 4, sub_809459C) -special_anim_with_timer_2(sub_80948D8, DIR_NORTH, go_faster, 4, sub_809459C) -special_anim_with_timer_2(sub_8094910, DIR_WEST, go_faster, 4, sub_809459C) -special_anim_with_timer_2(sub_8094948, DIR_EAST, go_faster, 4, sub_809459C) - -an_walk_any_2_macro(sub_8094980, do_go_anim, npc_obj_ministep_stop_on_arrival, 1, 2) -an_walk_any_2_macro(sub_80949C0, do_go_anim, npc_obj_ministep_stop_on_arrival, 2, 2) -an_walk_any_2_macro(sub_8094A00, do_go_anim, npc_obj_ministep_stop_on_arrival, 3, 2) -an_walk_any_2_macro(sub_8094A40, do_go_anim, npc_obj_ministep_stop_on_arrival, 4, 2) -an_walk_any_2_macro(sub_8094A80, do_go_anim, npc_obj_ministep_stop_on_arrival, 1, 3) -an_walk_any_2_macro(sub_8094AC0, do_go_anim, npc_obj_ministep_stop_on_arrival, 2, 3) -an_walk_any_2_macro(sub_8094B00, do_go_anim, npc_obj_ministep_stop_on_arrival, 3, 3) -an_walk_any_2_macro(sub_8094B40, do_go_anim, npc_obj_ministep_stop_on_arrival, 4, 3) -an_walk_any_2_macro(sub_8094B80, do_go_anim, npc_obj_ministep_stop_on_arrival, 1, 4) -an_walk_any_2_macro(sub_8094BC0, do_go_anim, npc_obj_ministep_stop_on_arrival, 2, 4) -an_walk_any_2_macro(sub_8094C00, do_go_anim, npc_obj_ministep_stop_on_arrival, 3, 4) -an_walk_any_2_macro(sub_8094C40, do_go_anim, npc_obj_ministep_stop_on_arrival, 4, 4) +special_anim_with_timer_2(sub_8094600, SOUTH, go, 32, sub_80945C4) +special_anim_with_timer_2(sub_8094638, NORTH, go, 32, sub_80945C4) +special_anim_with_timer_2(sub_8094670, WEST, go, 32, sub_80945C4) +special_anim_with_timer_2(sub_80946A8, EAST, go, 32, sub_80945C4) +special_anim_with_timer_2(sub_80946E0, SOUTH, go, 16, sub_809459C) +special_anim_with_timer_2(sub_8094718, NORTH, go, 16, sub_809459C) +special_anim_with_timer_2(sub_8094750, WEST, go, 16, sub_809459C) +special_anim_with_timer_2(sub_8094788, EAST, go, 16, sub_809459C) +special_anim_with_timer_2(sub_80947C0, SOUTH, go_fast, 8, sub_809459C) +special_anim_with_timer_2(sub_80947F8, NORTH, go_fast, 8, sub_809459C) +special_anim_with_timer_2(sub_8094830, WEST, go_fast, 8, sub_809459C) +special_anim_with_timer_2(sub_8094868, EAST, go_fast, 8, sub_809459C) +special_anim_with_timer_2(sub_80948A0, SOUTH, go_faster, 4, sub_809459C) +special_anim_with_timer_2(sub_80948D8, NORTH, go_faster, 4, sub_809459C) +special_anim_with_timer_2(sub_8094910, WEST, go_faster, 4, sub_809459C) +special_anim_with_timer_2(sub_8094948, EAST, go_faster, 4, sub_809459C) + +an_walk_any_2_macro(sub_8094980, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_SOUTH, 2) +an_walk_any_2_macro(sub_80949C0, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_NORTH, 2) +an_walk_any_2_macro(sub_8094A00, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_WEST, 2) +an_walk_any_2_macro(sub_8094A40, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_EAST, 2) +an_walk_any_2_macro(sub_8094A80, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_SOUTH, 3) +an_walk_any_2_macro(sub_8094AC0, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_NORTH, 3) +an_walk_any_2_macro(sub_8094B00, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_WEST, 3) +an_walk_any_2_macro(sub_8094B40, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_EAST, 3) +an_walk_any_2_macro(sub_8094B80, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_SOUTH, 4) +an_walk_any_2_macro(sub_8094BC0, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_NORTH, 4) +an_walk_any_2_macro(sub_8094C00, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_WEST, 4) +an_walk_any_2_macro(sub_8094C40, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_EAST, 4) +an_walk_any_2_macro(sub_8094C80, do_run_anim, npc_obj_ministep_stop_on_arrival, DIR_SOUTH) +an_walk_any_2_macro(sub_8094CC0, do_run_anim, npc_obj_ministep_stop_on_arrival, DIR_NORTH) +an_walk_any_2_macro(sub_8094D00, do_run_anim, npc_obj_ministep_stop_on_arrival, DIR_WEST) +an_walk_any_2_macro(sub_8094D40, do_run_anim, npc_obj_ministep_stop_on_arrival, DIR_EAST) -- cgit v1.2.3 From 9b4c61658a6a5d164ba67d6434be94540601cc83 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 10:58:24 -0400 Subject: npc_set_direction_and_anim__an_proceed --- src/field_map_obj.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 5fd92199f..e1ba386e0 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4487,3 +4487,26 @@ an_walk_any_2_macro(sub_8094C80, do_run_anim, npc_obj_ministep_stop_on_arrival, an_walk_any_2_macro(sub_8094CC0, do_run_anim, npc_obj_ministep_stop_on_arrival, DIR_NORTH) an_walk_any_2_macro(sub_8094D00, do_run_anim, npc_obj_ministep_stop_on_arrival, DIR_WEST) an_walk_any_2_macro(sub_8094D40, do_run_anim, npc_obj_ministep_stop_on_arrival, DIR_EAST) + +void npc_set_direction_and_anim__an_proceed(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 animNum) +{ + obj_anim_image_set_and_seek(sprite, animNum, 0); + FieldObjectSetDirection(mapObject, direction); + sprite->data2 = 1; +} + +bool8 sub_8094DAC(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_set_direction_and_anim__an_proceed(mapObject, sprite, mapObject->placeholder18, sprite->animNum); + return FALSE; +} + +bool8 sub_8094DC4(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_80979BC(sprite)) + { + sprite->data2 = 2; + return TRUE; + } + return FALSE; +} -- cgit v1.2.3 From 75595f9b3dfc57707183dae5d842ba21a8c2ff7f Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sun, 17 Sep 2017 17:14:32 +0200 Subject: decompile battle 3 --- src/battle_3.c | 1006 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1006 insertions(+) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index 09c401a5c..af3d4ebdd 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -14,6 +14,7 @@ #include "string_util.h" #include "battle_message.h" #include "battle_ai.h" +#include "event_data.h" extern const u8* gBattlescriptCurrInstr; extern const u8* gUnknown_02024220[BATTLE_BANKS_COUNT]; @@ -47,8 +48,14 @@ extern u8 gBattleMoveFlags; extern s32 gTakenDmg[BATTLE_BANKS_COUNT]; extern u8 gTakenDmgBanks[BATTLE_BANKS_COUNT]; extern u8 gLastUsedAbility; +extern u8 gFightStateTracker; +extern u32 gBattleExecBuffer; +extern u16 gRandomMove; +extern u8 gCurrMovePos; +extern u8 gUnknown_020241E9; extern const struct BattleMove gBattleMoves[]; +extern void (* const gBattleScriptingCommandsTable[])(void); // scripts extern const u8 gUnknown_082DAE2A[]; @@ -132,6 +139,35 @@ extern const u8 gUnknown_082DB4B8[]; extern const u8 gUnknown_082DB4C1[]; extern const u8 BattleScript_TraceActivates[]; +extern const u8 BattleScript_WhiteHerbEnd2[]; +extern const u8 BattleScript_WhiteHerbRet[]; +extern const u8 BattleScript_ItemHealHP_RemoveItem[]; +extern const u8 BattleScript_BerryPPHealEnd2[]; +extern const u8 BattleScript_ItemHealHP_End2[]; +extern const u8 BattleScript_BerryConfuseHealEnd2[]; +extern const u8 BattleScript_BerryStatRaiseEnd2[]; +extern const u8 BattleScript_BerryFocusEnergyEnd2[]; +extern const u8 BattleScript_BerryCurePrlzEnd2[]; +extern const u8 BattleScript_BerryCurePsnEnd2[]; +extern const u8 BattleScript_BerryCureBrnEnd2[]; +extern const u8 BattleScript_BerryCureFrzEnd2[]; +extern const u8 BattleScript_BerryCureSlpEnd2[]; +extern const u8 BattleScript_BerryCureConfusionEnd2[]; +extern const u8 BattleScript_BerryCureChosenStatusEnd2[]; +extern const u8 BattleScript_BerryCureParRet[]; +extern const u8 BattleScript_BerryCurePsnRet[]; +extern const u8 BattleScript_BerryCureBrnRet[]; +extern const u8 BattleScript_BerryCureFrzRet[]; +extern const u8 BattleScript_BerryCureSlpRet[]; +extern const u8 BattleScript_BerryCureConfusionRet[]; +extern const u8 BattleScript_BerryCureChosenStatusRet[]; +extern const u8 BattleScript_ItemHealHP_Ret[]; + +extern const u8 gUnknown_082DB695[]; //disobedient while asleep +extern const u8 gUnknown_082DB6A5[]; //disobedient, uses a random move +extern const u8 gUnknown_082DB6D9[]; //disobedient, went to sleep +extern const u8 gUnknown_082DB6F0[]; //disobedient, hits itself + extern const u8 gStatusConditionString_PoisonJpn[]; extern const u8 gStatusConditionString_SleepJpn[]; extern const u8 gStatusConditionString_ParalysisJpn[]; @@ -159,6 +195,9 @@ extern u8 GetBankByPlayerAI(u8); extern u8 sub_806D864(u8); extern u8 sub_806D82C(u8); extern u8 weather_get_current(void); +extern void sub_803E08C(void); +extern void bc_move_exec_returning(void); +extern s8 GetFlavourRelationByPersonality(u32 personality, u8 flavor); u8 IsImprisoned(u8 bank, u16 move); u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn); @@ -5423,3 +5462,970 @@ _0804443A:\n\ .syntax divided"); } #endif // NONMATCHING + +void b_call_bc_move_exec(const u8* BS_ptr) +{ + gBattlescriptCurrInstr = BS_ptr; + BATTLE_CALLBACKS_STACK->function[BATTLE_CALLBACKS_STACK->size++] = gBattleMainFunc; + gBattleMainFunc = bc_move_exec_returning; + gFightStateTracker = 0; +} + +void b_push_move_exec(const u8* BS_ptr) +{ + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BS_ptr; + BATTLE_CALLBACKS_STACK->function[BATTLE_CALLBACKS_STACK->size++] = gBattleMainFunc; + gBattleMainFunc = sub_803E08C; +} + +enum +{ + ITEM_NO_EFFECT, // 0 + ITEM_STATUS_CHANGE, // 1 + ITEM_EFFECT_OTHER, // 2 + ITEM_PP_CHANGE, // 3 + ITEM_HP_CHANGE, // 4 + ITEM_STATS_CHANGE, // 5 +}; + +enum +{ + FLAVOR_SPICY, // 0 + FLAVOR_DRY, // 1 + FLAVOR_SWEET, // 2 + FLAVOR_BITTER, // 3 + FLAVOR_SOUR, // 4 +}; + +u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) +{ + int i = 0; + u8 effect = ITEM_NO_EFFECT; + u8 changedPP = 0; + u8 bankHoldEffect, atkHoldEffect, defHoldEffect; + u8 bankQuality, atkQuality, defQuality; + u16 atkItem, defItem; + + gLastUsedItem = gBattleMons[bank].item; + if (gLastUsedItem == ITEM_ENIGMA_BERRY) + { + bankHoldEffect = gEnigmaBerries[bank].holdEffect; + bankQuality = gEnigmaBerries[bank].holdEffectParam; + } + else + { + bankHoldEffect = ItemId_GetHoldEffect(gLastUsedItem); + bankQuality = ItemId_GetHoldEffectParam(gLastUsedItem); + } + + atkItem = gBattleMons[gBankAttacker].item; + if (atkItem == ITEM_ENIGMA_BERRY) + { + atkHoldEffect = gEnigmaBerries[gBankAttacker].holdEffect; + atkQuality = gEnigmaBerries[gBankAttacker].holdEffectParam; + } + else + { + atkHoldEffect = ItemId_GetHoldEffect(atkItem); + atkQuality = ItemId_GetHoldEffectParam(atkItem); + } + + // def variables are unused + defItem = gBattleMons[gBankTarget].item; + if (defItem == ITEM_ENIGMA_BERRY) + { + defHoldEffect = gEnigmaBerries[gBankTarget].holdEffect; + defQuality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + defHoldEffect = ItemId_GetHoldEffect(defItem); + defQuality = ItemId_GetHoldEffectParam(defItem); + } + + switch (caseID) + { + case 0: + switch (bankHoldEffect) + { + case HOLD_EFFECT_DOUBLE_PRIZE: + if (GetBankSide(bank) == SIDE_PLAYER) + gBattleStruct->moneyMultiplier = 2; + break; + case HOLD_EFFECT_RESTORE_STATS: + for (i = 0; i < 8; i++) + { + if (gBattleMons[bank].statStages[i] < 6) + { + gBattleMons[bank].statStages[i] = 6; + effect = ITEM_STATS_CHANGE; + } + } + if (effect) + { + gBattleScripting.bank = bank; + gStringBank = bank; + gActiveBank = gBankAttacker = bank; + b_call_bc_move_exec(BattleScript_WhiteHerbEnd2); + } + break; + } + break; + case 1: + if (gBattleMons[bank].hp) + { + switch (bankHoldEffect) + { + case HOLD_EFFECT_RESTORE_HP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleMoveDamage = bankQuality; + if (gBattleMons[bank].hp + bankQuality > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + effect = 4; + } + break; + case HOLD_EFFECT_RESTORE_PP: + if (!moveTurn) + { + struct Pokemon* poke; + u8 ppBonuses; + u16 move; + + if (GetBankSide(bank) == 0) + poke = &gPlayerParty[gBattlePartyID[bank]]; + else + poke = &gEnemyParty[gBattlePartyID[bank]]; + for (i = 0; i < 4; i++) + { + move = GetMonData(poke, MON_DATA_MOVE1 + i); + changedPP = GetMonData(poke, MON_DATA_PP1 + i); + ppBonuses = GetMonData(poke, MON_DATA_PP_BONUSES); + if (move && changedPP == 0) + break; + } + if (i != 4) + { + u8 maxPP = CalculatePPWithBonus(move, ppBonuses, i); + if (changedPP + bankQuality > maxPP) + changedPP = maxPP; + else + changedPP = changedPP + bankQuality; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = move; + gBattleTextBuff1[3] = move >> 8; + gBattleTextBuff1[4] = 0xFF; + b_call_bc_move_exec(BattleScript_BerryPPHealEnd2); + EmitSetAttributes(0, i + REQUEST_PPMOVE1_BATTLE, 0, 1, &changedPP); + MarkBufferBankForExecution(gActiveBank); + effect = ITEM_PP_CHANGE; + } + } + break; + case HOLD_EFFECT_RESTORE_STATS: + for (i = 0; i < 8; i++) + { + if (gBattleMons[bank].statStages[i] < 6) + { + gBattleMons[bank].statStages[i] = 6; + effect = ITEM_STATS_CHANGE; + } + } + if (effect) + { + gBattleScripting.bank = bank; + gStringBank = bank; + gActiveBank = gBankAttacker = bank; + b_call_bc_move_exec(BattleScript_WhiteHerbEnd2); + } + break; + case HOLD_EFFECT_LEFTOVERS: + if (gBattleMons[bank].hp < gBattleMons[bank].maxHP && !moveTurn) + { + gBattleMoveDamage = gBattleMons[bank].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + b_call_bc_move_exec(BattleScript_ItemHealHP_End2); + effect = ITEM_HP_CHANGE; + RecordItemEffectBattle(bank, bankHoldEffect); + } + break; + // nice copy/paste there gamefreak, making a function for confuse berries was too much eh? + case HOLD_EFFECT_CONFUSE_SPICY: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 8; + gBattleTextBuff1[2] = FLAVOR_SPICY; + gBattleTextBuff1[3] = EOS; + gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + if (GetFlavourRelationByPersonality(gBattleMons[bank].personality, FLAVOR_SPICY) < 0) + b_call_bc_move_exec(BattleScript_BerryConfuseHealEnd2); + else + b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + effect = ITEM_HP_CHANGE; + } + break; + case HOLD_EFFECT_CONFUSE_DRY: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 8; + gBattleTextBuff1[2] = FLAVOR_DRY; + gBattleTextBuff1[3] = EOS; + gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + if (GetFlavourRelationByPersonality(gBattleMons[bank].personality, FLAVOR_DRY) < 0) + b_call_bc_move_exec(BattleScript_BerryConfuseHealEnd2); + else + b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + effect = ITEM_HP_CHANGE; + } + break; + case HOLD_EFFECT_CONFUSE_SWEET: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 8; + gBattleTextBuff1[2] = FLAVOR_SWEET; + gBattleTextBuff1[3] = EOS; + gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + if (GetFlavourRelationByPersonality(gBattleMons[bank].personality, FLAVOR_SWEET) < 0) + b_call_bc_move_exec(BattleScript_BerryConfuseHealEnd2); + else + b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + effect = ITEM_HP_CHANGE; + } + break; + case HOLD_EFFECT_CONFUSE_BITTER: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 8; + gBattleTextBuff1[2] = FLAVOR_BITTER; + gBattleTextBuff1[3] = EOS; + gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + if (GetFlavourRelationByPersonality(gBattleMons[bank].personality, FLAVOR_BITTER) < 0) + b_call_bc_move_exec(BattleScript_BerryConfuseHealEnd2); + else + b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + effect = ITEM_HP_CHANGE; + } + break; + case HOLD_EFFECT_CONFUSE_SOUR: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 8; + gBattleTextBuff1[2] = FLAVOR_SOUR; + gBattleTextBuff1[3] = EOS; + gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + if (GetFlavourRelationByPersonality(gBattleMons[bank].personality, FLAVOR_SOUR) < 0) + b_call_bc_move_exec(BattleScript_BerryConfuseHealEnd2); + else + b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + effect = ITEM_HP_CHANGE; + } + break; + // copy/paste again, smh + case HOLD_EFFECT_ATTACK_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_ATK] < 0xC) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = STAT_STAGE_ATK; + gBattleTextBuff1[3] = EOS; + + gBattleTextBuff2[0] = 0xFD; + gBattleTextBuff2[1] = 0; + gBattleTextBuff2[2] = 0xD2; + gBattleTextBuff2[3] = 0xD2 >> 8; + gBattleTextBuff2[4] = EOS; + + gEffectBank = bank; + gBattleScripting.statChanger = 0x10 + STAT_STAGE_ATK; + gBattleScripting.animArg1 = 0xE + STAT_STAGE_ATK; + gBattleScripting.animArg2 = 0; + b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + break; + case HOLD_EFFECT_DEFENSE_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_DEF] < 0xC) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = STAT_STAGE_DEF; + gBattleTextBuff1[3] = EOS; + + gEffectBank = bank; + gBattleScripting.statChanger = 0x10 + STAT_STAGE_DEF; + gBattleScripting.animArg1 = 0xE + STAT_STAGE_DEF; + gBattleScripting.animArg2 = 0; + b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + break; + case HOLD_EFFECT_SPEED_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = STAT_STAGE_SPEED; + gBattleTextBuff1[3] = EOS; + + gEffectBank = bank; + gBattleScripting.statChanger = 0x10 + STAT_STAGE_SPEED; + gBattleScripting.animArg1 = 0xE + STAT_STAGE_SPEED; + gBattleScripting.animArg2 = 0; + b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + break; + case HOLD_EFFECT_SP_ATTACK_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPATK] < 0xC) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = STAT_STAGE_SPATK; + gBattleTextBuff1[3] = EOS; + + gEffectBank = bank; + gBattleScripting.statChanger = 0x10 + STAT_STAGE_SPATK; + gBattleScripting.animArg1 = 0xE + STAT_STAGE_SPATK; + gBattleScripting.animArg2 = 0; + b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + break; + case HOLD_EFFECT_SP_DEFENSE_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPDEF] < 0xC) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = STAT_STAGE_SPDEF; + gBattleTextBuff1[3] = EOS; + + gEffectBank = bank; + gBattleScripting.statChanger = 0x10 + STAT_STAGE_SPDEF; + gBattleScripting.animArg1 = 0xE + STAT_STAGE_SPDEF; + gBattleScripting.animArg2 = 0; + b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + break; + case HOLD_EFFECT_CRITICAL_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && !(gBattleMons[bank].status2 & STATUS2_FOCUS_ENERGY)) + { + gBattleMons[bank].status2 |= STATUS2_FOCUS_ENERGY; + b_call_bc_move_exec(BattleScript_BerryFocusEnergyEnd2); + effect = ITEM_EFFECT_OTHER; + } + break; + case HOLD_EFFECT_RANDOM_STAT_UP: + if (!moveTurn && gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality) + { + for (i = 0; i < 5; i++) + { + if (gBattleMons[bank].statStages[STAT_STAGE_ATK + i] < 0xC) + break; + } + if (i != 5) + { + do + { + i = Random() % 5; + } while (gBattleMons[bank].statStages[STAT_STAGE_ATK + i] == 0xC); + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = i + 1; + gBattleTextBuff1[3] = EOS; + + gBattleTextBuff2[0] = 0xFD; + gBattleTextBuff2[1] = 0; + gBattleTextBuff2[2] = 0xD1; + gBattleTextBuff2[3] = 0xD1 >> 8; + gBattleTextBuff2[4] = 0; + gBattleTextBuff2[5] = 0xD2; + gBattleTextBuff2[6] = 0xD2 >> 8; + gBattleTextBuff2[7] = EOS; + + gEffectBank = bank; + gBattleScripting.statChanger = 0x21 + i; + gBattleScripting.animArg1 = 0x21 + i + 6; + gBattleScripting.animArg2 = 0; + b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + } + break; + case HOLD_EFFECT_CURE_PAR: + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + { + gBattleMons[bank].status1 &= ~(STATUS_PARALYSIS); + b_call_bc_move_exec(BattleScript_BerryCurePrlzEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_PSN: + if (gBattleMons[bank].status1 & STATUS_PSN_ANY) + { + gBattleMons[bank].status1 &= ~(STATUS_PSN_ANY | STATUS_TOXIC_COUNTER); + b_call_bc_move_exec(BattleScript_BerryCurePsnEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_BRN: + if (gBattleMons[bank].status1 & STATUS_BURN) + { + gBattleMons[bank].status1 &= ~(STATUS_BURN); + b_call_bc_move_exec(BattleScript_BerryCureBrnEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_FRZ: + if (gBattleMons[bank].status1 & STATUS_FREEZE) + { + gBattleMons[bank].status1 &= ~(STATUS_FREEZE); + b_call_bc_move_exec(BattleScript_BerryCureFrzEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_SLP: + if (gBattleMons[bank].status1 & STATUS_SLEEP) + { + gBattleMons[bank].status1 &= ~(STATUS_SLEEP); + gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + b_call_bc_move_exec(BattleScript_BerryCureSlpEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_CONFUSION: + if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + b_call_bc_move_exec(BattleScript_BerryCureConfusionEnd2); + effect = ITEM_EFFECT_OTHER; + } + break; + case HOLD_EFFECT_CURE_STATUS: + if (gBattleMons[bank].status1 & STATUS_ANY || gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + i = 0; + if (gBattleMons[bank].status1 & STATUS_PSN_ANY) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); + i++; + } + if (gBattleMons[bank].status1 & STATUS_SLEEP) + { + gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); + i++; + } + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); + i++; + } + if (gBattleMons[bank].status1 & STATUS_BURN) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); + i++; + } + if (gBattleMons[bank].status1 & STATUS_FREEZE) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); + i++; + } + if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); + i++; + } + if (!(i > 1)) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBattleMons[bank].status1 = 0; + gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + b_call_bc_move_exec(BattleScript_BerryCureChosenStatusEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_ATTRACT: + if (gBattleMons[bank].status2 & STATUS2_INFATUATION) + { + gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); + StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); + b_call_bc_move_exec(BattleScript_BerryCureChosenStatusEnd2); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + effect = ITEM_EFFECT_OTHER; + } + break; + } + if (effect) + { + gBattleScripting.bank = bank; + gStringBank = bank; + gActiveBank = gBankAttacker = bank; + switch (effect) + { + case ITEM_STATUS_CHANGE: + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); + MarkBufferBankForExecution(gActiveBank); + break; + case ITEM_PP_CHANGE: + if (!(gBattleMons[bank].status2 & STATUS2_TRANSFORMED) && !(gDisableStructs[bank].unk18_b & gBitTable[i])) + gBattleMons[bank].pp[i] = changedPP; + break; + } + } + } + break; + case 2: + break; + case 3: + for (bank = 0; bank < gNoOfAllBanks; bank++) + { + gLastUsedItem = gBattleMons[bank].item; + if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY) + { + bankHoldEffect = gEnigmaBerries[bank].holdEffect; + bankQuality = gEnigmaBerries[bank].holdEffectParam; + } + else + { + bankHoldEffect = ItemId_GetHoldEffect(gLastUsedItem); + bankQuality = ItemId_GetHoldEffectParam(gLastUsedItem); + } + switch (bankHoldEffect) + { + case HOLD_EFFECT_CURE_PAR: + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + { + gBattleMons[bank].status1 &= ~(STATUS_PARALYSIS); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_BerryCureParRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_PSN: + if (gBattleMons[bank].status1 & STATUS_PSN_ANY) + { + gBattleMons[bank].status1 &= ~(STATUS_PSN_ANY | STATUS_TOXIC_COUNTER); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_BerryCurePsnRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_BRN: + if (gBattleMons[bank].status1 & STATUS_BURN) + { + gBattleMons[bank].status1 &= ~(STATUS_BURN); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_BerryCureBrnRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_FRZ: + if (gBattleMons[bank].status1 & STATUS_FREEZE) + { + gBattleMons[bank].status1 &= ~(STATUS_FREEZE); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_BerryCureFrzRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_SLP: + if (gBattleMons[bank].status1 & STATUS_SLEEP) + { + gBattleMons[bank].status1 &= ~(STATUS_SLEEP); + gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_CONFUSION: + if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_BerryCureConfusionRet; + effect = ITEM_EFFECT_OTHER; + } + break; + case HOLD_EFFECT_CURE_ATTRACT: + if (gBattleMons[bank].status2 & STATUS2_INFATUATION) + { + gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); + StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); + b_movescr_stack_push_cursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet; + effect = ITEM_EFFECT_OTHER; + } + break; + case HOLD_EFFECT_CURE_STATUS: + if (gBattleMons[bank].status1 & STATUS_ANY || gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + if (gBattleMons[bank].status1 & STATUS_PSN_ANY) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); + } + if (gBattleMons[bank].status1 & STATUS_SLEEP) + { + gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); + } + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); + } + if (gBattleMons[bank].status1 & STATUS_BURN) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); + } + if (gBattleMons[bank].status1 & STATUS_FREEZE) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); + } + if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); + } + gBattleMons[bank].status1 = 0; + gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + b_movescr_stack_push_cursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_RESTORE_STATS: + for (i = 0; i < 8; i++) + { + if (gBattleMons[bank].statStages[i] < 6) + { + gBattleMons[bank].statStages[i] = 6; + effect = ITEM_STATS_CHANGE; + } + } + if (effect) + { + gBattleScripting.bank = bank; + gStringBank = bank; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_WhiteHerbRet; + return effect; // unnecessary return + } + break; + } + if (effect) + { + gBattleScripting.bank = bank; + gStringBank = bank; + gActiveBank = bank; + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + break; + } + } + break; + case 4: + if (gBattleMoveDamage) + { + switch (atkHoldEffect) + { + case HOLD_EFFECT_FLINCH: + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT) + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (Random() % 100) < atkQuality + && gBattleMoves[gCurrentMove].flags & FLAG_KINGSROCK_AFFECTED + && gBattleMons[gBankTarget].hp) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 8; + b_movescr_stack_push_cursor(); + SetMoveEffect(0, 0); + b_movescr_stack_pop_cursor(); + } + break; + case HOLD_EFFECT_SHELL_BELL: + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT) + && gSpecialStatuses[gBankTarget].moveturnLostHP != 0 + && gSpecialStatuses[gBankTarget].moveturnLostHP != 0xFFFF + && gBankAttacker != gBankTarget + && gBattleMons[gBankAttacker].hp != gBattleMons[gBankAttacker].maxHP + && gBattleMons[gBankAttacker].hp != 0) + { + gLastUsedItem = atkItem; + gStringBank = gBankAttacker; + gBattleScripting.bank = gBankAttacker; + gBattleMoveDamage = (gSpecialStatuses[gBankTarget].moveturnLostHP / atkQuality) * -1; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = -1; + gSpecialStatuses[gBankTarget].moveturnLostHP = 0; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_ItemHealHP_Ret; + effect++; + } + break; + } + } + break; + } + + return effect; +} + +void sub_8045868(u8 bank) +{ + gDisableStructs[bank].furyCutterCounter = 0; + gBattleMons[bank].status2 &= ~(STATUS2_DESTINY_BOND); + gStatuses3[bank] &= ~(STATUS3_GRUDGE); +} + +void sub_80458B4(void) +{ + if (gBattleExecBuffer == 0) + gBattleScriptingCommandsTable[*gBattlescriptCurrInstr](); +} + +u8 GetMoveTarget(u16 move, u8 useMoveTarget) +{ + u8 targetBank = 0; + u8 moveTarget; + u8 side; + + if (useMoveTarget) + moveTarget = useMoveTarget - 1; + else + moveTarget = gBattleMoves[move].target; + + switch (moveTarget) + { + case 0: + side = GetBankSide(gBankAttacker) ^ 1; + if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp) + targetBank = gSideTimers[side].followmeTarget; + else + { + side = GetBankSide(gBankAttacker); + do + { + targetBank = Random() % gNoOfAllBanks; + } while (targetBank == gBankAttacker || side == GetBankSide(targetBank) || gAbsentBankFlags & gBitTable[targetBank]); + if (gBattleMoves[move].type == TYPE_ELECTRIC + && AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIZE, gBankAttacker, ABILITY_LIGHTNING_ROD, 0, 0) + && gBattleMons[targetBank].ability != ABILITY_LIGHTNING_ROD) + { + targetBank ^= 2; + RecordAbilityBattle(targetBank, gBattleMons[targetBank].ability); + gSpecialStatuses[targetBank].lightningRodRedirected = 1; + } + } + break; + case 1: + case 8: + case 32: + case 64: + targetBank = GetBankByPlayerAI((GetBankIdentity(gBankAttacker) & 1) ^ 1); + if (gAbsentBankFlags & gBitTable[targetBank]) + targetBank ^= 2; + break; + case 4: + side = GetBankSide(gBankAttacker) ^ 1; + if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp) + targetBank = gSideTimers[side].followmeTarget; + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & 4) + { + if (GetBankSide(gBankAttacker) == 0) + { + if (Random() & 1) + targetBank = GetBankByPlayerAI(1); + else + targetBank = GetBankByPlayerAI(3); + } + else + { + if (Random() & 1) + targetBank = GetBankByPlayerAI(0); + else + targetBank = GetBankByPlayerAI(2); + } + if (gAbsentBankFlags & gBitTable[targetBank]) + targetBank ^= 2; + } + else + targetBank = GetBankByPlayerAI((GetBankIdentity(gBankAttacker) & 1) ^ 1); + break; + case 2: + case 16: + targetBank = gBankAttacker; + break; + } + + #ifndef NONMATCHING + MEME_ACCESS_U8(BattleStruct, gBattleStruct, gBankAttacker, moveTarget, targetBank); + #else + gBattleStruct->moveTarget[gBankAttacker] = targetBank; + #endif // NONMATCHING + + return targetBank; +} + +static bool32 HasObedientBitSet(u8 bank) +{ + if (GetBankSide(bank) == SIDE_OPPONENT) + return TRUE; + if (GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS + && GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_SPECIES, NULL) != SPECIES_MEW) + return TRUE; + return GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_OBEDIENCE, NULL); +} + +u8 IsPokeDisobedient(void) +{ + s32 rnd; + s32 calc; + u8 obedienceLevel = 0; + + if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) + return 0; + if (GetBankSide(gBankAttacker) == SIDE_OPPONENT) + return 0; + + if (HasObedientBitSet(gBankAttacker)) // only if species is Mew or Deoxys + { + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && GetBankIdentity(gBankAttacker) == 2) + return 0; + if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) + return 0; + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + return 0; + if (!IsOtherTrainer(gBattleMons[gBankAttacker].otId, gBattleMons[gBankAttacker].otName)) + return 0; + if (FlagGet(BADGE08_GET)) + return 0; + + obedienceLevel = 10; + + if (FlagGet(BADGE02_GET)) + obedienceLevel = 30; + if (FlagGet(BADGE04_GET)) + obedienceLevel = 50; + if (FlagGet(BADGE06_GET)) + obedienceLevel = 70; + } + + if (gBattleMons[gBankAttacker].level <= obedienceLevel) + return 0; + rnd = (Random() & 255); + calc = (gBattleMons[gBankAttacker].level + obedienceLevel) * rnd >> 8; + if (calc < obedienceLevel) + return 0; + + // is not obedient + if (gCurrentMove == MOVE_RAGE) + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_RAGE); + if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP && (gCurrentMove == MOVE_SNORE || gCurrentMove == MOVE_SLEEP_TALK)) + { + gBattlescriptCurrInstr = gUnknown_082DB695; + return 1; + } + + rnd = (Random() & 255); + calc = (gBattleMons[gBankAttacker].level + obedienceLevel) * rnd >> 8; + if (calc < obedienceLevel) + { + calc = CheckMoveLimitations(gBankAttacker, gBitTable[gCurrMovePos], 0xFF); + if (calc == 0xF) // all moves cannot be used + { + gBattleCommunication[MULTISTRING_CHOOSER] = Random() & 3; + gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; + return 1; + } + else // use a random move + { + do + { + gCurrMovePos = gUnknown_020241E9 = Random() & 3; + } while (gBitTable[gCurrMovePos] & calc); + + gRandomMove = gBattleMons[gBankAttacker].moves[gCurrMovePos]; + gBattlescriptCurrInstr = gUnknown_082DB6A5; + gBankTarget = GetMoveTarget(gRandomMove, 0); + gHitMarker |= HITMARKER_x200000; + return 2; + } + } + else + { + obedienceLevel = gBattleMons[gBankAttacker].level - obedienceLevel; + + calc = (Random() & 255); + if (calc < obedienceLevel && !(gBattleMons[gBankAttacker].status1 & STATUS_ANY) && gBattleMons[gBankAttacker].ability != ABILITY_VITAL_SPIRIT && gBattleMons[gBankAttacker].ability != ABILITY_INSOMNIA) + { + // try putting asleep + int i; + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleMons[i].status2 & STATUS2_UPROAR) + break; + } + if (i == gNoOfAllBanks) + { + gBattlescriptCurrInstr = gUnknown_082DB6D9; + return 1; + } + } + calc -= obedienceLevel; + if (calc < obedienceLevel) + { + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankAttacker], MOVE_POUND, 0, 40, 0, gBankAttacker, gBankAttacker); + gBankTarget = gBankAttacker; + gBattlescriptCurrInstr = gUnknown_082DB6F0; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + return 2; + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = Random() & 3; + gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; + return 1; + } + } +} -- cgit v1.2.3 From 3356a4fb923d73bba9422b564bc1c0ef7e62f47c Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 11:39:49 -0400 Subject: Failed attempt to fix InitFieldObjectStateFromTemplate, but at least we fixed the weirdness with the double MapObject structs --- src/field_map_obj.c | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index e1ba386e0..9f01e87df 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -117,7 +117,7 @@ static u32 state_to_direction(u8, u32, u32); static void FieldObjectExecSpecialAnim(struct MapObject *, struct Sprite *); /*static*/ void npc_obj_transfer_image_anim_pause_flag(struct MapObject *, struct Sprite *); -static bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *, s16, s16); +static bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject *, s16, s16); static bool8 IsMetatileDirectionallyImpassable(struct MapObject *, s16, s16, u8); static bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *, s16, s16); @@ -253,14 +253,15 @@ static u8 GetFieldObjectIdByLocalId(u8 localId) // This function has the same nonmatching quirk as in Ruby/Sapphire. #ifdef NONMATCHING -static u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId) +static u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapNum, u8 mapGroup) { - u8 slot; struct MapObject *mapObject; - u16 x; - u16 y; + s16 x; + s16 y; + u8 slot; - if (GetAvailableFieldObjectSlot(template->localId, mapId, mapGroupId, &slot)) + // mapNum and mapGroup are in the wrong registers (r7/r6 instead of r6/r7) + if (GetAvailableFieldObjectSlot(template->localId, mapNum, mapGroup, &slot)) { return NUM_FIELD_OBJECTS; } @@ -273,8 +274,8 @@ static u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u mapObject->graphicsId = template->graphicsId; mapObject->animPattern = template->movementType; mapObject->localId = template->localId; - mapObject->mapNum = mapId; - mapObject->mapGroup = mapGroupId; + mapObject->mapNum = mapNum; + mapObject->mapGroup = mapGroup; mapObject->coords1.x = x; mapObject->coords1.y = y; mapObject->coords2.x = x; @@ -283,24 +284,25 @@ static u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u mapObject->coords3.y = y; mapObject->mapobj_unk_0B_0 = template->elevation; mapObject->elevation = template->elevation; - mapObject->mapobj_unk_19 = template->unkA_0; - mapObject->mapobj_unk_19b = template->unkA_4; + // For some reason, 0x0F is placed in r9, to be used later + mapObject->range.as_nybbles.x = template->unkA_0; + mapObject->range.as_nybbles.y = template->unkA_4; mapObject->trainerType = template->unkC; mapObject->trainerRange_berryTreeId = template->unkE; mapObject->mapobj_unk_20 = gUnknown_085055CD[template->movementType]; FieldObjectSetDirection(mapObject, mapObject->mapobj_unk_20); FieldObjectHandleDynamicGraphicsId(mapObject); - // This block is the culprit if (gUnknown_0850557C[mapObject->animPattern]) { - if (mapObject->mapobj_unk_19 == 0) + if ((mapObject->range.as_nybbles.x) == 0) { - mapObject->mapobj_unk_19 ++; + // r9 is invoked here + mapObject->range.as_nybbles.x ++; } - if (mapObject->mapobj_unk_19b == 0) + if ((mapObject->range.as_nybbles.y) == 0) { - mapObject->mapobj_unk_19b ++; + mapObject->range.as_nybbles.y ++; } } return slot; @@ -3654,7 +3656,7 @@ u8 npc_block_way(struct MapObject *mapObject, s16 x, s16 y, u32 dirn) u8 direction; direction = dirn; - if (IsCoordOutsideFieldObjectMovementRect((struct MapObject2 *)mapObject, x, y)) + if (IsCoordOutsideFieldObjectMovementRect(mapObject, x, y)) { return 1; } @@ -3682,7 +3684,7 @@ u8 sub_8092C8C(struct MapObject *mapObject, s16 x, s16 y, u8 direction) u8 retval; retval = 0x00; - if (IsCoordOutsideFieldObjectMovementRect((struct MapObject2 *)mapObject, x, y)) + if (IsCoordOutsideFieldObjectMovementRect(mapObject, x, y)) { retval |= 1; } @@ -3701,26 +3703,26 @@ u8 sub_8092C8C(struct MapObject *mapObject, s16 x, s16 y, u8 direction) return retval; } -static bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *mapObject, s16 x, s16 y) +static bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject *mapObject, s16 x, s16 y) { s16 left; s16 right; s16 top; s16 bottom; - if (mapObject->mapobj_unk_19 != 0) + if (mapObject->range.as_nybbles.x != 0) { - left = mapObject->coords1.x - mapObject->mapobj_unk_19; - right = mapObject->coords1.x + mapObject->mapobj_unk_19; + left = mapObject->coords1.x - mapObject->range.as_nybbles.x; + right = mapObject->coords1.x + mapObject->range.as_nybbles.x; if (left > x || right < x) { return TRUE; } } - if (mapObject->mapobj_unk_19b != 0) + if (mapObject->range.as_nybbles.y != 0) { - top = mapObject->coords1.y - mapObject->mapobj_unk_19b; - bottom = mapObject->coords1.y + mapObject->mapobj_unk_19b; + top = mapObject->coords1.y - mapObject->range.as_nybbles.y; + bottom = mapObject->coords1.y + mapObject->range.as_nybbles.y; if (top > y || bottom < y) { return TRUE; -- cgit v1.2.3 From 20152fb0aff7e4e7de34be319f6ce120ae09aaa1 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 12:19:35 -0400 Subject: Yet Another Macro Cluster TM --- src/field_map_obj.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 9f01e87df..1d91184ec 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4512,3 +4512,32 @@ bool8 sub_8094DC4(struct MapObject *mapObject, struct Sprite *sprite) } return FALSE; } + +void sub_8094DE4(struct MapObject *mapObject, struct Sprite *sprite, u8 direction) +{ + sub_8093FC4(mapObject, sprite, direction, 1, 0); + StartSpriteAnim(sprite, sub_80929AC(direction)); +} + +#define unk_macro_8094E18(name, direction)\ +static bool8 name##_2(struct MapObject *, struct Sprite *);\ +bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + sub_8094DE4(mapObject, sprite, direction);\ + return name##_2(mapObject, sprite);\ +}\ +static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + if (sub_80941C8(mapObject, sprite))\ + {\ + sprite->data2 = 2;\ + mapObject->mapobj_bit_5 = FALSE;\ + return TRUE;\ + }\ + return FALSE;\ +} + +unk_macro_8094E18(sub_8094E18, DIR_SOUTH) +unk_macro_8094E18(sub_8094E60, DIR_NORTH) +unk_macro_8094E18(sub_8094EB8, DIR_WEST) +unk_macro_8094E18(sub_8094710, DIR_EAST) -- cgit v1.2.3 From b06631f6540bc1b08613e08edb0f615ec1d3c28d Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 12:25:27 -0400 Subject: Functions for facing towards/away from another object? --- src/field_map_obj.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 1d91184ec..c4b1255ad 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4541,3 +4541,27 @@ unk_macro_8094E18(sub_8094E18, DIR_SOUTH) unk_macro_8094E18(sub_8094E60, DIR_NORTH) unk_macro_8094E18(sub_8094EB8, DIR_WEST) unk_macro_8094E18(sub_8094710, DIR_EAST) + +bool8 sub_8094F38(struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 mapObjectId; + + if (!TryGetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0, &mapObjectId)) + { + an_look_any(mapObject, sprite, sub_8092AF8(mapObject->coords2.x, mapObject->coords2.y, gMapObjects[mapObjectId].coords2.x, gMapObjects[mapObjectId].coords2.y)); + } + sprite->data2 = 1; + return TRUE; +} + +bool8 sub_8094F94(struct MapObject *mapObject, struct Sprite *sprite) +{ + u8 mapObjectId; + + if (!TryGetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0, &mapObjectId)) + { + an_look_any(mapObject, sprite, GetOppositeDirection(sub_8092AF8(mapObject->coords2.x, mapObject->coords2.y, gMapObjects[mapObjectId].coords2.x, gMapObjects[mapObjectId].coords2.y))); + } + sprite->data2 = 1; + return TRUE; +} -- cgit v1.2.3 From 92a3f1cb2e2dae3275a595b847d3ffcf05817663 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 12:57:42 -0400 Subject: More maybe_shadow_1_macro memes --- src/field_map_obj.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index c4b1255ad..db28ce1ca 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4565,3 +4565,30 @@ bool8 sub_8094F94(struct MapObject *mapObject, struct Sprite *sprite) sprite->data2 = 1; return TRUE; } + +bool8 sub_8094FF8(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_9 = TRUE; + sprite->data2 = 1; + return TRUE; +} + +bool8 sub_8095008(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_9 = FALSE; + sprite->data2 = 1; + return TRUE; +} + +maybe_shadow_1_macro(sub_8095018, maybe_shadow_1, sub_80941B0, DIR_SOUTH, 1, 2) +maybe_shadow_1_macro(sub_8095070, maybe_shadow_1, sub_80941B0, DIR_NORTH, 1, 2) +maybe_shadow_1_macro(sub_80950C8, maybe_shadow_1, sub_80941B0, DIR_WEST, 1, 2) +maybe_shadow_1_macro(sub_8095120, maybe_shadow_1, sub_80941B0, DIR_EAST, 1, 2) +maybe_shadow_1_macro(sub_8095178, maybe_shadow_1, sub_80941B0, DIR_SOUTH, 0, 0) +maybe_shadow_1_macro(sub_80951D0, maybe_shadow_1, sub_80941B0, DIR_NORTH, 0, 0) +maybe_shadow_1_macro(sub_8095228, maybe_shadow_1, sub_80941B0, DIR_WEST, 0, 0) +maybe_shadow_1_macro(sub_8095280, maybe_shadow_1, sub_80941B0, DIR_EAST, 0, 0) +maybe_shadow_1_macro(sub_80952D8, maybe_shadow_1, sub_80941E0, DIR_SOUTH, 0, 2) +maybe_shadow_1_macro(sub_8095330, maybe_shadow_1, sub_80941E0, DIR_NORTH, 0, 2) +maybe_shadow_1_macro(sub_8095388, maybe_shadow_1, sub_80941E0, DIR_WEST, 0, 2) +maybe_shadow_1_macro(sub_80953E0, maybe_shadow_1, sub_80941E0, DIR_EAST, 0, 2) -- cgit v1.2.3 From 513e3cd9bcd7628b9f2f24ab0e7a5f78763cf44e Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 13:00:43 -0400 Subject: Five small functions --- src/field_map_obj.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index db28ce1ca..b337349a2 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4592,3 +4592,36 @@ maybe_shadow_1_macro(sub_80952D8, maybe_shadow_1, sub_80941E0, DIR_SOUTH, 0, 2) maybe_shadow_1_macro(sub_8095330, maybe_shadow_1, sub_80941E0, DIR_NORTH, 0, 2) maybe_shadow_1_macro(sub_8095388, maybe_shadow_1, sub_80941E0, DIR_WEST, 0, 2) maybe_shadow_1_macro(sub_80953E0, maybe_shadow_1, sub_80941E0, DIR_EAST, 0, 2) + +bool8 sub_8095438(struct MapObject *mapObject, struct Sprite *sprite) +{ + an_look_any(mapObject, sprite, gUnknown_085055CD[mapObject->animPattern]); + return TRUE; +} + +bool8 sub_8095450(struct MapObject *mapObject, struct Sprite *sprite) +{ + npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_SOUTH, 0x14); + return FALSE; +} + +bool8 sub_8095460(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_25 = FALSE; + sprite->data2 = 1; + return TRUE; +} + +bool8 sub_8095470(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_25 = TRUE; + sprite->data2 = 1; + return TRUE; +} + +bool8 sub_8095480(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_12 = TRUE; + sprite->data2 = 1; + return TRUE; +} -- cgit v1.2.3 From 7af98338830aaeb33be4c28dc26f14cc788f9df7 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 13:06:03 -0400 Subject: Additional script object callbacks --- src/field_map_obj.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index b337349a2..432eb5b47 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4625,3 +4625,48 @@ bool8 sub_8095480(struct MapObject *mapObject, struct Sprite *sprite) sprite->data2 = 1; return TRUE; } + +bool8 sub_8095490(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_12 = GetFieldObjectGraphicsInfo(mapObject->graphicsId)->inanimate; + sprite->data2 = 1; + return TRUE; +} + +bool8 sub_80954BC(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_13 = TRUE; + sprite->data2 = 1; + return TRUE; +} + +bool8 sub_80954CC(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_13 = FALSE; + sprite->data2 = 1; + return TRUE; +} + +bool8 do_exclamation_mark_bubble_1(struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectSpawnParams[0], (u8 *)&gFieldEffectSpawnParams[1], (u8 *)&gFieldEffectSpawnParams[2]); + FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON_1); + sprite->data2 = 1; + return TRUE; +} + +bool8 do_exclamation_mark_bubble_2(struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectSpawnParams[0], (u8 *)&gFieldEffectSpawnParams[1], (u8 *)&gFieldEffectSpawnParams[2]); + FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON_2); + sprite->data2 = 1; + return TRUE; +} + +bool8 do_heart_bubble(struct MapObject *mapObject, struct Sprite *sprite) +{ + FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectSpawnParams[0], (u8 *)&gFieldEffectSpawnParams[1], (u8 *)&gFieldEffectSpawnParams[2]); + FieldEffectStart(FLDEFF_HEART_ICON); + sprite->data2 = 1; + return TRUE; +} -- cgit v1.2.3 From 4b04e92e8b236d91ea5cc45813f914f10a86b748 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 13:26:17 -0400 Subject: Ten more functions (remaining function count is 99) --- src/field_map_obj.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 432eb5b47..cc645751c 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -21,6 +21,7 @@ #include "field_effect.h" #include "field_effect_helpers.h" #include "field_camera.h" +#include "trainer_see.h" #include "field_map_obj.h" #define NUM_FIELD_MAP_OBJECT_TEMPLATES 0x51 @@ -120,6 +121,7 @@ static void FieldObjectExecSpecialAnim(struct MapObject *, struct Sprite *); static bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject *, s16, s16); static bool8 IsMetatileDirectionallyImpassable(struct MapObject *, s16, s16, u8); static bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *, s16, s16); +static bool8 sub_809558C(struct MapObject *, struct Sprite *); // ROM data @@ -4670,3 +4672,100 @@ bool8 do_heart_bubble(struct MapObject *mapObject, struct Sprite *sprite) sprite->data2 = 1; return TRUE; } + +bool8 sub_8095548(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (mapObject->animPattern == 0x3F) + { + sub_80B4578(mapObject); + return FALSE; + } + if (mapObject->animPattern != 0x39 && mapObject->animPattern != 0x3A) + { + sprite->data2 = 2; + return TRUE; + } + sub_8155D78(mapObject); + sprite->data2 = 1; + return sub_809558C(mapObject, sprite); +} + +static bool8 sub_809558C(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_8155DA0(mapObject)) + { + sprite->data2 = 2; + return TRUE; + } + return FALSE; +} + +bool8 sub_80955AC(struct MapObject *mapObject, struct Sprite *sprite) +{ + obj_anim_image_set_and_seek(sprite, 1, 0); + sprite->data2 = 1; + return FALSE; +} + +bool8 sub_80955C8(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_80979BC(sprite)) + { + SetFieldObjectStepTimer(sprite, 32); + sprite->data2 = 2; + } + return FALSE; +} + +bool8 sub_80955EC(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_13 ^= TRUE; + if (RunFieldObjectStepTimer(sprite)) + { + mapObject->mapobj_bit_13 = TRUE; + sprite->data2 = 3; + } + return FALSE; +} + +bool8 sub_8095628(struct MapObject *mapObject, struct Sprite *sprite) +{ + obj_anim_image_set_and_seek(sprite, 1, 0); + sprite->data2 = 1; + return FALSE; +} + +bool8 sub_8095644(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_80979BC(sprite)) + { + SetFieldObjectStepTimer(sprite, 32); + sprite->data2 = 2; + } + return FALSE; +} + +bool8 sub_8095668(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_13 ^= TRUE; + if (RunFieldObjectStepTimer(sprite)) + { + mapObject->mapobj_bit_13 = TRUE; + sprite->data2 = 3; + } + return FALSE; +} + +bool8 sub_80956A4(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_26 = TRUE; + sprite->data2 = 1; + return TRUE; +} + +bool8 sub_80956B4(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_26 = FALSE; + sprite->data2 = 1; + return TRUE; +} -- cgit v1.2.3 From 283d9060a78cbf618c2c3807f3fa8e3b4b240c0d Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 13:59:30 -0400 Subject: Some functions relating to affine animations --- src/field_map_obj.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index cc645751c..3e72f538c 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4769,3 +4769,57 @@ bool8 sub_80956B4(struct MapObject *mapObject, struct Sprite *sprite) sprite->data2 = 1; return TRUE; } + +bool8 sub_80956C4(struct MapObject *mapObject, struct Sprite *sprite) +{ + sprite->oam.affineMode = 3; + InitSpriteAffineAnim(sprite); + sprite->affineAnimPaused = TRUE; + sprite->subspriteMode = 0; + return TRUE; +} + +bool8 sub_80956F4(struct MapObject *mapObject, struct Sprite *sprite) +{ + FreeOamMatrix(sprite->oam.matrixNum); + sprite->oam.affineMode = 0; + CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode); + return TRUE; +} + +bool8 sub_8095724(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_27 = TRUE; + return TRUE; +} + +bool8 sub_8095730(struct MapObject *mapObject, struct Sprite *sprite) +{ + mapObject->mapobj_bit_27 = FALSE; + return TRUE; +} + +#define affine_an_walk_any_2_macro(name, fn, fn2, action, anim, ...)\ +static bool8 name##_2(struct MapObject *, struct Sprite *);\ +bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + fn(mapObject, sprite, __VA_ARGS__);\ + sprite->affineAnimPaused = FALSE;\ + action(sprite, anim);\ + return name##_2(mapObject, sprite);\ +}\ +static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + if (fn2(mapObject, sprite))\ + {\ + sprite->affineAnimPaused = TRUE;\ + sprite->data2 = 2;\ + return TRUE;\ + }\ + return FALSE;\ +}\ + +affine_an_walk_any_2_macro(sub_8095740, sub_8093B60, an_walk_any_2, StartSpriteAffineAnimIfDifferent, 0, DIR_SOUTH) +affine_an_walk_any_2_macro(sub_80957A0, sub_8093B60, an_walk_any_2, ChangeSpriteAffineAnimIfDifferent, 1, DIR_SOUTH) +affine_an_walk_any_2_macro(sub_8095800, do_go_anim, npc_obj_ministep_stop_on_arrival, ChangeSpriteAffineAnimIfDifferent, 2, DIR_WEST, 1) +affine_an_walk_any_2_macro(sub_8095860, do_go_anim, npc_obj_ministep_stop_on_arrival, ChangeSpriteAffineAnimIfDifferent, 3, DIR_EAST, 1) -- cgit v1.2.3 From e544d5f8b8704d5ca77de8b1bd8245daad973490 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 14:02:43 -0400 Subject: sub_80958C0 and callers --- src/field_map_obj.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 3e72f538c..a5c3c013f 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4823,3 +4823,36 @@ affine_an_walk_any_2_macro(sub_8095740, sub_8093B60, an_walk_any_2, StartSpriteA affine_an_walk_any_2_macro(sub_80957A0, sub_8093B60, an_walk_any_2, ChangeSpriteAffineAnimIfDifferent, 1, DIR_SOUTH) affine_an_walk_any_2_macro(sub_8095800, do_go_anim, npc_obj_ministep_stop_on_arrival, ChangeSpriteAffineAnimIfDifferent, 2, DIR_WEST, 1) affine_an_walk_any_2_macro(sub_8095860, do_go_anim, npc_obj_ministep_stop_on_arrival, ChangeSpriteAffineAnimIfDifferent, 3, DIR_EAST, 1) + +static void sub_80958C0(struct MapObject *mapObject, struct Sprite *sprite, u8 direction) +{ + FieldObjectSetDirection(mapObject, direction); + npc_coords_shift_still(mapObject); + obj_npc_animation_step(mapObject, sprite, sub_80929FC(direction)); + sprite->animPaused = TRUE; + sprite->data2 = 1; +} + +bool8 sub_8095900(struct MapObject *mapObject, struct Sprite *sprite) +{ + sub_80958C0(mapObject, sprite, DIR_SOUTH); + return TRUE; +} + +bool8 sub_8095910(struct MapObject *mapObject, struct Sprite *sprite) +{ + sub_80958C0(mapObject, sprite, DIR_NORTH); + return TRUE; +} + +bool8 sub_8095920(struct MapObject *mapObject, struct Sprite *sprite) +{ + sub_80958C0(mapObject, sprite, DIR_WEST); + return TRUE; +} + +bool8 sub_8095930(struct MapObject *mapObject, struct Sprite *sprite) +{ + sub_80958C0(mapObject, sprite, DIR_EAST); + return TRUE; +} -- cgit v1.2.3 From c9699169ad0e07326a3d77b1836681b870ecd618 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 14:06:43 -0400 Subject: another block of directional anim functions --- src/field_map_obj.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index a5c3c013f..3e1e3d19e 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4856,3 +4856,23 @@ bool8 sub_8095930(struct MapObject *mapObject, struct Sprite *sprite) sub_80958C0(mapObject, sprite, DIR_EAST); return TRUE; } + +#define set_dirn_and_anim__an_proceed(name, direction, anims)\ +bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ +{\ + npc_set_direction_and_anim__an_proceed(mapObject, sprite, direction, anims(direction));\ + return FALSE;\ +} + +set_dirn_and_anim__an_proceed(sub_8095940, DIR_SOUTH, sub_80929BC) +set_dirn_and_anim__an_proceed(sub_8095964, DIR_NORTH, sub_80929BC) +set_dirn_and_anim__an_proceed(sub_8095988, DIR_WEST, sub_80929BC) +set_dirn_and_anim__an_proceed(sub_80959AC, DIR_EAST, sub_80929BC) +set_dirn_and_anim__an_proceed(sub_80959D0, DIR_SOUTH, sub_80929DC) +set_dirn_and_anim__an_proceed(sub_80959F4, DIR_NORTH, sub_80929DC) +set_dirn_and_anim__an_proceed(sub_8095A18, DIR_WEST, sub_80929DC) +set_dirn_and_anim__an_proceed(sub_8095A3C, DIR_EAST, sub_80929DC) +set_dirn_and_anim__an_proceed(sub_8095A60, DIR_SOUTH, sub_80929EC) +set_dirn_and_anim__an_proceed(sub_8095A84, DIR_NORTH, sub_80929EC) +set_dirn_and_anim__an_proceed(sub_8095AA8, DIR_WEST, sub_80929EC) +set_dirn_and_anim__an_proceed(sub_8095ACC, DIR_EAST, sub_80929EC) -- cgit v1.2.3 From b54689b9a37d38ada226504c384054c56310e2dc Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 14:12:32 -0400 Subject: Another four functions --- src/field_map_obj.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 3e1e3d19e..9092a6089 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4876,3 +4876,40 @@ set_dirn_and_anim__an_proceed(sub_8095A60, DIR_SOUTH, sub_80929EC) set_dirn_and_anim__an_proceed(sub_8095A84, DIR_NORTH, sub_80929EC) set_dirn_and_anim__an_proceed(sub_8095AA8, DIR_WEST, sub_80929EC) set_dirn_and_anim__an_proceed(sub_8095ACC, DIR_EAST, sub_80929EC) + +void sub_8095AF0(struct MapObject *mapObject, struct Sprite *sprite) +{ + sub_8097750(sprite); + sprite->animPaused = FALSE; +} + +bool8 sub_8095B0C(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_8097758(sprite)) + { + npc_coords_shift_still(mapObject); + mapObject->mapobj_bit_3 = TRUE; + sprite->animPaused = TRUE; + return TRUE; + } + return FALSE; +} + +static bool8 sub_8095B64(struct MapObject *, struct Sprite *); + +bool8 sub_8095B44(struct MapObject *mapObject, struct Sprite *sprite) +{ + sub_8095AF0(mapObject, sprite); + sprite->data2 = 1; + return sub_8095B64(mapObject, sprite); +} + +static bool8 sub_8095B64(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sub_8095B0C(mapObject, sprite)) + { + sprite->data2 = 2; + return TRUE; + } + return FALSE; +} -- cgit v1.2.3 From 0689afbd865d017171c86c1743d2a3d123abb156 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 14:51:10 -0400 Subject: Yet more maybe_shadow_1 memes --- src/field_map_obj.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 9092a6089..87ae05ad7 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4381,10 +4381,10 @@ static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ return FALSE;\ } -maybe_shadow_1_macro(sub_8094230, maybe_shadow_1, sub_80941B0, 1, 2, 0) -maybe_shadow_1_macro(sub_8094288, maybe_shadow_1, sub_80941B0, 2, 2, 0) -maybe_shadow_1_macro(sub_80942E0, maybe_shadow_1, sub_80941B0, 3, 2, 0) -maybe_shadow_1_macro(sub_8094338, maybe_shadow_1, sub_80941B0, 4, 2, 0) +maybe_shadow_1_macro(sub_8094230, maybe_shadow_1, sub_80941B0, DIR_SOUTH, 2, 0) +maybe_shadow_1_macro(sub_8094288, maybe_shadow_1, sub_80941B0, DIR_NORTH, 2, 0) +maybe_shadow_1_macro(sub_80942E0, maybe_shadow_1, sub_80941B0, DIR_WEST, 2, 0) +maybe_shadow_1_macro(sub_8094338, maybe_shadow_1, sub_80941B0, DIR_EAST, 2, 0) void sub_8094390(struct Sprite *sprite, u16 duration) { @@ -4584,16 +4584,16 @@ bool8 sub_8095008(struct MapObject *mapObject, struct Sprite *sprite) maybe_shadow_1_macro(sub_8095018, maybe_shadow_1, sub_80941B0, DIR_SOUTH, 1, 2) maybe_shadow_1_macro(sub_8095070, maybe_shadow_1, sub_80941B0, DIR_NORTH, 1, 2) -maybe_shadow_1_macro(sub_80950C8, maybe_shadow_1, sub_80941B0, DIR_WEST, 1, 2) -maybe_shadow_1_macro(sub_8095120, maybe_shadow_1, sub_80941B0, DIR_EAST, 1, 2) +maybe_shadow_1_macro(sub_80950C8, maybe_shadow_1, sub_80941B0, DIR_WEST, 1, 2) +maybe_shadow_1_macro(sub_8095120, maybe_shadow_1, sub_80941B0, DIR_EAST, 1, 2) maybe_shadow_1_macro(sub_8095178, maybe_shadow_1, sub_80941B0, DIR_SOUTH, 0, 0) maybe_shadow_1_macro(sub_80951D0, maybe_shadow_1, sub_80941B0, DIR_NORTH, 0, 0) -maybe_shadow_1_macro(sub_8095228, maybe_shadow_1, sub_80941B0, DIR_WEST, 0, 0) -maybe_shadow_1_macro(sub_8095280, maybe_shadow_1, sub_80941B0, DIR_EAST, 0, 0) +maybe_shadow_1_macro(sub_8095228, maybe_shadow_1, sub_80941B0, DIR_WEST, 0, 0) +maybe_shadow_1_macro(sub_8095280, maybe_shadow_1, sub_80941B0, DIR_EAST, 0, 0) maybe_shadow_1_macro(sub_80952D8, maybe_shadow_1, sub_80941E0, DIR_SOUTH, 0, 2) maybe_shadow_1_macro(sub_8095330, maybe_shadow_1, sub_80941E0, DIR_NORTH, 0, 2) -maybe_shadow_1_macro(sub_8095388, maybe_shadow_1, sub_80941E0, DIR_WEST, 0, 2) -maybe_shadow_1_macro(sub_80953E0, maybe_shadow_1, sub_80941E0, DIR_EAST, 0, 2) +maybe_shadow_1_macro(sub_8095388, maybe_shadow_1, sub_80941E0, DIR_WEST, 0, 2) +maybe_shadow_1_macro(sub_80953E0, maybe_shadow_1, sub_80941E0, DIR_EAST, 0, 2) bool8 sub_8095438(struct MapObject *mapObject, struct Sprite *sprite) { @@ -4913,3 +4913,23 @@ static bool8 sub_8095B64(struct MapObject *mapObject, struct Sprite *sprite) } return FALSE; } + +void sub_8095B84(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 speed, u8 a4) +{ + sub_8093FC4(mapObject, sprite, direction, speed, a4); + StartSpriteAnimIfDifferent(sprite, sub_80929BC(direction)); + DoShadowFieldEffect(mapObject); +} + +maybe_shadow_1_macro(sub_8095BC8, sub_8095B84, sub_80941B0, DIR_SOUTH, 0, 1) +maybe_shadow_1_macro(sub_8095C20, sub_8095B84, sub_80941B0, DIR_NORTH, 0, 1) +maybe_shadow_1_macro(sub_8095C78, sub_8095B84, sub_80941B0, DIR_WEST, 0, 1) +maybe_shadow_1_macro(sub_8095CD0, sub_8095B84, sub_80941B0, DIR_EAST, 0, 1) +maybe_shadow_1_macro(sub_8095D28, sub_8095B84, sub_80941B0, DIR_SOUTH, 1, 1) +maybe_shadow_1_macro(sub_8095D80, sub_8095B84, sub_80941B0, DIR_NORTH, 1, 1) +maybe_shadow_1_macro(sub_8095DD8, sub_8095B84, sub_80941B0, DIR_WEST, 1, 1) +maybe_shadow_1_macro(sub_8095E30, sub_8095B84, sub_80941B0, DIR_EAST, 1, 1) +maybe_shadow_1_macro(sub_8095E88, sub_8095B84, sub_80941B0, DIR_SOUTH, 2, 0) +maybe_shadow_1_macro(sub_8095EE0, sub_8095B84, sub_80941B0, DIR_NORTH, 2, 0) +maybe_shadow_1_macro(sub_8095F38, sub_8095B84, sub_80941B0, DIR_WEST, 2, 0) +maybe_shadow_1_macro(sub_8095F90, sub_8095B84, sub_80941B0, DIR_EAST, 2, 0) -- cgit v1.2.3 From 7bf307e7aee242ddba099d8963b13ad022efb9f1 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 14:59:52 -0400 Subject: The memes keep coming --- src/field_map_obj.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 87ae05ad7..f1de23307 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4453,27 +4453,27 @@ bool8 sub_80945C4(struct MapObject *mapObject, struct Sprite *sprite) bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ {\ u8 animId;\ - animId = get_##images##_image_anim_num(DIR_##direction);\ + animId = images(DIR_##direction);\ sub_8094554(mapObject, sprite, DIR_##direction, animId, duration);\ return timer(mapObject, sprite);\ } -special_anim_with_timer_2(sub_8094600, SOUTH, go, 32, sub_80945C4) -special_anim_with_timer_2(sub_8094638, NORTH, go, 32, sub_80945C4) -special_anim_with_timer_2(sub_8094670, WEST, go, 32, sub_80945C4) -special_anim_with_timer_2(sub_80946A8, EAST, go, 32, sub_80945C4) -special_anim_with_timer_2(sub_80946E0, SOUTH, go, 16, sub_809459C) -special_anim_with_timer_2(sub_8094718, NORTH, go, 16, sub_809459C) -special_anim_with_timer_2(sub_8094750, WEST, go, 16, sub_809459C) -special_anim_with_timer_2(sub_8094788, EAST, go, 16, sub_809459C) -special_anim_with_timer_2(sub_80947C0, SOUTH, go_fast, 8, sub_809459C) -special_anim_with_timer_2(sub_80947F8, NORTH, go_fast, 8, sub_809459C) -special_anim_with_timer_2(sub_8094830, WEST, go_fast, 8, sub_809459C) -special_anim_with_timer_2(sub_8094868, EAST, go_fast, 8, sub_809459C) -special_anim_with_timer_2(sub_80948A0, SOUTH, go_faster, 4, sub_809459C) -special_anim_with_timer_2(sub_80948D8, NORTH, go_faster, 4, sub_809459C) -special_anim_with_timer_2(sub_8094910, WEST, go_faster, 4, sub_809459C) -special_anim_with_timer_2(sub_8094948, EAST, go_faster, 4, sub_809459C) +special_anim_with_timer_2(sub_8094600, SOUTH, get_go_image_anim_num, 32, sub_80945C4) +special_anim_with_timer_2(sub_8094638, NORTH, get_go_image_anim_num, 32, sub_80945C4) +special_anim_with_timer_2(sub_8094670, WEST, get_go_image_anim_num, 32, sub_80945C4) +special_anim_with_timer_2(sub_80946A8, EAST, get_go_image_anim_num, 32, sub_80945C4) +special_anim_with_timer_2(sub_80946E0, SOUTH, get_go_image_anim_num, 16, sub_809459C) +special_anim_with_timer_2(sub_8094718, NORTH, get_go_image_anim_num, 16, sub_809459C) +special_anim_with_timer_2(sub_8094750, WEST, get_go_image_anim_num, 16, sub_809459C) +special_anim_with_timer_2(sub_8094788, EAST, get_go_image_anim_num, 16, sub_809459C) +special_anim_with_timer_2(sub_80947C0, SOUTH, get_go_fast_image_anim_num, 8, sub_809459C) +special_anim_with_timer_2(sub_80947F8, NORTH, get_go_fast_image_anim_num, 8, sub_809459C) +special_anim_with_timer_2(sub_8094830, WEST, get_go_fast_image_anim_num, 8, sub_809459C) +special_anim_with_timer_2(sub_8094868, EAST, get_go_fast_image_anim_num, 8, sub_809459C) +special_anim_with_timer_2(sub_80948A0, SOUTH, get_go_faster_image_anim_num, 4, sub_809459C) +special_anim_with_timer_2(sub_80948D8, NORTH, get_go_faster_image_anim_num, 4, sub_809459C) +special_anim_with_timer_2(sub_8094910, WEST, get_go_faster_image_anim_num, 4, sub_809459C) +special_anim_with_timer_2(sub_8094948, EAST, get_go_faster_image_anim_num, 4, sub_809459C) an_walk_any_2_macro(sub_8094980, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_SOUTH, 2) an_walk_any_2_macro(sub_80949C0, do_go_anim, npc_obj_ministep_stop_on_arrival, DIR_NORTH, 2) @@ -4933,3 +4933,8 @@ maybe_shadow_1_macro(sub_8095E88, sub_8095B84, sub_80941B0, DIR_SOUTH, 2, 0) maybe_shadow_1_macro(sub_8095EE0, sub_8095B84, sub_80941B0, DIR_NORTH, 2, 0) maybe_shadow_1_macro(sub_8095F38, sub_8095B84, sub_80941B0, DIR_WEST, 2, 0) maybe_shadow_1_macro(sub_8095F90, sub_8095B84, sub_80941B0, DIR_EAST, 2, 0) + +special_anim_with_timer_2(sub_8095FE8, SOUTH, sub_80929FC, 8, sub_809459C) +special_anim_with_timer_2(sub_8096020, NORTH, sub_80929FC, 8, sub_809459C) +special_anim_with_timer_2(sub_8096058, WEST, sub_80929FC, 8, sub_809459C) +special_anim_with_timer_2(sub_8096090, EAST, sub_80929FC, 8, sub_809459C) -- cgit v1.2.3 From 8d34e9c3970d23832bb5500358fe4a2e250c5124 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 15:03:47 -0400 Subject: More an_walk_any_2_macro memes --- src/field_map_obj.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index f1de23307..b5f92645d 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4938,3 +4938,15 @@ special_anim_with_timer_2(sub_8095FE8, SOUTH, sub_80929FC, 8, sub_809459C) special_anim_with_timer_2(sub_8096020, NORTH, sub_80929FC, 8, sub_809459C) special_anim_with_timer_2(sub_8096058, WEST, sub_80929FC, 8, sub_809459C) special_anim_with_timer_2(sub_8096090, EAST, sub_80929FC, 8, sub_809459C) + +void sub_80960C8(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 speed) +{ + npc_apply_direction(mapObject, sprite, direction, speed); + StartSpriteAnim(sprite, sub_80929BC(mapObject->mapobj_unk_18)); + SeekSpriteAnim(sprite, 0); +} + +an_walk_any_2_macro(sub_8096100, sub_80960C8, npc_obj_ministep_stop_on_arrival, DIR_SOUTH, 1) +an_walk_any_2_macro(sub_8096140, sub_80960C8, npc_obj_ministep_stop_on_arrival, DIR_NORTH, 1) +an_walk_any_2_macro(sub_8096180, sub_80960C8, npc_obj_ministep_stop_on_arrival, DIR_WEST, 1) +an_walk_any_2_macro(sub_80961C0, sub_80960C8, npc_obj_ministep_stop_on_arrival, DIR_EAST, 1) -- cgit v1.2.3 From a9d3949c915a6ccb58f0fe6b58af18ae34a60974 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 15:05:23 -0400 Subject: More an_walk_any_2_macro memes (again) --- src/field_map_obj.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index b5f92645d..9769c6a03 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4950,3 +4950,14 @@ an_walk_any_2_macro(sub_8096100, sub_80960C8, npc_obj_ministep_stop_on_arrival, an_walk_any_2_macro(sub_8096140, sub_80960C8, npc_obj_ministep_stop_on_arrival, DIR_NORTH, 1) an_walk_any_2_macro(sub_8096180, sub_80960C8, npc_obj_ministep_stop_on_arrival, DIR_WEST, 1) an_walk_any_2_macro(sub_80961C0, sub_80960C8, npc_obj_ministep_stop_on_arrival, DIR_EAST, 1) + +void sub_8096200(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 speed) +{ + npc_apply_direction(mapObject, sprite, direction, speed); + npc_apply_anim_looping(mapObject, sprite, sub_80929FC(mapObject->mapobj_unk_18)); +} + +an_walk_any_2_macro(sub_8096230, sub_8096200, npc_obj_ministep_stop_on_arrival, DIR_SOUTH, 1) +an_walk_any_2_macro(sub_8096270, sub_8096200, npc_obj_ministep_stop_on_arrival, DIR_NORTH, 1) +an_walk_any_2_macro(sub_80962B0, sub_8096200, npc_obj_ministep_stop_on_arrival, DIR_WEST, 1) +an_walk_any_2_macro(sub_80962F0, sub_8096200, npc_obj_ministep_stop_on_arrival, DIR_EAST, 1) -- cgit v1.2.3 From fb01dd2e5a6d76974eaceeb6fdaab11abfd4f910 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 15:06:45 -0400 Subject: More an_walk_any_2_macro memes (again again) --- src/field_map_obj.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 9769c6a03..d4c00685f 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -4961,3 +4961,14 @@ an_walk_any_2_macro(sub_8096230, sub_8096200, npc_obj_ministep_stop_on_arrival, an_walk_any_2_macro(sub_8096270, sub_8096200, npc_obj_ministep_stop_on_arrival, DIR_NORTH, 1) an_walk_any_2_macro(sub_80962B0, sub_8096200, npc_obj_ministep_stop_on_arrival, DIR_WEST, 1) an_walk_any_2_macro(sub_80962F0, sub_8096200, npc_obj_ministep_stop_on_arrival, DIR_EAST, 1) + +void sub_8096330(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 speed) +{ + npc_apply_direction(mapObject, sprite, direction, speed); + StartSpriteAnim(sprite, sub_80929DC(mapObject->mapobj_unk_18)); + SeekSpriteAnim(sprite, 0); +} +an_walk_any_2_macro(sub_8096368, sub_8096330, npc_obj_ministep_stop_on_arrival, DIR_SOUTH, 1) +an_walk_any_2_macro(sub_80963A8, sub_8096330, npc_obj_ministep_stop_on_arrival, DIR_NORTH, 1) +an_walk_any_2_macro(sub_80963E8, sub_8096330, npc_obj_ministep_stop_on_arrival, DIR_WEST, 1) +an_walk_any_2_macro(sub_8096428, sub_8096330, npc_obj_ministep_stop_on_arrival, DIR_EAST, 1) -- cgit v1.2.3 From 70b1ad485719ce1854020222131a0c0daa5a16cd Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 15:33:26 -0400 Subject: Remaining functions --- src/field_map_obj.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index d4c00685f..a79f78434 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -122,6 +122,8 @@ static bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject *, s16, s16) static bool8 IsMetatileDirectionallyImpassable(struct MapObject *, s16, s16, u8); static bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *, s16, s16); static bool8 sub_809558C(struct MapObject *, struct Sprite *); +static void sub_8096530(struct MapObject *, struct Sprite *); +static void npc_update_obj_anim_flag(struct MapObject *, struct Sprite *); // ROM data @@ -4972,3 +4974,107 @@ an_walk_any_2_macro(sub_8096368, sub_8096330, npc_obj_ministep_stop_on_arrival, an_walk_any_2_macro(sub_80963A8, sub_8096330, npc_obj_ministep_stop_on_arrival, DIR_NORTH, 1) an_walk_any_2_macro(sub_80963E8, sub_8096330, npc_obj_ministep_stop_on_arrival, DIR_WEST, 1) an_walk_any_2_macro(sub_8096428, sub_8096330, npc_obj_ministep_stop_on_arrival, DIR_EAST, 1) + +bool8 sub_8096468(struct MapObject *mapObject, struct Sprite *sprite) +{ + sub_8097FA4(mapObject); + sprite->data2 = 1; + return TRUE; +} + +bool8 sub_809647C(struct MapObject *mapObject, struct Sprite *sprite) +{ + sub_8098044(mapObject->mapobj_unk_1B); + sprite->pos2.y = 0; + sprite->data2 = 1; + return TRUE; +} + +bool8 sub_8096494(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (sprite->pos2.y == 0) + { + sub_8098044(mapObject->mapobj_unk_1B); + sprite->data2 = 1; + return TRUE; + } + return FALSE; +} + +bool8 sub_80964B8(struct MapObject *mapObject, struct Sprite *sprite) +{ + return TRUE; +} + +bool8 sub_80964BC(struct MapObject *mapObject, struct Sprite *sprite) +{ + sprite->animPaused = TRUE; + return TRUE; +} + +void npc_obj_transfer_image_anim_pause_flag(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (mapObject->mapobj_bit_10) + { + sprite->animPaused = TRUE; + } +} + +void sub_80964E8(struct MapObject *mapObject, struct Sprite *sprite) +{ + if (mapObject->mapobj_bit_11) + { + sprite->animPaused = FALSE; + mapObject->mapobj_bit_10 = FALSE; + mapObject->mapobj_bit_11 = FALSE; + } +} + +void sub_8096518(struct MapObject *mapObject, struct Sprite *sprite) +{ + sub_8096530(mapObject, sprite); + npc_update_obj_anim_flag(mapObject, sprite); +} + +static void sub_8096530(struct MapObject *mapObject, struct Sprite *sprite) +{ + u16 x; + u16 y; + u16 x2; + u16 y2; + const struct MapObjectGraphicsInfo *graphicsInfo; + + mapObject->mapobj_bit_14 = FALSE; + graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId); + if (sprite->coordOffsetEnabled) + { + x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX + gSpriteCoordOffsetX; + y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY; + } + else + { + x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX; + y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY; + } + x2 = graphicsInfo->width; + x2 += x; + y2 = y; + y2 += graphicsInfo->height; + if ((s16)x >= 0x100 || (s16)x2 < -0x10) + { + mapObject->mapobj_bit_14 = TRUE; + } + if ((s16)y >= 0xB0 || (s16)y2 < -0x10) + { + mapObject->mapobj_bit_14 = TRUE; + } +} + +static void npc_update_obj_anim_flag(struct MapObject *mapObject, struct Sprite *sprite) +{ + sprite->invisible = FALSE; + if (mapObject->mapobj_bit_13 || mapObject->mapobj_bit_14) + { + sprite->invisible = TRUE; + } +} -- cgit v1.2.3 From 130ba76533e6b87696b8e960eb8a09cb951417ad Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 17:50:07 -0400 Subject: remove data3.h --- src/field_map_obj.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index a79f78434..1ffa0a594 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -5,7 +5,6 @@ #include "sprite.h" #include "rom4.h" #include "rng.h" -#include "data3.h" #include "event_scripts.h" #include "berry.h" #include "palette.h" @@ -134,6 +133,46 @@ const struct MapObjectGraphicsInfo *const gMauvilleOldManGraphicsInfoPointers[7] const struct MapObjectGraphicsInfo *const gFieldObjectGraphicsInfoPointers[0xEF]; u8 (*const gUnknown_0850D714[11])(s16, s16, s16, s16); +struct PairedPalettes { + u16 tag; + const u16 *data; +}; + +u8 gUnknown_084975C4[0x10]; +const struct SpriteTemplate gUnknown_084975D4; +void (*const gUnknown_084975EC[3])(struct Sprite *); +const struct SpritePalette gUnknown_0850BBC8[39]; +const struct PairedPalettes gUnknown_0850BD00[15]; +const struct PairedPalettes gUnknown_0850BD78[15]; +const u16 *const gUnknown_0850BE38[2]; +const s16 gUnknown_0850D6DC[4]; // {0x20, 0x40, 0x60, 0x80} +const s16 gUnknown_0850D6EC[4]; +const u8 gUnknown_0850D710[4]; // {DIR_SOUTH, DIR_NORTH, DIR_WEST, DIR_EAST} +const u8 gUnknown_0850D770[2]; // {DIR_SOUTH, DIR_NORTH} +const u8 gUnknown_0850D790[2]; // {DIR_WEST, DIR_EAST} +const u8 gUnknown_0850D7F0[2]; // {DIR_NORTH, DIR_WEST} +const u8 gUnknown_0850D808[2]; // {DIR_NORTH, DIR_EAST} +const u8 gUnknown_0850D820[2]; // {DIR_SOUTH, DIR_WEST} +const u8 gUnknown_0850D838[2]; // {DIR_SOUTH, DIR_EAST} +const u8 gUnknown_0850D850[4]; +const u8 gUnknown_0850D868[4]; +const u8 gUnknown_0850D880[4]; +const u8 gUnknown_0850D898[4]; +const u8 gUnknown_0850D8AC[5]; +const u8 gUnknown_0850D8C4[5]; +const u8 gUnknown_0850D8E8[4]; +bool8 (*const gUnknown_0850DA64[11])(struct MapObject *, struct Sprite *, u8, bool8(u8)); +bool8 (*const gUnknown_0850DB5C[4])(u8); +bool8 (*const gUnknown_0850DB6C[4])(u8); +const struct Coords16 gUnknown_0850DB7C[4]; +const u8 gUnknown_0850DC2F[4][4]; +const u8 gUnknown_0850DC3F[4][4]; +const u8 gUnknown_0850DBA0[5]; +bool8 (*const *const gUnknown_0850DC50[166])(struct MapObject *, struct Sprite *); +u8 (*const gUnknown_0850DEE8[5])(u8); +const s16 gUnknown_0850DFBC[3]; +const s16 gUnknown_0850DFC2[3]; + // Code static void npc_clear_ids_and_state(struct MapObject *mapObject) -- cgit v1.2.3 From a23f1a4b11a2d1b5a87898146c7eb0a6ec44da46 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 19:17:58 -0400 Subject: hooray, another data dump --- src/field_map_obj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 1ffa0a594..ed51d5fe8 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -142,8 +142,8 @@ u8 gUnknown_084975C4[0x10]; const struct SpriteTemplate gUnknown_084975D4; void (*const gUnknown_084975EC[3])(struct Sprite *); const struct SpritePalette gUnknown_0850BBC8[39]; -const struct PairedPalettes gUnknown_0850BD00[15]; -const struct PairedPalettes gUnknown_0850BD78[15]; +const struct PairedPalettes gUnknown_0850BD00[4]; +const struct PairedPalettes gUnknown_0850BD78[14]; const u16 *const gUnknown_0850BE38[2]; const s16 gUnknown_0850D6DC[4]; // {0x20, 0x40, 0x60, 0x80} const s16 gUnknown_0850D6EC[4]; -- cgit v1.2.3 From c9800706575024da3192360cb3055b90424e7045 Mon Sep 17 00:00:00 2001 From: scnorton Date: Sun, 17 Sep 2017 19:33:44 -0400 Subject: More glorious data dumping --- src/field_map_obj.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index ed51d5fe8..60e622f28 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -26,24 +26,24 @@ #define NUM_FIELD_MAP_OBJECT_TEMPLATES 0x51 #define null_object_step(name, retval) \ -static bool8 FieldObjectCB2_##name(struct MapObject *, struct Sprite *);\ +bool8 FieldObjectCB2_##name(struct MapObject *, struct Sprite *);\ void FieldObjectCB_##name(struct Sprite *sprite)\ {\ FieldObjectStep(&gMapObjects[sprite->data0], sprite, FieldObjectCB2_##name);\ }\ -static bool8 FieldObjectCB2_##name(struct MapObject *mapObject, struct Sprite *sprite)\ +bool8 FieldObjectCB2_##name(struct MapObject *mapObject, struct Sprite *sprite)\ {\ return (retval);\ } #define field_object_step(name, table) \ extern bool8 (*const (table)[])(struct MapObject *, struct Sprite *);\ -static bool8 FieldObjectCB2_##name(struct MapObject *, struct Sprite *);\ +bool8 FieldObjectCB2_##name(struct MapObject *, struct Sprite *);\ void FieldObjectCB_##name(struct Sprite *sprite)\ {\ FieldObjectStep(&gMapObjects[sprite->data0], sprite, FieldObjectCB2_##name);\ }\ -static bool8 FieldObjectCB2_##name(struct MapObject *mapObject, struct Sprite *sprite)\ +bool8 FieldObjectCB2_##name(struct MapObject *mapObject, struct Sprite *sprite)\ {\ return (table)[sprite->data1](mapObject, sprite);\ } @@ -120,7 +120,8 @@ static void FieldObjectExecSpecialAnim(struct MapObject *, struct Sprite *); static bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject *, s16, s16); static bool8 IsMetatileDirectionallyImpassable(struct MapObject *, s16, s16, u8); static bool8 CheckForCollisionBetweenFieldObjects(struct MapObject *, s16, s16); -static bool8 sub_809558C(struct MapObject *, struct Sprite *); +bool8 sub_809558C(struct MapObject *, struct Sprite *); +bool8 sub_8095B64(struct MapObject *, struct Sprite *); static void sub_8096530(struct MapObject *, struct Sprite *); static void npc_update_obj_anim_flag(struct MapObject *, struct Sprite *); @@ -4275,13 +4276,13 @@ bool8 an_walk_any_2(struct MapObject *mapObject, struct Sprite *sprite) } #define an_walk_any_2_macro(name, fn1, fn2, ...) \ -static bool8 name##_2(struct MapObject *, struct Sprite *);\ +bool8 name##_2(struct MapObject *, struct Sprite *);\ bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ {\ fn1(mapObject, sprite, __VA_ARGS__);\ return name##_2(mapObject, sprite);\ }\ -static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ +bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ {\ if (fn2(mapObject, sprite))\ {\ @@ -4405,13 +4406,13 @@ bool8 sub_80941E0(struct MapObject *mapObject, struct Sprite *sprite) } #define maybe_shadow_1_macro(name, fn1, fn2, ...) \ -static bool8 name##_2(struct MapObject *, struct Sprite *);\ +bool8 name##_2(struct MapObject *, struct Sprite *);\ bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ {\ fn1(mapObject, sprite, __VA_ARGS__);\ return name##_2(mapObject, sprite);\ }\ -static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ +bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ {\ if (fn2(mapObject, sprite))\ {\ @@ -4563,13 +4564,13 @@ void sub_8094DE4(struct MapObject *mapObject, struct Sprite *sprite, u8 directio } #define unk_macro_8094E18(name, direction)\ -static bool8 name##_2(struct MapObject *, struct Sprite *);\ +bool8 name##_2(struct MapObject *, struct Sprite *);\ bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ {\ sub_8094DE4(mapObject, sprite, direction);\ return name##_2(mapObject, sprite);\ }\ -static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ +bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ {\ if (sub_80941C8(mapObject, sprite))\ {\ @@ -4731,7 +4732,7 @@ bool8 sub_8095548(struct MapObject *mapObject, struct Sprite *sprite) return sub_809558C(mapObject, sprite); } -static bool8 sub_809558C(struct MapObject *mapObject, struct Sprite *sprite) +bool8 sub_809558C(struct MapObject *mapObject, struct Sprite *sprite) { if (sub_8155DA0(mapObject)) { @@ -4841,7 +4842,7 @@ bool8 sub_8095730(struct MapObject *mapObject, struct Sprite *sprite) } #define affine_an_walk_any_2_macro(name, fn, fn2, action, anim, ...)\ -static bool8 name##_2(struct MapObject *, struct Sprite *);\ +bool8 name##_2(struct MapObject *, struct Sprite *);\ bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ {\ fn(mapObject, sprite, __VA_ARGS__);\ @@ -4849,7 +4850,7 @@ bool8 name(struct MapObject *mapObject, struct Sprite *sprite)\ action(sprite, anim);\ return name##_2(mapObject, sprite);\ }\ -static bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ +bool8 name##_2(struct MapObject *mapObject, struct Sprite *sprite)\ {\ if (fn2(mapObject, sprite))\ {\ @@ -4936,8 +4937,6 @@ bool8 sub_8095B0C(struct MapObject *mapObject, struct Sprite *sprite) return FALSE; } -static bool8 sub_8095B64(struct MapObject *, struct Sprite *); - bool8 sub_8095B44(struct MapObject *mapObject, struct Sprite *sprite) { sub_8095AF0(mapObject, sprite); @@ -4945,7 +4944,7 @@ bool8 sub_8095B44(struct MapObject *mapObject, struct Sprite *sprite) return sub_8095B64(mapObject, sprite); } -static bool8 sub_8095B64(struct MapObject *mapObject, struct Sprite *sprite) +bool8 sub_8095B64(struct MapObject *mapObject, struct Sprite *sprite) { if (sub_8095B0C(mapObject, sprite)) { -- cgit v1.2.3 From 16f2e40576b29fd85366305b4165da3aff4aef0e Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 17 Sep 2017 23:42:44 -0400 Subject: Fix naming conflicts --- src/berry.c | 6 +++--- src/load_save.c | 4 ---- src/reset_save_heap.c | 32 ++++++++++++++++++++++++++++++++ src/rom_81700F8.c | 32 -------------------------------- 4 files changed, 35 insertions(+), 39 deletions(-) create mode 100644 src/reset_save_heap.c delete mode 100644 src/rom_81700F8.c (limited to 'src') diff --git a/src/berry.c b/src/berry.c index b6eaa14a0..46b93d6ff 100644 --- a/src/berry.c +++ b/src/berry.c @@ -807,7 +807,7 @@ const struct Berry gBerries[] = // unused void ClearEnigmaBerries(void) { - CpuFill16(0, &gSaveBlock1Ptr->enigmaBerry, sizeof(gSaveBlock1Ptr->enigmaBerry)); + CpuFill16(0, &gSaveBlock1Ptr->enigmaBerry, 52 /*FIXME: sizeof(gSaveBlock1Ptr->enigmaBerry)*/); } void SetEnigmaBerry(u8 *src) @@ -815,7 +815,7 @@ void SetEnigmaBerry(u8 *src) u32 i; u8 *dest = (u8*)&gSaveBlock1Ptr->enigmaBerry; - for (i = 0; i < sizeof(gSaveBlock1Ptr->enigmaBerry); i++) + for (i = 0; i < 52 /*FIXME: sizeof(gSaveBlock1Ptr->enigmaBerry)*/; i++) dest[i] = src[i]; } @@ -827,7 +827,7 @@ u32 GetEnigmaBerryChecksum(struct EnigmaBerry *enigmaBerry) dest = (u8*)enigmaBerry; checksum = 0; - for (i = 0; i < sizeof(gSaveBlock1Ptr->enigmaBerry) - sizeof(gSaveBlock1Ptr->enigmaBerry.checksum); i++) + for (i = 0; i < 52 /*FIXME: sizeof(gSaveBlock1Ptr->enigmaBerry)*/ - sizeof(gSaveBlock1Ptr->enigmaBerry.checksum); i++) { checksum += dest[i]; } diff --git a/src/load_save.c b/src/load_save.c index 588387186..68d978e3d 100644 --- a/src/load_save.c +++ b/src/load_save.c @@ -6,15 +6,11 @@ #include "rng.h" #include "malloc.h" -extern u8 gPlayerPartyCount; -extern struct PokemonStorage* gPokemonStoragePtr; extern void* gUnknown_0203CF5C; -extern u8 gHeap[0x1C000]; extern bool16 IdentifyFlash(void); extern void SetBagItemsPointers(void); extern void SetDecorationInventoriesPointers(void); -extern void InitHeap(void *heapStart, u32 heapSize); void ApplyNewEncyprtionKeyToAllEncryptedData(u32 encryptionKey); diff --git a/src/reset_save_heap.c b/src/reset_save_heap.c new file mode 100644 index 000000000..b786ff9f8 --- /dev/null +++ b/src/reset_save_heap.c @@ -0,0 +1,32 @@ +#include "global.h" +#include "main.h" +#include "gpu_regs.h" +#include "m4a.h" +#include "load_save.h" +#include "save.h" +#include "new_game.h" +#include "rom4.h" +#include "malloc.h" + +void sub_81700F8(void) +{ + u16 imeBackup; + + imeBackup = REG_IME; + REG_IME = 0; + RegisterRamReset(0x00000001); + ClearGpuRegBits(REG_OFFSET_DISPCNT, 0x80); + REG_IME = imeBackup; + gMain.inBattle = FALSE; + SetSaveBlocksPointers(sub_815355C()); + sub_808447C(); + ResetSaveCounters(); + sub_81534D0(0); + if (gSaveFileStatus == 0 || gSaveFileStatus == 2) + { + Sav2_ClearSetDefault(); + } + SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound); + InitHeap(gHeap, 0x1c000); + SetMainCallback2(sub_8086230); +} diff --git a/src/rom_81700F8.c b/src/rom_81700F8.c deleted file mode 100644 index b786ff9f8..000000000 --- a/src/rom_81700F8.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "global.h" -#include "main.h" -#include "gpu_regs.h" -#include "m4a.h" -#include "load_save.h" -#include "save.h" -#include "new_game.h" -#include "rom4.h" -#include "malloc.h" - -void sub_81700F8(void) -{ - u16 imeBackup; - - imeBackup = REG_IME; - REG_IME = 0; - RegisterRamReset(0x00000001); - ClearGpuRegBits(REG_OFFSET_DISPCNT, 0x80); - REG_IME = imeBackup; - gMain.inBattle = FALSE; - SetSaveBlocksPointers(sub_815355C()); - sub_808447C(); - ResetSaveCounters(); - sub_81534D0(0); - if (gSaveFileStatus == 0 || gSaveFileStatus == 2) - { - Sav2_ClearSetDefault(); - } - SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound); - InitHeap(gHeap, 0x1c000); - SetMainCallback2(sub_8086230); -} -- cgit v1.2.3 From ecd659f46ef26be357118543321d8f4ef7e2e4e9 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Mon, 18 Sep 2017 12:51:16 +0200 Subject: add side labels --- src/battle_3.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index af3d4ebdd..d5d14e040 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -1473,11 +1473,11 @@ bool8 sub_80423F4(u8 bank, u8 r1, u8 r2) return FALSE; if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) { - if (GetBankSide(bank) == 0) + if (GetBankSide(bank) == SIDE_PLAYER) party = gPlayerParty; else party = gEnemyParty; - r6 = ((bank & 2) >> 1); + r6 = ((bank & 2) / 2); for (i = r6 * 3; i < r6 * 3 + 3; i++) { if (GetMonData(&party[i], MON_DATA_HP) != 0 @@ -1508,13 +1508,13 @@ bool8 sub_80423F4(u8 bank, u8 r1, u8 r2) party = gEnemyParty; var = bank ^ 1; - r6 = (var == 0) ? 0 : 1; + r6 = (var != 0) ? 1 : 0; } } else { r7 = sub_806D864(bank); - if (GetBankSide(bank) == 0) + if (GetBankSide(bank) == SIDE_PLAYER) party = gPlayerParty; else party = gEnemyParty; @@ -1529,7 +1529,7 @@ bool8 sub_80423F4(u8 bank, u8 r1, u8 r2) } return (i == r6 * 3 + 3); } - else if ((gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) && GetBankSide(bank) == 1) + else if ((gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) && GetBankSide(bank) == SIDE_OPPONENT) { party = gEnemyParty; @@ -1548,7 +1548,7 @@ bool8 sub_80423F4(u8 bank, u8 r1, u8 r2) } else { - if (GetBankSide(bank) == 1) + if (GetBankSide(bank) == SIDE_OPPONENT) { r7 = GetBankByPlayerAI(1); r6 = GetBankByPlayerAI(3); @@ -5595,7 +5595,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) u8 ppBonuses; u16 move; - if (GetBankSide(bank) == 0) + if (GetBankSide(bank) == SIDE_PLAYER) poke = &gPlayerParty[gBattlePartyID[bank]]; else poke = &gEnemyParty[gBattlePartyID[bank]]; @@ -6272,7 +6272,7 @@ u8 GetMoveTarget(u16 move, u8 useMoveTarget) targetBank = gSideTimers[side].followmeTarget; else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & 4) { - if (GetBankSide(gBankAttacker) == 0) + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) { if (Random() & 1) targetBank = GetBankByPlayerAI(1); -- cgit v1.2.3 From 8604291b0f0e430b01f0099ea4e098171938505b Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 18 Sep 2017 08:52:57 -0400 Subject: Start decomp --- src/berry_fix_program.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/berry_fix_program.c (limited to 'src') diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c new file mode 100644 index 000000000..bafefaf7a --- /dev/null +++ b/src/berry_fix_program.c @@ -0,0 +1,123 @@ + +// Includes +#include "global.h" +#include "multiboot.h" +#include "gpu_regs.h" +#include "main.h" +#include "sprite.h" +#include "task.h" +#include "unknown_task.h" +#include "malloc.h" +#include "m4a.h" + +// Static type declarations + +typedef struct { + u8 state; + u8 unk1; + u16 unk2; + struct MultiBootParam mb; +} berryfix_t; + +// Static RAM declarations + +extern berryfix_t *gUnknown_030012B8; + +// Static ROM declarations + +static void sub_81BF3DC(void); +void sub_81BF5A4(void); +u32 sub_81BF7A4(u8); + +// .rodata + +extern const u8 gUnknown_089A6550[0xC0]; +extern const u8 gMultiBootProgram_BerryGlitchFix_Script[0x3b34]; +extern const u8 gMultiBootProgram_BerryGlitchFix_Start[]; +extern const u8 gMultiBootProgram_BerryGlitchFix_End[]; + +// .text + +void sub_81BF384(void) +{ + DisableInterrupts(0xFFFF); + EnableInterrupts(0x0001); + m4aSoundVSyncOff(); + SetVBlankCallback(NULL); + ResetSpriteData(); + ResetTasks(); + remove_some_task(); + SetGpuReg(REG_OFFSET_DISPCNT, 0x0000); + gUnknown_030012B8 = AllocZeroed(0x50); + gUnknown_030012B8->state = 0; + gUnknown_030012B8->unk1 = 6; + SetMainCallback2(sub_81BF3DC); +} + +static void sub_81BF3DC(void) +{ + switch (gUnknown_030012B8->state) + { + case 0: + sub_81BF5A4(); + gUnknown_030012B8->state = 1; + break; + case 1: + if (sub_81BF7A4(5) == 5 && (gMain.newKeys & A_BUTTON)) + { + gUnknown_030012B8->state = 2; + } + break; + case 2: + if (sub_81BF7A4(0) == 0 && (gMain.newKeys & A_BUTTON)) + { + gUnknown_030012B8->state = 3; + } + break; + case 3: + if (sub_81BF7A4(1) == 1) + { + gUnknown_030012B8->mb.masterp = gUnknown_089A6550; + gUnknown_030012B8->mb.server_type = 0; + MultiBootInit(&gUnknown_030012B8->mb); + gUnknown_030012B8->unk2 = 0; + gUnknown_030012B8->state = 4; + } + break; + case 4: + MultiBootMain(&gUnknown_030012B8->mb); + if (gUnknown_030012B8->mb.probe_count != 0 || (!(gUnknown_030012B8->mb.response_bit & 2) || !(gUnknown_030012B8->mb.client_bit & 2))) + { + gUnknown_030012B8->unk2 = 0; + } + else if (++ gUnknown_030012B8->unk2 > 180) + { + MultiBootStartMaster(&gUnknown_030012B8->mb, gMultiBootProgram_BerryGlitchFix_Start, (u32)(gMultiBootProgram_BerryGlitchFix_End - gMultiBootProgram_BerryGlitchFix_Start), 4, 1); + gUnknown_030012B8->state = 5; + } + break; + case 5: + if (sub_81BF7A4(2) == 2) { + MultiBootMain(&gUnknown_030012B8->mb); + if (MultiBootCheckComplete(&gUnknown_030012B8->mb)) { + gUnknown_030012B8->state = 6; + } + else if (!(gUnknown_030012B8->mb.client_bit & 2)) { + gUnknown_030012B8->state = 7; + } + } + break; + case 6: + if (sub_81BF7A4(3) == 3 && gMain.newKeys & A_BUTTON) + { + DoSoftReset(); + } + break; + case 7: + if (sub_81BF7A4(4) == 4 && gMain.newKeys & A_BUTTON) + { + gUnknown_030012B8->state = 1; + } + break; + } +} -- cgit v1.2.3 From c5dddf41f58446139b52d3b60cb8738052e4a084 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 18 Sep 2017 11:26:45 -0400 Subject: sub_81BF5A4 --- src/berry_fix_program.c | 272 +++++++++++++++++++++++++++++++++++++++++++++++- src/bg.c | 189 ++++++++++++++++----------------- src/multiboot.c | 2 +- src/text.c | 6 +- src/window.c | 2 +- 5 files changed, 364 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c index bafefaf7a..58e50e509 100644 --- a/src/berry_fix_program.c +++ b/src/berry_fix_program.c @@ -1,13 +1,16 @@ // Includes #include "global.h" -#include "multiboot.h" #include "gpu_regs.h" +#include "multiboot.h" +#include "malloc.h" +#include "bg.h" #include "main.h" #include "sprite.h" #include "task.h" #include "unknown_task.h" -#include "malloc.h" +#include "window.h" +#include "menu.h" #include "m4a.h" // Static type declarations @@ -26,7 +29,7 @@ extern berryfix_t *gUnknown_030012B8; // Static ROM declarations static void sub_81BF3DC(void); -void sub_81BF5A4(void); +static void sub_81BF5A4(void); u32 sub_81BF7A4(u8); // .rodata @@ -35,6 +38,14 @@ extern const u8 gUnknown_089A6550[0xC0]; extern const u8 gMultiBootProgram_BerryGlitchFix_Script[0x3b34]; extern const u8 gMultiBootProgram_BerryGlitchFix_Start[]; extern const u8 gMultiBootProgram_BerryGlitchFix_End[]; +extern const u8 gUnknown_08617E78[]; +extern const u8 gUnknown_08617E8D[]; +extern const u8 gUnknown_08617E9B[]; +extern const struct BgTemplate gUnknown_08618108[2]; +extern const struct WindowTemplate gUnknown_08618110[7]; +extern const u16 gUnknown_08618138[16]; +extern const u8 gUnknown_08618158[3]; +extern const u8 gUnknown_0861815B[3]; // .text @@ -121,3 +132,258 @@ static void sub_81BF3DC(void) break; } } + +#ifdef NONMATCHING +static void sub_81BF5A4(void) +{ + s32 width; + + SetGpuReg(REG_OFFSET_BG0CNT, 0x0000); + SetGpuReg(REG_OFFSET_BG1CNT, 0x0000); + SetGpuReg(REG_OFFSET_BG0HOFS, 0x0000); + SetGpuReg(REG_OFFSET_BG0VOFS, 0x0000); + SetGpuReg(REG_OFFSET_BG1HOFS, 0x0000); + SetGpuReg(REG_OFFSET_BG1VOFS, 0x0000); + SetGpuReg(REG_OFFSET_BLDCNT, 0x0000); + + DmaFill32(3, 0, VRAM, VRAM_SIZE); + DmaFill32(3, 0, OAM, OAM_SIZE); + DmaFill32(3, 0, PLTT, PLTT_SIZE); + ResetBgsAndClearDma3BusyFlags(0); + + InitBgsFromTemplates(0, gUnknown_08618108, ARRAY_COUNT(gUnknown_08618108)); + ChangeBgX(0, 0, 0); + ChangeBgY(0, 0, 0); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + InitWindows(gUnknown_08618110); + DeactivateAllTextPrinters(); + + DmaCopy32(3, gUnknown_08618138, BG_PLTT + 0x1E0, 0x20); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP); + FillWindowPixelBuffer(2, 0); + FillWindowPixelBuffer(3, 0); + FillWindowPixelBuffer(0, 0xAA); + +// This block is a meme among memes + width = (0x78 - GetStringWidth(0, gUnknown_08617E9B, 0)) / 2; + box_print(2, 0, width, 3, gUnknown_0861815B, -1, gUnknown_08617E9B); + width = (s32)(0x78 - GetStringWidth(0, gUnknown_08617E9B, 0)) / 2 + 0x78; + box_print(2, 0, width, 3, gUnknown_0861815B, -1, gUnknown_08617E8D); + width = (0x70 - GetStringWidth(0, gUnknown_08617E8D, 0)) / 2; + box_print(3, 0, width, 0, gUnknown_0861815B, -1, gUnknown_08617E8D); + width = (0xd0 - GetStringWidth(1, gUnknown_08617E78, 0)) / 2; + box_print(0, 1, width, 2, gUnknown_08618158, -1, gUnknown_08617E78); + + CopyWindowToVram(2, 2); + CopyWindowToVram(3, 2); + CopyWindowToVram(0, 2); +} +#else +__attribute__((naked)) static void sub_81BF5A4(void) +{ + asm(".syntax unified\n" + "\tpush {r4-r6,lr}\n" + "\tmov r6, r8\n" + "\tpush {r6}\n" + "\tsub sp, 0x10\n" + "\tmovs r0, 0x8\n" + "\tmovs r1, 0\n" + "\tbl SetGpuReg\n" + "\tmovs r0, 0xA\n" + "\tmovs r1, 0\n" + "\tbl SetGpuReg\n" + "\tmovs r0, 0x10\n" + "\tmovs r1, 0\n" + "\tbl SetGpuReg\n" + "\tmovs r0, 0x12\n" + "\tmovs r1, 0\n" + "\tbl SetGpuReg\n" + "\tmovs r0, 0x14\n" + "\tmovs r1, 0\n" + "\tbl SetGpuReg\n" + "\tmovs r0, 0x16\n" + "\tmovs r1, 0\n" + "\tbl SetGpuReg\n" + "\tmovs r0, 0x50\n" + "\tmovs r1, 0\n" + "\tbl SetGpuReg\n" + "\tmovs r1, 0\n" + "\tstr r1, [sp, 0xC]\n" + "\tldr r4, =0x040000d4\n" + "\tadd r0, sp, 0xC\n" + "\tstr r0, [r4]\n" + "\tmovs r0, 0xC0\n" + "\tlsls r0, 19\n" + "\tstr r0, [r4, 0x4]\n" + "\tldr r0, =0x85006000\n" + "\tstr r0, [r4, 0x8]\n" + "\tldr r0, [r4, 0x8]\n" + "\tstr r1, [sp, 0xC]\n" + "\tadd r0, sp, 0xC\n" + "\tstr r0, [r4]\n" + "\tmovs r0, 0xE0\n" + "\tlsls r0, 19\n" + "\tstr r0, [r4, 0x4]\n" + "\tldr r2, =0x85000100\n" + "\tstr r2, [r4, 0x8]\n" + "\tldr r0, [r4, 0x8]\n" + "\tstr r1, [sp, 0xC]\n" + "\tadd r0, sp, 0xC\n" + "\tstr r0, [r4]\n" + "\tmovs r0, 0xA0\n" + "\tlsls r0, 19\n" + "\tstr r0, [r4, 0x4]\n" + "\tstr r2, [r4, 0x8]\n" + "\tldr r0, [r4, 0x8]\n" + "\tmovs r0, 0\n" + "\tbl ResetBgsAndClearDma3BusyFlags\n" + "\tldr r1, =gUnknown_08618108\n" + "\tmovs r0, 0\n" + "\tmovs r2, 0x2\n" + "\tbl InitBgsFromTemplates\n" + "\tmovs r0, 0\n" + "\tmovs r1, 0\n" + "\tmovs r2, 0\n" + "\tbl ChangeBgX\n" + "\tmovs r0, 0\n" + "\tmovs r1, 0\n" + "\tmovs r2, 0\n" + "\tbl ChangeBgY\n" + "\tmovs r0, 0x1\n" + "\tmovs r1, 0\n" + "\tmovs r2, 0\n" + "\tbl ChangeBgX\n" + "\tmovs r0, 0x1\n" + "\tmovs r1, 0\n" + "\tmovs r2, 0\n" + "\tbl ChangeBgY\n" + "\tldr r0, =gUnknown_08618110\n" + "\tbl InitWindows\n" + "\tbl DeactivateAllTextPrinters\n" + "\tldr r0, =gUnknown_08618138\n" + "\tstr r0, [r4]\n" + "\tldr r0, =0x050001e0\n" + "\tstr r0, [r4, 0x4]\n" + "\tldr r0, =0x84000008\n" + "\tstr r0, [r4, 0x8]\n" + "\tldr r0, [r4, 0x8]\n" + "\tmovs r0, 0\n" + "\tmovs r1, 0x40\n" + "\tbl SetGpuReg\n" + "\tmovs r0, 0x2\n" + "\tmovs r1, 0\n" + "\tbl FillWindowPixelBuffer\n" + "\tmovs r0, 0x3\n" + "\tmovs r1, 0\n" + "\tbl FillWindowPixelBuffer\n" + "\tmovs r0, 0\n" + "\tmovs r1, 0xAA\n" + "\tbl FillWindowPixelBuffer\n" + "\tldr r5, =gUnknown_08617E9B\n" + "\tmovs r0, 0\n" + "\tadds r1, r5, 0\n" + "\tmovs r2, 0\n" + "\tbl GetStringWidth\n" + "\tadds r1, r0, 0\n" + "\tmovs r4, 0x78\n" + "\tsubs r0, r4, r1\n" + "\tlsrs r1, r0, 31\n" + "\tadds r0, r1\n" + "\tasrs r0, 1\n" + "\tlsls r2, r0, 24\n" + "\tlsrs r2, 24\n" + "\tldr r6, =gUnknown_0861815B\n" + "\tstr r6, [sp]\n" + "\tmovs r0, 0x1\n" + "\tnegs r0, r0\n" + "\tmov r8, r0\n" + "\tstr r0, [sp, 0x4]\n" + "\tstr r5, [sp, 0x8]\n" + "\tmovs r0, 0x2\n" + "\tmovs r1, 0\n" + "\tmovs r3, 0x3\n" + "\tbl box_print\n" + "\tldr r5, =gUnknown_08617E8D\n" + "\tmovs r0, 0\n" + "\tadds r1, r5, 0\n" + "\tmovs r2, 0\n" + "\tbl GetStringWidth\n" + "\tadds r1, r0, 0\n" + "\tsubs r4, r1\n" + "\tlsrs r0, r4, 31\n" + "\tadds r4, r0\n" + "\tasrs r4, 1\n" + "\tadds r0, r4, 0\n" + "\tadds r0, 0x78\n" + "\tlsls r2, r0, 24\n" + "\tlsrs r2, 24\n" + "\tstr r6, [sp]\n" + "\tmov r0, r8\n" + "\tstr r0, [sp, 0x4]\n" + "\tstr r5, [sp, 0x8]\n" + "\tmovs r0, 0x2\n" + "\tmovs r1, 0\n" + "\tmovs r3, 0x3\n" + "\tbl box_print\n" + "\tmovs r0, 0\n" + "\tadds r1, r5, 0\n" + "\tmovs r2, 0\n" + "\tbl GetStringWidth\n" + "\tadds r1, r0, 0\n" + "\tmovs r0, 0x70\n" + "\tsubs r0, r1\n" + "\tlsrs r1, r0, 31\n" + "\tadds r0, r1\n" + "\tasrs r0, 1\n" + "\tlsls r2, r0, 24\n" + "\tlsrs r2, 24\n" + "\tstr r6, [sp]\n" + "\tmov r0, r8\n" + "\tstr r0, [sp, 0x4]\n" + "\tstr r5, [sp, 0x8]\n" + "\tmovs r0, 0x3\n" + "\tmovs r1, 0\n" + "\tmovs r3, 0\n" + "\tbl box_print\n" + "\tldr r4, =gUnknown_08617E78\n" + "\tmovs r0, 0x1\n" + "\tadds r1, r4, 0\n" + "\tmovs r2, 0\n" + "\tbl GetStringWidth\n" + "\tadds r1, r0, 0\n" + "\tmovs r0, 0xD0\n" + "\tsubs r0, r1\n" + "\tlsrs r1, r0, 31\n" + "\tadds r0, r1\n" + "\tasrs r0, 1\n" + "\tlsls r2, r0, 24\n" + "\tlsrs r2, 24\n" + "\tldr r0, =gUnknown_08618158\n" + "\tstr r0, [sp]\n" + "\tmov r0, r8\n" + "\tstr r0, [sp, 0x4]\n" + "\tstr r4, [sp, 0x8]\n" + "\tmovs r0, 0\n" + "\tmovs r1, 0x1\n" + "\tmovs r3, 0x2\n" + "\tbl box_print\n" + "\tmovs r0, 0x2\n" + "\tmovs r1, 0x2\n" + "\tbl CopyWindowToVram\n" + "\tmovs r0, 0x3\n" + "\tmovs r1, 0x2\n" + "\tbl CopyWindowToVram\n" + "\tmovs r0, 0\n" + "\tmovs r1, 0x2\n" + "\tbl CopyWindowToVram\n" + "\tadd sp, 0x10\n" + "\tpop {r3}\n" + "\tmov r8, r3\n" + "\tpop {r4-r6}\n" + "\tpop {r0}\n" + "\tbx r0\n" + "\t.pool\n" + ".syntax divided"); +} +#endif diff --git a/src/bg.c b/src/bg.c index 8979eaecd..390a99d50 100644 --- a/src/bg.c +++ b/src/bg.c @@ -1,5 +1,6 @@ #include "global.h" #include "dma3.h" +#include "bg.h" #define DISPCNT_ALL_BG_AND_MODE_BITS 0x0F07 @@ -22,33 +23,23 @@ struct BgControl { u16 priority:2; u16 mosaic:1; u16 wraparound:1; - + u16 charBaseIndex:2; u16 mapBaseIndex:5; u16 paletteMode:1; - + u8 unknown_2; u8 unknown_3; } configs[4]; - - u16 bgVisibilityAndMode; -}; -struct BgTemplate { - u32 bg:2; - u32 charBaseIndex:2; - u32 mapBaseIndex:5; - u32 screenSize:2; - u32 paletteMode:1; - u32 priority:2; - u32 baseTile:10; + u16 bgVisibilityAndMode; }; struct BgConfig2 { u32 baseTile:10; u32 basePalette:4; u32 unk_3:18; - + void* tilemap; u32 bg_x; u32 bg_y; @@ -103,7 +94,7 @@ void ResetBgControlStructs(void) struct BgConfig* bgConfigs = &gGpuBgConfigs.configs[0]; struct BgConfig zeroedConfig = gZeroedBgControlStruct; int i; - + for (i = 0; i < 4; i++) { bgConfigs[i] = zeroedConfig; @@ -126,40 +117,40 @@ void SetBgControlAttributes(u8 bg, u8 charBaseIndex, u8 mapBaseIndex, u8 screenS { gGpuBgConfigs.configs[bg].charBaseIndex = charBaseIndex & 0x3; } - + if (mapBaseIndex != 0xFF) { gGpuBgConfigs.configs[bg].mapBaseIndex = mapBaseIndex & 0x1F; } - + if (screenSize != 0xFF) { gGpuBgConfigs.configs[bg].screenSize = screenSize & 0x3; } - + if (paletteMode != 0xFF) { gGpuBgConfigs.configs[bg].paletteMode = paletteMode; } - + if (priority != 0xFF) { gGpuBgConfigs.configs[bg].priority = priority & 0x3; } - + if (mosaic != 0xFF) { gGpuBgConfigs.configs[bg].mosaic = mosaic & 0x1; } - + if (wraparound != 0xFF) { gGpuBgConfigs.configs[bg].wraparound = wraparound; } - + gGpuBgConfigs.configs[bg].unknown_2 = 0; gGpuBgConfigs.configs[bg].unknown_3 = 0; - + gGpuBgConfigs.configs[bg].visible = 1; } } @@ -188,7 +179,7 @@ u16 GetBgControlAttribute(u8 bg, u8 attributeId) return gGpuBgConfigs.configs[bg].wraparound; } } - + return 0xFF; } @@ -196,7 +187,7 @@ u8 LoadBgVram(u8 bg, void *src, u16 size, u16 destOffset, u8 mode) { u16 offset; s8 cursor; - + if (IsInvalidBg(bg) == FALSE && gGpuBgConfigs.configs[bg].visible != FALSE) { switch (mode) @@ -211,11 +202,11 @@ u8 LoadBgVram(u8 bg, void *src, u16 size, u16 destOffset, u8 mode) cursor = -1; goto end; } - + offset = destOffset + offset; - + cursor = RequestDma3Copy(src, (void*)(offset + BG_VRAM), size, 0); - + if (cursor == -1) { return -1; @@ -225,7 +216,7 @@ u8 LoadBgVram(u8 bg, void *src, u16 size, u16 destOffset, u8 mode) { return -1; } - + end: return cursor; } @@ -242,9 +233,9 @@ void ShowBgInternal(u8 bg) (gGpuBgConfigs.configs[bg].mapBaseIndex << 8) | (gGpuBgConfigs.configs[bg].wraparound << 13) | (gGpuBgConfigs.configs[bg].screenSize << 14); - + SetGpuReg((bg << 1) + 0x8, value); - + gGpuBgConfigs.bgVisibilityAndMode |= 1 << (bg + 8); gGpuBgConfigs.bgVisibilityAndMode &= DISPCNT_ALL_BG_AND_MODE_BITS; } @@ -273,7 +264,7 @@ void SetBgAffineInternal(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, { struct BgAffineSrcData src; struct BgAffineDstData dest; - + switch (gGpuBgConfigs.bgVisibilityAndMode & 0x7) { case 1: @@ -288,7 +279,7 @@ void SetBgAffineInternal(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, default: return; } - + src.texX = srcCenterX; src.texY = srcCenterY; src.scrX = dispCenterX; @@ -296,7 +287,7 @@ void SetBgAffineInternal(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, src.sx = scaleX; src.sy = scaleY; src.alpha = rotationAngle; - + BgAffineSet(&src, &dest, 1); SetGpuReg(REG_OFFSET_BG2PA, dest.pa); @@ -326,20 +317,20 @@ void ResetBgsAndClearDma3BusyFlags(u32 leftoverFireRedLeafGreenVariable) { int i; ResetBgs(); - + for (i = 0; i < 4; i++) { gDmaBusyBitfield[i] = 0; } - + gUnneededFireRedVariable = leftoverFireRedLeafGreenVariable; } -void InitBgsFromTemplates(u8 bgMode, struct BgTemplate *templates, u8 numTemplates) +void InitBgsFromTemplates(u8 bgMode, const struct BgTemplate *templates, u8 numTemplates) { int i; u8 bg; - + SetBgModeInternal(bgMode); ResetBgControlStructs(); @@ -355,11 +346,11 @@ void InitBgsFromTemplates(u8 bgMode, struct BgTemplate *templates, u8 numTemplat templates[i].priority, 0, 0); - + gGpuBgConfigs2[bg].baseTile = templates[i].baseTile; gGpuBgConfigs2[bg].basePalette = 0; gGpuBgConfigs2[bg].unk_3 = 0; - + gGpuBgConfigs2[bg].tilemap = NULL; gGpuBgConfigs2[bg].bg_x = 0; gGpuBgConfigs2[bg].bg_y = 0; @@ -367,10 +358,10 @@ void InitBgsFromTemplates(u8 bgMode, struct BgTemplate *templates, u8 numTemplat } } -void InitBgFromTemplate(struct BgTemplate *template) +void InitBgFromTemplate(const struct BgTemplate *template) { u8 bg = template->bg; - + if (bg < 4) { SetBgControlAttributes(bg, @@ -381,11 +372,11 @@ void InitBgFromTemplate(struct BgTemplate *template) template->priority, 0, 0); - + gGpuBgConfigs2[bg].baseTile = template->baseTile; gGpuBgConfigs2[bg].basePalette = 0; gGpuBgConfigs2[bg].unk_3 = 0; - + gGpuBgConfigs2[bg].tilemap = NULL; gGpuBgConfigs2[bg].bg_x = 0; gGpuBgConfigs2[bg].bg_y = 0; @@ -401,7 +392,7 @@ u16 LoadBgTiles(u8 bg, void* src, u16 size, u16 destOffset) { u16 tileOffset; u8 cursor; - + if (GetBgControlAttribute(bg, BG_CTRL_ATTR_PALETTEMODE) == 0) { tileOffset = (gGpuBgConfigs2[bg].baseTile + destOffset) * 0x20; @@ -410,37 +401,37 @@ u16 LoadBgTiles(u8 bg, void* src, u16 size, u16 destOffset) { tileOffset = (gGpuBgConfigs2[bg].baseTile + destOffset) * 0x40; } - + cursor = LoadBgVram(bg, src, size, tileOffset, DISPCNT_MODE_1); - + if (cursor == 0xFF) { return -1; } - + gDmaBusyBitfield[cursor / 0x20] |= (1 << (cursor % 0x20)); - + if (gUnneededFireRedVariable == 1) { DummiedOutFireRedLeafGreenTileAllocFunc(bg, tileOffset / 0x20, size / 0x20, 1); } - + return cursor; } u16 LoadBgTilemap(u8 bg, void *src, u16 size, u16 destOffset) { u8 cursor; - + cursor = LoadBgVram(bg, src, size, destOffset * 2, DISPCNT_MODE_2); - + if (cursor == 0xFF) { return -1; } - + gDmaBusyBitfield[cursor / 0x20] |= (1 << (cursor % 0x20)); - + return cursor; } @@ -448,12 +439,12 @@ u16 Unused_LoadBgPalette(u8 bg, void *src, u16 size, u16 destOffset) { u16 paletteOffset; s8 cursor; - + if (IsInvalidBg32(bg) == FALSE) { paletteOffset = (gGpuBgConfigs2[bg].basePalette * 0x20) + (destOffset * 2); cursor = RequestDma3Copy(src, (void*)(paletteOffset + BG_PLTT), size, 0); - + if (cursor == -1) { return -1; @@ -475,14 +466,14 @@ bool8 IsDma3ManagerBusyWithBgCopy(void) u8 mod; u8 div; s8 reqSpace; - + int i; - + for (i = 0; i < 0x80; i++) { div = i / 0x20; mod = i % 0x20; - + if ((gDmaBusyBitfield[div] & (1 << mod)) != FALSE) { reqSpace = CheckForSpaceForDma3Request(i); @@ -490,7 +481,7 @@ bool8 IsDma3ManagerBusyWithBgCopy(void) { return TRUE; } - + gDmaBusyBitfield[div] &= ~(1 << mod); } } @@ -634,12 +625,12 @@ u32 ChangeBgX(u8 bg, u32 value, u8 op) u8 mode; u16 temp1; u16 temp2; - + if (IsInvalidBg32(bg) != FALSE || GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) == 0) { return -1; } - + switch (op) { case 0: @@ -653,9 +644,9 @@ u32 ChangeBgX(u8 bg, u32 value, u8 op) gGpuBgConfigs2[bg].bg_x -= value; break; } - + mode = GetBgMode(); - + switch (bg) { case 0: @@ -695,7 +686,7 @@ u32 ChangeBgX(u8 bg, u32 value, u8 op) } break; } - + return gGpuBgConfigs2[bg].bg_x; } @@ -713,12 +704,12 @@ u32 ChangeBgY(u8 bg, u32 value, u8 op) u8 mode; u16 temp1; u16 temp2; - + if (IsInvalidBg32(bg) != FALSE || GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) == 0) { return -1; } - + switch (op) { case 0: @@ -732,9 +723,9 @@ u32 ChangeBgY(u8 bg, u32 value, u8 op) gGpuBgConfigs2[bg].bg_y -= value; break; } - + mode = GetBgMode(); - + switch (bg) { case 0: @@ -774,7 +765,7 @@ u32 ChangeBgY(u8 bg, u32 value, u8 op) } break; } - + return gGpuBgConfigs2[bg].bg_y; } @@ -783,12 +774,12 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) u8 mode; u16 temp1; u16 temp2; - + if (IsInvalidBg32(bg) != FALSE || GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) == 0) { return -1; } - + switch (op) { case 0: @@ -802,9 +793,9 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) gGpuBgConfigs2[bg].bg_y -= value; break; } - + mode = GetBgMode(); - + switch (bg) { case 0: @@ -820,7 +811,7 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) { temp1 = gGpuBgConfigs2[2].bg_y >> 0x8; SetGpuReg_ForcedBlank(REG_OFFSET_BG2VOFS, temp1); - + } else { @@ -845,7 +836,7 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) } break; } - + return gGpuBgConfigs2[bg].bg_y; } @@ -868,13 +859,13 @@ u8 Unused_AdjustBgMosaic(u8 a1, u8 a2) u16 result; s16 test1; s16 test2; - + result = GetGpuReg(REG_OFFSET_MOSAIC); - + test1 = result & 0xF; test2 = (result >> 4) & 0xF; result &= 0xFF00; - + switch (a2) { case 0: @@ -929,12 +920,12 @@ u8 Unused_AdjustBgMosaic(u8 a1, u8 a2) } break; } - + result |= ((test2 << 0x4) & 0xF0); result |= (test1 & 0xF); - + SetGpuReg(REG_OFFSET_MOSAIC, result); - + return result; } @@ -981,7 +972,7 @@ void CopyToBgTilemapBuffer(u8 bg, void *src, u16 mode, u16 destOffset) void CopyBgTilemapBufferToVram(u8 bg) { u16 sizeToLoad; - + if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { switch (GetBgType(bg)) @@ -1006,7 +997,7 @@ void CopyToBgTilemapBufferRect(u8 bg, void* src, u8 destX, u8 destY, u8 width, u u16 destX16; u16 destY16; u16 mode; - + if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { switch (GetBgType(bg)) @@ -1047,11 +1038,11 @@ void CopyRectToBgTilemapBufferRect(u8 bg, void* src, u8 srcX, u8 srcY, u8 srcWid u16 attribute; u16 mode; u16 mode2; - + void* srcCopy; u16 destX16; u16 destY16; - + if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { attribute = GetBgControlAttribute(bg, BG_CTRL_ATTR_SCREENSIZE); @@ -1336,7 +1327,7 @@ void FillBgTilemapBufferRect_Palette0(u8 bg, u16 tileNum, u8 x, u8 y, u8 width, u16 x16; u16 y16; u16 mode; - + if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { switch (GetBgType(bg)) @@ -1375,10 +1366,10 @@ void WriteSequenceToBgTilemapBuffer(u8 bg, u16 firstTileNum, u8 x, u8 y, u8 widt u16 mode2; u16 attribute; u16 mode3; - + u16 x16; u16 y16; - + if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { attribute = GetBgControlAttribute(bg, BG_CTRL_ATTR_SCREENSIZE); @@ -1414,9 +1405,9 @@ void WriteSequenceToBgTilemapBuffer(u8 bg, u16 firstTileNum, u8 x, u8 y, u8 widt u16 GetBgMetricTextMode(u8 bg, u8 whichMetric) { u8 attribute; - + attribute = GetBgControlAttribute(bg, BG_CTRL_ATTR_SCREENSIZE); - + switch (whichMetric) { case 0: @@ -1462,9 +1453,9 @@ u16 GetBgMetricTextMode(u8 bg, u8 whichMetric) u32 GetBgMetricAffineMode(u8 bg, u8 whichMetric) { u8 attribute; - + attribute = GetBgControlAttribute(bg, BG_CTRL_ATTR_SCREENSIZE); - + switch (whichMetric) { case 0: @@ -1491,7 +1482,7 @@ u32 GetTileMapIndexFromCoords(s32 x, s32 y, s32 screenSize, u32 screenWidth, u32 { x = x & (screenWidth - 1); y = y & (screenHeight - 1); - + switch (screenSize) { case 0: @@ -1526,7 +1517,7 @@ void CopyTileMapEntry(u16 *src, u16 *dest, s32 palette1, u32 tileOffset, u32 pal test = ((*dest & 0xFC00) + (palette2 << 12)) | ((*src + tileOffset) & 0x3FF); break; } - + *dest = test; } #else @@ -1586,10 +1577,10 @@ _08002B3C:\n\ u32 GetBgType(u8 bg) { u8 mode; - + mode = GetBgMode(); - - + + switch (bg) { case 0: @@ -1621,7 +1612,7 @@ u32 GetBgType(u8 bg) } break; } - + return 0xFFFF; } diff --git a/src/multiboot.c b/src/multiboot.c index 80291ff46..7fd6df2d0 100644 --- a/src/multiboot.c +++ b/src/multiboot.c @@ -316,7 +316,7 @@ void MultiBootStartProbe(struct MultiBootParam *mp) mp->probe_count = 1; } -void MultiBootStartMaster(struct MultiBootParam *mp, u8 *srcp, int length, u8 palette_color, s8 palette_speed) +void MultiBootStartMaster(struct MultiBootParam *mp, const u8 *srcp, int length, u8 palette_color, s8 palette_speed) { int i = 0; diff --git a/src/text.c b/src/text.c index cad8326e3..aa4e201c0 100644 --- a/src/text.c +++ b/src/text.c @@ -2779,7 +2779,7 @@ _08005D6E:\n\ bx r1"); } -u32 GetStringWidthFixedWidthFont(u8 *str, u8 fontId, u8 letterSpacing) +u32 GetStringWidthFixedWidthFont(const u8 *str, u8 fontId, u8 letterSpacing) { int i; u8 width; @@ -2788,7 +2788,7 @@ u32 GetStringWidthFixedWidthFont(u8 *str, u8 fontId, u8 letterSpacing) u8 line; int strPos; u8 lineWidths[8]; - u8 *strLocal; + const u8 *strLocal; for (i = 0; i < 8; i++) { @@ -2883,7 +2883,7 @@ u32 (*GetFontWidthFunc(u8 glyphId))(u16, bool32) return 0; } -s32 GetStringWidth(u8 fontId, u8 *str, s16 letterSpacing) +u32 GetStringWidth(u8 fontId, const u8 *str, s16 letterSpacing) { bool8 isJapanese; int minGlyphWidth; diff --git a/src/window.c b/src/window.c index 574b13aa0..164031bee 100644 --- a/src/window.c +++ b/src/window.c @@ -35,7 +35,7 @@ static void nullsub_8(void) } -bool16 InitWindows(struct WindowTemplate *templates) +bool16 InitWindows(const struct WindowTemplate *templates) { int i; void *bgTilemapBuffer; -- cgit v1.2.3 From c253bf5e75796c462fe5e389c7e8f6040f826c0f Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Mon, 18 Sep 2017 18:36:05 +0200 Subject: add important headers, const ptrs and egg hatch start --- src/bg.c | 204 ++++++++++++++---------------- src/dma3_manager.c | 30 ++--- src/egg_hatch.c | 364 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/safari_zone.c | 4 +- src/window.c | 2 +- 5 files changed, 474 insertions(+), 130 deletions(-) create mode 100644 src/egg_hatch.c (limited to 'src') diff --git a/src/bg.c b/src/bg.c index 8979eaecd..9f6d12062 100644 --- a/src/bg.c +++ b/src/bg.c @@ -1,19 +1,9 @@ #include "global.h" +#include "bg.h" #include "dma3.h" #define DISPCNT_ALL_BG_AND_MODE_BITS 0x0F07 -enum { - BG_CTRL_ATTR_VISIBLE = 1, - BG_CTRL_ATTR_CHARBASEINDEX = 2, - BG_CTRL_ATTR_MAPBASEINDEX = 3, - BG_CTRL_ATTR_SCREENSIZE = 4, - BG_CTRL_ATTR_PALETTEMODE = 5, - BG_CTRL_ATTR_PRIORITY = 6, - BG_CTRL_ATTR_MOSAIC = 7, - BG_CTRL_ATTR_WRAPAROUND = 8, -}; - struct BgControl { struct BgConfig { u16 visible:1; @@ -22,33 +12,23 @@ struct BgControl { u16 priority:2; u16 mosaic:1; u16 wraparound:1; - + u16 charBaseIndex:2; u16 mapBaseIndex:5; u16 paletteMode:1; - + u8 unknown_2; u8 unknown_3; } configs[4]; - - u16 bgVisibilityAndMode; -}; -struct BgTemplate { - u32 bg:2; - u32 charBaseIndex:2; - u32 mapBaseIndex:5; - u32 screenSize:2; - u32 paletteMode:1; - u32 priority:2; - u32 baseTile:10; + u16 bgVisibilityAndMode; }; struct BgConfig2 { u32 baseTile:10; u32 basePalette:4; u32 unk_3:18; - + void* tilemap; u32 bg_x; u32 bg_y; @@ -103,7 +83,7 @@ void ResetBgControlStructs(void) struct BgConfig* bgConfigs = &gGpuBgConfigs.configs[0]; struct BgConfig zeroedConfig = gZeroedBgControlStruct; int i; - + for (i = 0; i < 4; i++) { bgConfigs[i] = zeroedConfig; @@ -126,40 +106,40 @@ void SetBgControlAttributes(u8 bg, u8 charBaseIndex, u8 mapBaseIndex, u8 screenS { gGpuBgConfigs.configs[bg].charBaseIndex = charBaseIndex & 0x3; } - + if (mapBaseIndex != 0xFF) { gGpuBgConfigs.configs[bg].mapBaseIndex = mapBaseIndex & 0x1F; } - + if (screenSize != 0xFF) { gGpuBgConfigs.configs[bg].screenSize = screenSize & 0x3; } - + if (paletteMode != 0xFF) { gGpuBgConfigs.configs[bg].paletteMode = paletteMode; } - + if (priority != 0xFF) { gGpuBgConfigs.configs[bg].priority = priority & 0x3; } - + if (mosaic != 0xFF) { gGpuBgConfigs.configs[bg].mosaic = mosaic & 0x1; } - + if (wraparound != 0xFF) { gGpuBgConfigs.configs[bg].wraparound = wraparound; } - + gGpuBgConfigs.configs[bg].unknown_2 = 0; gGpuBgConfigs.configs[bg].unknown_3 = 0; - + gGpuBgConfigs.configs[bg].visible = 1; } } @@ -188,15 +168,15 @@ u16 GetBgControlAttribute(u8 bg, u8 attributeId) return gGpuBgConfigs.configs[bg].wraparound; } } - + return 0xFF; } -u8 LoadBgVram(u8 bg, void *src, u16 size, u16 destOffset, u8 mode) +u8 LoadBgVram(u8 bg, const void *src, u16 size, u16 destOffset, u8 mode) { u16 offset; s8 cursor; - + if (IsInvalidBg(bg) == FALSE && gGpuBgConfigs.configs[bg].visible != FALSE) { switch (mode) @@ -211,11 +191,11 @@ u8 LoadBgVram(u8 bg, void *src, u16 size, u16 destOffset, u8 mode) cursor = -1; goto end; } - + offset = destOffset + offset; - + cursor = RequestDma3Copy(src, (void*)(offset + BG_VRAM), size, 0); - + if (cursor == -1) { return -1; @@ -225,7 +205,7 @@ u8 LoadBgVram(u8 bg, void *src, u16 size, u16 destOffset, u8 mode) { return -1; } - + end: return cursor; } @@ -242,9 +222,9 @@ void ShowBgInternal(u8 bg) (gGpuBgConfigs.configs[bg].mapBaseIndex << 8) | (gGpuBgConfigs.configs[bg].wraparound << 13) | (gGpuBgConfigs.configs[bg].screenSize << 14); - + SetGpuReg((bg << 1) + 0x8, value); - + gGpuBgConfigs.bgVisibilityAndMode |= 1 << (bg + 8); gGpuBgConfigs.bgVisibilityAndMode &= DISPCNT_ALL_BG_AND_MODE_BITS; } @@ -273,7 +253,7 @@ void SetBgAffineInternal(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, { struct BgAffineSrcData src; struct BgAffineDstData dest; - + switch (gGpuBgConfigs.bgVisibilityAndMode & 0x7) { case 1: @@ -288,7 +268,7 @@ void SetBgAffineInternal(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, default: return; } - + src.texX = srcCenterX; src.texY = srcCenterY; src.scrX = dispCenterX; @@ -296,7 +276,7 @@ void SetBgAffineInternal(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, src.sx = scaleX; src.sy = scaleY; src.alpha = rotationAngle; - + BgAffineSet(&src, &dest, 1); SetGpuReg(REG_OFFSET_BG2PA, dest.pa); @@ -326,20 +306,20 @@ void ResetBgsAndClearDma3BusyFlags(u32 leftoverFireRedLeafGreenVariable) { int i; ResetBgs(); - + for (i = 0; i < 4; i++) { gDmaBusyBitfield[i] = 0; } - + gUnneededFireRedVariable = leftoverFireRedLeafGreenVariable; } -void InitBgsFromTemplates(u8 bgMode, struct BgTemplate *templates, u8 numTemplates) +void InitBgsFromTemplates(u8 bgMode, const struct BgTemplate *templates, u8 numTemplates) { int i; u8 bg; - + SetBgModeInternal(bgMode); ResetBgControlStructs(); @@ -355,11 +335,11 @@ void InitBgsFromTemplates(u8 bgMode, struct BgTemplate *templates, u8 numTemplat templates[i].priority, 0, 0); - + gGpuBgConfigs2[bg].baseTile = templates[i].baseTile; gGpuBgConfigs2[bg].basePalette = 0; gGpuBgConfigs2[bg].unk_3 = 0; - + gGpuBgConfigs2[bg].tilemap = NULL; gGpuBgConfigs2[bg].bg_x = 0; gGpuBgConfigs2[bg].bg_y = 0; @@ -370,7 +350,7 @@ void InitBgsFromTemplates(u8 bgMode, struct BgTemplate *templates, u8 numTemplat void InitBgFromTemplate(struct BgTemplate *template) { u8 bg = template->bg; - + if (bg < 4) { SetBgControlAttributes(bg, @@ -381,11 +361,11 @@ void InitBgFromTemplate(struct BgTemplate *template) template->priority, 0, 0); - + gGpuBgConfigs2[bg].baseTile = template->baseTile; gGpuBgConfigs2[bg].basePalette = 0; gGpuBgConfigs2[bg].unk_3 = 0; - + gGpuBgConfigs2[bg].tilemap = NULL; gGpuBgConfigs2[bg].bg_x = 0; gGpuBgConfigs2[bg].bg_y = 0; @@ -397,11 +377,11 @@ void SetBgMode(u8 bgMode) SetBgModeInternal(bgMode); } -u16 LoadBgTiles(u8 bg, void* src, u16 size, u16 destOffset) +u16 LoadBgTiles(u8 bg, const void* src, u16 size, u16 destOffset) { u16 tileOffset; u8 cursor; - + if (GetBgControlAttribute(bg, BG_CTRL_ATTR_PALETTEMODE) == 0) { tileOffset = (gGpuBgConfigs2[bg].baseTile + destOffset) * 0x20; @@ -410,37 +390,37 @@ u16 LoadBgTiles(u8 bg, void* src, u16 size, u16 destOffset) { tileOffset = (gGpuBgConfigs2[bg].baseTile + destOffset) * 0x40; } - + cursor = LoadBgVram(bg, src, size, tileOffset, DISPCNT_MODE_1); - + if (cursor == 0xFF) { return -1; } - + gDmaBusyBitfield[cursor / 0x20] |= (1 << (cursor % 0x20)); - + if (gUnneededFireRedVariable == 1) { DummiedOutFireRedLeafGreenTileAllocFunc(bg, tileOffset / 0x20, size / 0x20, 1); } - + return cursor; } u16 LoadBgTilemap(u8 bg, void *src, u16 size, u16 destOffset) { u8 cursor; - + cursor = LoadBgVram(bg, src, size, destOffset * 2, DISPCNT_MODE_2); - + if (cursor == 0xFF) { return -1; } - + gDmaBusyBitfield[cursor / 0x20] |= (1 << (cursor % 0x20)); - + return cursor; } @@ -448,12 +428,12 @@ u16 Unused_LoadBgPalette(u8 bg, void *src, u16 size, u16 destOffset) { u16 paletteOffset; s8 cursor; - + if (IsInvalidBg32(bg) == FALSE) { paletteOffset = (gGpuBgConfigs2[bg].basePalette * 0x20) + (destOffset * 2); cursor = RequestDma3Copy(src, (void*)(paletteOffset + BG_PLTT), size, 0); - + if (cursor == -1) { return -1; @@ -475,14 +455,14 @@ bool8 IsDma3ManagerBusyWithBgCopy(void) u8 mod; u8 div; s8 reqSpace; - + int i; - + for (i = 0; i < 0x80; i++) { div = i / 0x20; mod = i % 0x20; - + if ((gDmaBusyBitfield[div] & (1 << mod)) != FALSE) { reqSpace = CheckForSpaceForDma3Request(i); @@ -490,7 +470,7 @@ bool8 IsDma3ManagerBusyWithBgCopy(void) { return TRUE; } - + gDmaBusyBitfield[div] &= ~(1 << mod); } } @@ -634,12 +614,12 @@ u32 ChangeBgX(u8 bg, u32 value, u8 op) u8 mode; u16 temp1; u16 temp2; - + if (IsInvalidBg32(bg) != FALSE || GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) == 0) { return -1; } - + switch (op) { case 0: @@ -653,9 +633,9 @@ u32 ChangeBgX(u8 bg, u32 value, u8 op) gGpuBgConfigs2[bg].bg_x -= value; break; } - + mode = GetBgMode(); - + switch (bg) { case 0: @@ -695,7 +675,7 @@ u32 ChangeBgX(u8 bg, u32 value, u8 op) } break; } - + return gGpuBgConfigs2[bg].bg_x; } @@ -713,12 +693,12 @@ u32 ChangeBgY(u8 bg, u32 value, u8 op) u8 mode; u16 temp1; u16 temp2; - + if (IsInvalidBg32(bg) != FALSE || GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) == 0) { return -1; } - + switch (op) { case 0: @@ -732,9 +712,9 @@ u32 ChangeBgY(u8 bg, u32 value, u8 op) gGpuBgConfigs2[bg].bg_y -= value; break; } - + mode = GetBgMode(); - + switch (bg) { case 0: @@ -774,7 +754,7 @@ u32 ChangeBgY(u8 bg, u32 value, u8 op) } break; } - + return gGpuBgConfigs2[bg].bg_y; } @@ -783,12 +763,12 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) u8 mode; u16 temp1; u16 temp2; - + if (IsInvalidBg32(bg) != FALSE || GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) == 0) { return -1; } - + switch (op) { case 0: @@ -802,9 +782,9 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) gGpuBgConfigs2[bg].bg_y -= value; break; } - + mode = GetBgMode(); - + switch (bg) { case 0: @@ -820,7 +800,7 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) { temp1 = gGpuBgConfigs2[2].bg_y >> 0x8; SetGpuReg_ForcedBlank(REG_OFFSET_BG2VOFS, temp1); - + } else { @@ -845,7 +825,7 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) } break; } - + return gGpuBgConfigs2[bg].bg_y; } @@ -868,13 +848,13 @@ u8 Unused_AdjustBgMosaic(u8 a1, u8 a2) u16 result; s16 test1; s16 test2; - + result = GetGpuReg(REG_OFFSET_MOSAIC); - + test1 = result & 0xF; test2 = (result >> 4) & 0xF; result &= 0xFF00; - + switch (a2) { case 0: @@ -929,12 +909,12 @@ u8 Unused_AdjustBgMosaic(u8 a1, u8 a2) } break; } - + result |= ((test2 << 0x4) & 0xF0); result |= (test1 & 0xF); - + SetGpuReg(REG_OFFSET_MOSAIC, result); - + return result; } @@ -963,7 +943,7 @@ void* GetBgTilemapBuffer(u8 bg) return gGpuBgConfigs2[bg].tilemap; } -void CopyToBgTilemapBuffer(u8 bg, void *src, u16 mode, u16 destOffset) +void CopyToBgTilemapBuffer(u8 bg, const void *src, u16 mode, u16 destOffset) { if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { @@ -981,7 +961,7 @@ void CopyToBgTilemapBuffer(u8 bg, void *src, u16 mode, u16 destOffset) void CopyBgTilemapBufferToVram(u8 bg) { u16 sizeToLoad; - + if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { switch (GetBgType(bg)) @@ -1006,7 +986,7 @@ void CopyToBgTilemapBufferRect(u8 bg, void* src, u8 destX, u8 destY, u8 width, u u16 destX16; u16 destY16; u16 mode; - + if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { switch (GetBgType(bg)) @@ -1047,11 +1027,11 @@ void CopyRectToBgTilemapBufferRect(u8 bg, void* src, u8 srcX, u8 srcY, u8 srcWid u16 attribute; u16 mode; u16 mode2; - + void* srcCopy; u16 destX16; u16 destY16; - + if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { attribute = GetBgControlAttribute(bg, BG_CTRL_ATTR_SCREENSIZE); @@ -1336,7 +1316,7 @@ void FillBgTilemapBufferRect_Palette0(u8 bg, u16 tileNum, u8 x, u8 y, u8 width, u16 x16; u16 y16; u16 mode; - + if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { switch (GetBgType(bg)) @@ -1375,10 +1355,10 @@ void WriteSequenceToBgTilemapBuffer(u8 bg, u16 firstTileNum, u8 x, u8 y, u8 widt u16 mode2; u16 attribute; u16 mode3; - + u16 x16; u16 y16; - + if (IsInvalidBg32(bg) == FALSE && IsTileMapOutsideWram(bg) == FALSE) { attribute = GetBgControlAttribute(bg, BG_CTRL_ATTR_SCREENSIZE); @@ -1414,9 +1394,9 @@ void WriteSequenceToBgTilemapBuffer(u8 bg, u16 firstTileNum, u8 x, u8 y, u8 widt u16 GetBgMetricTextMode(u8 bg, u8 whichMetric) { u8 attribute; - + attribute = GetBgControlAttribute(bg, BG_CTRL_ATTR_SCREENSIZE); - + switch (whichMetric) { case 0: @@ -1462,9 +1442,9 @@ u16 GetBgMetricTextMode(u8 bg, u8 whichMetric) u32 GetBgMetricAffineMode(u8 bg, u8 whichMetric) { u8 attribute; - + attribute = GetBgControlAttribute(bg, BG_CTRL_ATTR_SCREENSIZE); - + switch (whichMetric) { case 0: @@ -1491,7 +1471,7 @@ u32 GetTileMapIndexFromCoords(s32 x, s32 y, s32 screenSize, u32 screenWidth, u32 { x = x & (screenWidth - 1); y = y & (screenHeight - 1); - + switch (screenSize) { case 0: @@ -1526,7 +1506,7 @@ void CopyTileMapEntry(u16 *src, u16 *dest, s32 palette1, u32 tileOffset, u32 pal test = ((*dest & 0xFC00) + (palette2 << 12)) | ((*src + tileOffset) & 0x3FF); break; } - + *dest = test; } #else @@ -1586,10 +1566,10 @@ _08002B3C:\n\ u32 GetBgType(u8 bg) { u8 mode; - + mode = GetBgMode(); - - + + switch (bg) { case 0: @@ -1621,7 +1601,7 @@ u32 GetBgType(u8 bg) } break; } - + return 0xFFFF; } diff --git a/src/dma3_manager.c b/src/dma3_manager.c index 6d12dec05..0d3cf264b 100644 --- a/src/dma3_manager.c +++ b/src/dma3_manager.c @@ -14,7 +14,7 @@ void ClearDma3Requests(void) gDma3Requests[i].src = 0; gDma3Requests[i].dest = 0; } - + gDma3ManagerLocked = FALSE; } @@ -24,7 +24,7 @@ void ProcessDma3Requests(void) // NOTE: the fillerA member of the DMA struct is actually u32 value; // NOTE: gUnknown_0300001C is just a pointer inside the gDma3Requests structure, not a true symbol; feel free to remove u16 total_size; - + if (gDma3ManagerLocked) return; @@ -34,7 +34,7 @@ void ProcessDma3Requests(void) while (gDma3Requests[gDma3RequestCursor].size) { total_size += gDma3Requests[gDma3RequestCursor].size; - + if (total_size > 0xA000) return; // don't do too much at once @@ -90,14 +90,14 @@ void ProcessDma3Requests(void) } DmaFill16(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size); break; - } + } gDma3Requests[gDma3RequestCursor].src = 0; gDma3Requests[gDma3RequestCursor].dest = 0; gDma3Requests[gDma3RequestCursor].size = 0; gDma3Requests[gDma3RequestCursor].mode = 0; gDma3Requests[gDma3RequestCursor].value = 0; gDma3RequestCursor++; - + if (gDma3RequestCursor >= 128) // loop back to the first DMA request gDma3RequestCursor = 0; } @@ -419,13 +419,13 @@ _08000E46:\n\ } #endif -int RequestDma3Copy(void *src, void *dest, u16 size, u8 mode) +int RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode) { int cursor; int var = 0; - + gDma3ManagerLocked = 1; - + cursor = gDma3RequestCursor; while(1) { @@ -434,12 +434,12 @@ int RequestDma3Copy(void *src, void *dest, u16 size, u8 mode) gDma3Requests[cursor].src = src; gDma3Requests[cursor].dest = dest; gDma3Requests[cursor].size = size; - + if(mode == 1) gDma3Requests[cursor].mode = mode; else gDma3Requests[cursor].mode = 3; - + gDma3ManagerLocked = FALSE; return (s16)cursor; } @@ -460,10 +460,10 @@ int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode) { int cursor; int var = 0; - + cursor = gDma3RequestCursor; gDma3ManagerLocked = 1; - + while(1) { if(!gDma3Requests[cursor].size) @@ -477,7 +477,7 @@ int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode) gDma3Requests[cursor].mode = 2; else gDma3Requests[cursor].mode = 4; - + gDma3ManagerLocked = FALSE; return (s16)cursor; } @@ -503,9 +503,9 @@ int CheckForSpaceForDma3Request(s16 index) for (; current < 0x80; current ++) if (gDma3Requests[current].size) return -1; - + return 0; - } + } if (gDma3Requests[index].size) return -1; diff --git a/src/egg_hatch.c b/src/egg_hatch.c new file mode 100644 index 000000000..0b924fced --- /dev/null +++ b/src/egg_hatch.c @@ -0,0 +1,364 @@ +#include "global.h" +#include "pokemon.h" +#include "pokedex.h" +#include "items.h" +#include "script.h" +#include "decompress.h" +#include "task.h" +#include "palette.h" +#include "main.h" +#include "event_data.h" +#include "sound.h" +#include "songs.h" +#include "text.h" +#include "text_window.h" +#include "string_util.h" +#include "menu.h" +#include "trig.h" +#include "rng.h" +#include "malloc.h" +#include "dma3.h" +#include "gpu_regs.h" +#include "bg.h" +#include "m4a.h" +#include "window.h" +#include "battle.h" // to get rid of later + +struct EggHatchData +{ + u8 eggSpriteID; + u8 pokeSpriteID; + u8 CB2_state; + u8 CB2_PalCounter; + u8 eggPartyID; + u8 field_5; + u8 field_6; + u8 eggShardVelocityID; + u8 field_8; + u8 field_9; + u8 field_A; + u8 field_B; + u16 species; + u8 field_E; + u8 field_F; + u8 field_10; + u8 field_11; + u8 field_12; + u8 field_13; +}; + +extern struct EggHatchData* gEggHatchData; + +extern struct SpriteTemplate gUnknown_0202499C; +extern void (*gFieldCallback)(void); + +extern const struct CompressedSpriteSheet gMonFrontPicTable[]; +extern const struct BgTemplate gUnknown_0832C064[2]; +extern const struct WindowTemplate gUnknown_0832C06C[2]; +extern const u8 gUnknown_08C00000[]; +extern const u8 gUnknown_08C00524[]; +extern const u8 gUnknown_08C004E0[]; +extern const struct SpriteSheet gUnknown_0832BFE4; // hatching egg +extern const struct SpriteSheet gUnknown_0832BFEC; // egg shell +extern const struct SpritePalette gUnknown_0832BFF4; // hatching egg +extern const u16 gUnknown_08DD7300[]; // palette, gameboy advance +extern const u32 gUnknown_08DD7360[]; // tileset gameboy advance +extern const u32 gUnknown_08331F60[]; // tilemap gameboy circle + +extern u8* GetMonNick(struct Pokemon* mon, u8* dst); +extern u8* GetBoxMonNick(struct BoxPokemon* boxMon, u8* dst); +extern u8 sav1_map_get_name(void); +extern void sub_81DB5E8(u8* str1, u8* str2, u8); +extern void sub_806A068(u16, u8); +extern void fade_screen(u8, u8); +extern void overworld_free_bg_tilemaps(void); +extern void sub_80AF168(void); +extern void init_uns_table_pokemon_copy(void); +extern void remove_some_task(void); +extern void reset_temp_tile_data_buffers(void); +extern void copy_decompressed_tile_data_to_vram_autofree(u8 bg_id, const void* src, u16 size, u16 offset, u8 mode); + + void Task_EggHatch(u8 taskID); + void CB2_EggHatch_0(void); + void CB2_EggHatch_1(void); + void SpriteCB_Egg_0(struct Sprite* sprite); + void SpriteCB_Egg_1(struct Sprite* sprite); + void SpriteCB_Egg_2(struct Sprite* sprite); + void SpriteCB_Egg_3(struct Sprite* sprite); + void SpriteCB_Egg_4(struct Sprite* sprite); + void SpriteCB_Egg_5(struct Sprite* sprite); + void SpriteCB_EggShard(struct Sprite* sprite); + void EggHatchPrintMessage2(u8* src); + void EggHatchPrintMessage1(u8* src); + bool8 EggHatchUpdateWindowText(void); + void CreateRandomEggShardSprite(void); + void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex); + +static void CreatedHatchedMon(struct Pokemon *egg, struct Pokemon *temp) +{ + u16 species; + u32 personality, pokerus; + u8 i, friendship, language, gameMet, markings, obedience; + u16 moves[4]; + u32 ivs[6]; + + + species = GetMonData(egg, MON_DATA_SPECIES); + + for (i = 0; i < 4; i++) + { + moves[i] = GetMonData(egg, MON_DATA_MOVE1 + i); + } + + personality = GetMonData(egg, MON_DATA_PERSONALITY); + + for (i = 0; i < 6; i++) + { + ivs[i] = GetMonData(egg, MON_DATA_HP_IV + i); + } + + language = GetMonData(egg, MON_DATA_LANGUAGE); + gameMet = GetMonData(egg, MON_DATA_MET_GAME); + markings = GetMonData(egg, MON_DATA_MARKINGS); + pokerus = GetMonData(egg, MON_DATA_POKERUS); + obedience = GetMonData(egg, MON_DATA_OBEDIENCE); + + CreateMon(temp, species, 5, 32, TRUE, personality, 0, 0); + + for (i = 0; i < 4; i++) + { + SetMonData(temp, MON_DATA_MOVE1 + i, &moves[i]); + } + + for (i = 0; i < 6; i++) + { + SetMonData(temp, MON_DATA_HP_IV + i, &ivs[i]); + } + + language = GAME_LANGUAGE; + SetMonData(temp, MON_DATA_LANGUAGE, &language); + SetMonData(temp, MON_DATA_MET_GAME, &gameMet); + SetMonData(temp, MON_DATA_MARKINGS, &markings); + + friendship = 120; + SetMonData(temp, MON_DATA_FRIENDSHIP, &friendship); + SetMonData(temp, MON_DATA_POKERUS, &pokerus); + SetMonData(temp, MON_DATA_OBEDIENCE, &obedience); + + *egg = *temp; +} + +void AddHatchedMonToParty(u8 id) +{ + u8 isEgg = 0x46; // ? + u16 pokeNum; + u8 name[12]; + u16 ball; + u16 caughtLvl; + u8 mapNameID; + struct Pokemon* mon = &gPlayerParty[id]; + + CreatedHatchedMon(mon, &gEnemyParty[0]); + SetMonData(mon, MON_DATA_IS_EGG, &isEgg); + + pokeNum = GetMonData(mon, MON_DATA_SPECIES); + GetSpeciesName(name, pokeNum); + SetMonData(mon, MON_DATA_NICKNAME, name); + + pokeNum = SpeciesToNationalPokedexNum(pokeNum); + GetSetPokedexFlag(pokeNum, FLAG_SET_SEEN); + GetSetPokedexFlag(pokeNum, FLAG_SET_CAUGHT); + + GetMonNick(mon, gStringVar1); + + ball = ITEM_POKE_BALL; + SetMonData(mon, MON_DATA_POKEBALL, &ball); + + caughtLvl = 0; + SetMonData(mon, MON_DATA_MET_LEVEL, &caughtLvl); + + mapNameID = sav1_map_get_name(); + SetMonData(mon, MON_DATA_MET_LOCATION, &mapNameID); + + MonRestorePP(mon); + CalculateMonStats(mon); +} + +void ScriptHatchMon(void) +{ + AddHatchedMonToParty(gSpecialVar_0x8004); +} + +static bool8 sub_807158C(struct DaycareData* daycare, u8 daycareId) +{ + u8 nick[0x20]; + struct DaycareMon* daycareMon = &daycare->mons[daycareId]; + + GetBoxMonNick(&daycareMon->mon, nick); + if (daycareMon->mail.itemId != 0 + && (StringCompareWithoutExtCtrlCodes(nick, daycareMon->monName) != 0 + || StringCompareWithoutExtCtrlCodes(gSaveBlock2Ptr->playerName, daycareMon->OT_name) != 0)) + { + StringCopy(gStringVar1, nick); + sub_81DB5E8(gStringVar2, daycareMon->OT_name, daycareMon->language_maybe); + sub_81DB5E8(gStringVar3, daycareMon->monName, daycareMon->unknown); + return TRUE; + } + return FALSE; +} + +bool8 sub_8071614(void) +{ + return sub_807158C(&gSaveBlock1Ptr->daycare, gSpecialVar_0x8004); +} + +u8 EggHatchCreateMonSprite(u8 a0, u8 switchID, u8 pokeID, u16* speciesLoc) +{ + u8 r5 = 0; + u8 spriteID = 0; + struct Pokemon* mon = NULL; + + if (a0 == 0) + { + mon = &gPlayerParty[pokeID]; + r5 = 1; + } + if (a0 == 1) + { + mon = &gPlayerParty[pokeID]; + r5 = 3; + } + switch (switchID) + { + case 0: + { + u16 species = GetMonData(mon, MON_DATA_SPECIES); + u32 pid = GetMonData(mon, MON_DATA_PERSONALITY); + HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species], + gBattleSpritesGfx->sprites[(a0 * 2) + 1], + species, pid); + LoadCompressedObjectPalette(sub_806E794(mon)); + *speciesLoc = species; + } + break; + case 1: + sub_806A068(sub_806E794(mon)->tag, r5); + spriteID = CreateSprite(&gUnknown_0202499C, 120, 75, 6); + gSprites[spriteID].invisible = 1; + gSprites[spriteID].callback = SpriteCallbackDummy; + break; + } + return spriteID; +} + +void VBlankCB_EggHatch(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +void EggHatch(void) +{ + ScriptContext2_Enable(); + CreateTask(Task_EggHatch, 10); + fade_screen(1, 0); +} + + void Task_EggHatch(u8 taskID) +{ + if (!gPaletteFade.active) + { + overworld_free_bg_tilemaps(); + SetMainCallback2(CB2_EggHatch_0); + gFieldCallback = sub_80AF168; + DestroyTask(taskID); + } +} + + void CB2_EggHatch_0(void) +{ + switch (gMain.state) + { + case 0: + SetGpuReg(REG_OFFSET_DISPCNT, 0); + + gEggHatchData = Alloc(sizeof(struct EggHatchData)); + init_uns_table_pokemon_copy(); + gEggHatchData->eggPartyID = gSpecialVar_0x8004; + gEggHatchData->eggShardVelocityID = 0; + + SetVBlankCallback(VBlankCB_EggHatch); + gSpecialVar_0x8005 = GetCurrentMapMusic(); + + reset_temp_tile_data_buffers(); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, gUnknown_0832C064, 2); + + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + ChangeBgX(0, 0, 0); + ChangeBgY(0, 0, 0); + + SetBgAttribute(1, BG_CTRL_ATTR_MOSAIC, 2); + SetBgTilemapBuffer(1, Alloc(0x1000)); + SetBgTilemapBuffer(0, Alloc(0x2000)); + + DeactivateAllTextPrinters(); + ResetPaletteFade(); + FreeAllSpritePalettes(); + ResetSpriteData(); + ResetTasks(); + remove_some_task(); + m4aSoundVSyncOn(); + gMain.state++; + break; + case 1: + InitWindows(gUnknown_0832C06C); + gEggHatchData->field_8 = 0; + gMain.state++; + break; + case 2: + copy_decompressed_tile_data_to_vram_autofree(0, gUnknown_08C00000, 0, 0, 0); + CopyToBgTilemapBuffer(0, gUnknown_08C00524, 0, 0); + LoadCompressedPalette(gUnknown_08C004E0, 0, 0x20); + gMain.state++; + break; + case 3: + LoadSpriteSheet(&gUnknown_0832BFE4); + LoadSpriteSheet(&gUnknown_0832BFEC); + LoadSpritePalette(&gUnknown_0832BFF4); + gMain.state++; + break; + case 4: + CopyBgTilemapBufferToVram(0); + AddHatchedMonToParty(gEggHatchData->eggPartyID); + gMain.state++; + break; + case 5: + EggHatchCreateMonSprite(0, 0, gEggHatchData->eggPartyID, &gEggHatchData->species); + gMain.state++; + break; + case 6: + gEggHatchData->pokeSpriteID = EggHatchCreateMonSprite(0, 1, gEggHatchData->eggPartyID, &gEggHatchData->species); + gMain.state++; + break; + case 7: + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + LoadPalette(gUnknown_08DD7300, 0x10, 0xA0); + LoadBgTiles(1, gUnknown_08DD7360, 0x1420, 0); + CopyToBgTilemapBuffer(1, gUnknown_08331F60, 0x1000, 0); + CopyBgTilemapBufferToVram(1); + gMain.state++; + break; + case 8: + SetMainCallback2(CB2_EggHatch_1); + gEggHatchData->CB2_state = 0; + break; + } + RunTasks(); + RunTextPrinters(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} diff --git a/src/safari_zone.c b/src/safari_zone.c index fdfdd961a..3e25468bf 100644 --- a/src/safari_zone.c +++ b/src/safari_zone.c @@ -18,7 +18,7 @@ struct PokeblockFeeder #define NUM_POKEBLOCK_FEEDERS 10 extern u8 gBattleOutcome; -extern void* gUnknown_03005DAC; +extern void* gFieldCallback; extern u8 gUnknown_082A4B8A[]; extern u8 gUnknown_082A4B6F[]; @@ -118,7 +118,7 @@ void sub_80FC190(void) { ScriptContext2_RunNewScript(gUnknown_082A4B4C); warp_in(); - gUnknown_03005DAC = sub_80AF6F0; + gFieldCallback = sub_80AF6F0; SetMainCallback2(c2_load_new_map); } else if (gBattleOutcome == BATTLE_CAUGHT) diff --git a/src/window.c b/src/window.c index 574b13aa0..164031bee 100644 --- a/src/window.c +++ b/src/window.c @@ -35,7 +35,7 @@ static void nullsub_8(void) } -bool16 InitWindows(struct WindowTemplate *templates) +bool16 InitWindows(const struct WindowTemplate *templates) { int i; void *bgTilemapBuffer; -- cgit v1.2.3 From 097a38f054c8a858917049fdf8973cb16a26c771 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 18 Sep 2017 13:54:39 -0400 Subject: nonmatching sub_81BF7A4 --- src/berry_fix_program.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c index 58e50e509..b63bc12be 100644 --- a/src/berry_fix_program.c +++ b/src/berry_fix_program.c @@ -30,7 +30,9 @@ extern berryfix_t *gUnknown_030012B8; static void sub_81BF3DC(void); static void sub_81BF5A4(void); -u32 sub_81BF7A4(u8); +static int sub_81BF7A4(int); +void sub_81BF7E8(int); +void sub_81BF8D8(int); // .rodata @@ -179,6 +181,32 @@ static void sub_81BF5A4(void) CopyWindowToVram(3, 2); CopyWindowToVram(0, 2); } + +static int sub_81BF7A4(int checkval) +{ + int retval; + + retval = gUnknown_030012B8->unk1; + if (retval == checkval) + { + retval = checkval; + } + else + { + if (retval == 6) + { + sub_81BF7E8(checkval); + gUnknown_030012B8->unk1 = checkval; + } + else + { + sub_81BF8D8(gUnknown_030012B8->unk1); + gUnknown_030012B8->unk1 = 6; + } + retval = gUnknown_030012B8->unk1; + } + return retval; +} #else __attribute__((naked)) static void sub_81BF5A4(void) { @@ -386,4 +414,43 @@ __attribute__((naked)) static void sub_81BF5A4(void) "\t.pool\n" ".syntax divided"); } + +__attribute__((naked)) static int sub_81BF7A4(int checkval) +{ + asm(".syntax unified\n" + "\tpush {r4,r5,lr}\n" + "\tadds r4, r0, 0\n" + "\tldr r5, =gUnknown_030012B8\n" + "\tldr r0, [r5]\n" + "\tldrb r0, [r0, 0x1]\n" + "\tcmp r0, r4\n" + "\tbne _081BF7BC\n" + "\tadds r0, r4, 0\n" + "\tb _081BF7DC\n" + "\t.pool\n" + "_081BF7BC:\n" + "\tcmp r0, 0x6\n" + "\tbne _081BF7CC\n" + "\tadds r0, r4, 0\n" + "\tbl sub_81BF7E8\n" + "\tldr r0, [r5]\n" + "\tstrb r4, [r0, 0x1]\n" + "\tb _081BF7D6\n" + "_081BF7CC:\n" + "\tbl sub_81BF8D8\n" + "\tldr r1, [r5]\n" + "\tmovs r0, 0x6\n" + "\tstrb r0, [r1, 0x1]\n" + "_081BF7D6:\n" + "\tldr r0, =gUnknown_030012B8\n" + "\tldr r0, [r0]\n" + "\tldrb r0, [r0, 0x1]\n" + "_081BF7DC:\n" + "\tpop {r4,r5}\n" + "\tpop {r1}\n" + "\tbx r1\n" + "\t.pool\n" + ".syntax divided"); +} #endif + -- cgit v1.2.3 From 39e6bdf094ac1b53109782c9b5b98c211bbe3149 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 18 Sep 2017 14:04:00 -0400 Subject: sub_81BF7E8 --- src/berry_fix_program.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c index b63bc12be..6f4c1c79e 100644 --- a/src/berry_fix_program.c +++ b/src/berry_fix_program.c @@ -31,7 +31,7 @@ extern berryfix_t *gUnknown_030012B8; static void sub_81BF3DC(void); static void sub_81BF5A4(void); static int sub_81BF7A4(int); -void sub_81BF7E8(int); +static void sub_81BF7E8(int); void sub_81BF8D8(int); // .rodata @@ -48,6 +48,8 @@ extern const struct WindowTemplate gUnknown_08618110[7]; extern const u16 gUnknown_08618138[16]; extern const u8 gUnknown_08618158[3]; extern const u8 gUnknown_0861815B[3]; +extern const u8 *const gUnknown_08618160[6]; +extern const u8 *const gUnknown_08618178[6][3]; // .text @@ -454,3 +456,32 @@ __attribute__((naked)) static int sub_81BF7A4(int checkval) } #endif +static void sub_81BF7E8(int scene) +{ + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32); + FillWindowPixelBuffer(1, 0xAA); + box_print(1, 1, 0, 0, gUnknown_08618158, -1, gUnknown_08618160[scene]); + PutWindowTilemap(1); + CopyWindowToVram(1, 2); + switch (scene) + { + case 0: + case 2: + case 3: + case 4: + PutWindowTilemap(2); + break; + case 1: + PutWindowTilemap(3); + break; + case 5: + PutWindowTilemap(0); + break; + } + CopyBgTilemapBufferToVram(0); + LZ77UnCompVram(gUnknown_08618178[scene][0], (void *)BG_CHAR_ADDR(1)); + LZ77UnCompVram(gUnknown_08618178[scene][1], (void *)BG_SCREEN_ADDR(31)); + CpuCopy32(gUnknown_08618178[scene][2], (void *)BG_PLTT, 0x100); + ShowBg(0); + ShowBg(1); +} -- cgit v1.2.3 From 0e2d84f24d22b6ec47e6adf32bc5f4d6b4c6289b Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 18 Sep 2017 14:07:34 -0400 Subject: Remaining functions --- src/berry_fix_program.c | 86 ++++++++++++++----------------------------------- 1 file changed, 24 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c index 6f4c1c79e..e4ec0d8c4 100644 --- a/src/berry_fix_program.c +++ b/src/berry_fix_program.c @@ -32,7 +32,7 @@ static void sub_81BF3DC(void); static void sub_81BF5A4(void); static int sub_81BF7A4(int); static void sub_81BF7E8(int); -void sub_81BF8D8(int); +static void sub_81BF8D8(void); // .rodata @@ -184,31 +184,6 @@ static void sub_81BF5A4(void) CopyWindowToVram(0, 2); } -static int sub_81BF7A4(int checkval) -{ - int retval; - - retval = gUnknown_030012B8->unk1; - if (retval == checkval) - { - retval = checkval; - } - else - { - if (retval == 6) - { - sub_81BF7E8(checkval); - gUnknown_030012B8->unk1 = checkval; - } - else - { - sub_81BF8D8(gUnknown_030012B8->unk1); - gUnknown_030012B8->unk1 = 6; - } - retval = gUnknown_030012B8->unk1; - } - return retval; -} #else __attribute__((naked)) static void sub_81BF5A4(void) { @@ -416,45 +391,26 @@ __attribute__((naked)) static void sub_81BF5A4(void) "\t.pool\n" ".syntax divided"); } +#endif -__attribute__((naked)) static int sub_81BF7A4(int checkval) +static int sub_81BF7A4(int checkval) { - asm(".syntax unified\n" - "\tpush {r4,r5,lr}\n" - "\tadds r4, r0, 0\n" - "\tldr r5, =gUnknown_030012B8\n" - "\tldr r0, [r5]\n" - "\tldrb r0, [r0, 0x1]\n" - "\tcmp r0, r4\n" - "\tbne _081BF7BC\n" - "\tadds r0, r4, 0\n" - "\tb _081BF7DC\n" - "\t.pool\n" - "_081BF7BC:\n" - "\tcmp r0, 0x6\n" - "\tbne _081BF7CC\n" - "\tadds r0, r4, 0\n" - "\tbl sub_81BF7E8\n" - "\tldr r0, [r5]\n" - "\tstrb r4, [r0, 0x1]\n" - "\tb _081BF7D6\n" - "_081BF7CC:\n" - "\tbl sub_81BF8D8\n" - "\tldr r1, [r5]\n" - "\tmovs r0, 0x6\n" - "\tstrb r0, [r1, 0x1]\n" - "_081BF7D6:\n" - "\tldr r0, =gUnknown_030012B8\n" - "\tldr r0, [r0]\n" - "\tldrb r0, [r0, 0x1]\n" - "_081BF7DC:\n" - "\tpop {r4,r5}\n" - "\tpop {r1}\n" - "\tbx r1\n" - "\t.pool\n" - ".syntax divided"); + if (gUnknown_030012B8->unk1 == checkval) + { + return checkval; + } + if (gUnknown_030012B8->unk1 == 6) + { + sub_81BF7E8(checkval); + gUnknown_030012B8->unk1 = checkval; + } + else + { + sub_81BF8D8(); + gUnknown_030012B8->unk1 = 6; + } + return gUnknown_030012B8->unk1; } -#endif static void sub_81BF7E8(int scene) { @@ -485,3 +441,9 @@ static void sub_81BF7E8(int scene) ShowBg(0); ShowBg(1); } + +static void sub_81BF8D8() +{ + HideBg(0); + HideBg(1); +} -- cgit v1.2.3 From 810bfffd1242ebfd29fcc2db6fef19b34545ad0b Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 18 Sep 2017 15:10:25 -0400 Subject: data decomp --- src/berry_fix_program.c | 103 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c index e4ec0d8c4..fa13c7e1e 100644 --- a/src/berry_fix_program.c +++ b/src/berry_fix_program.c @@ -36,20 +36,103 @@ static void sub_81BF8D8(void); // .rodata +const u8 gUnknown_08617E78[] = _("Berry Program Update"); +const u8 gUnknown_08617E8D[] = _("Ruby/Sapphire"); +const u8 gUnknown_08617E9B[] = _("Emerald"); + +const u8 Unknown_08617EA3[] = _("The Berry Program on your POKéMON\nRuby/Sapphire Game Pak will be updated.\n{COLOR RED}{SHADOW LIGHT_RED}Press the A Button."); +const u8 Unknown_08617F07[] = _("Please ensure the connection of your\nGame Boy Advance system matches this.\n{COLOR RED}{SHADOW LIGHT_RED}YES: Press the A Button.\nNO: Turn off the power and try again."); +const u8 Unknown_08617F97[] = _("Please turn on the power of POKéMON\nRuby/Sapphire while holding START and\nSELECT simultaneously. Then, ensure\nthe picture above appears."); +const u8 Unknown_08618020[] = _("Transmitting. Please wait.\n{COLOR RED}{SHADOW LIGHT_RED}Please do not turn off the power or\nunplug the Game Boy Advance Game\nLink Cable."); +const u8 Unknown_08618092[] = _("Please follow the instructions on your\nPOKéMON Ruby/Sapphire screen."); +const u8 Unknown_086180D7[] = _("Transmission failure.\n{COLOR RED}{SHADOW LIGHT_RED}Please try again."); + +const struct BgTemplate gUnknown_08618108[] = { + { + 0, 0, 30, 0, 0, 0 + }, { + 1, 1, 31, 0, 0, 1 + } +}; + +const struct WindowTemplate gUnknown_08618110[] = { + {0, 2, 4, 26, 2, 15, 0x001}, + {0, 1, 11, 28, 8, 15, 0x035}, + {0, 0, 8, 30, 2, 15, 0x115}, + {0, 8, 0, 14, 2, 15, 0x151}, + {-1} +}; + +const u16 gUnknown_08618138[] = { + 0x7fff, 0x7fff, 0x318c, 0x675a, + 0x043c, 0x3aff, 0x0664, 0x4bd2, + 0x6546, 0x7b14, 0x7fff, 0x318c, + 0x675a, 0x0000, 0x0000, 0x0000 +}; + +const u8 gUnknown_08618158[] = {10, 11, 12}; +const u8 gUnknown_0861815B[] = { 0, 10, 13}; + +const u8 *const gUnknown_08618160[] = { + Unknown_08617F07, + Unknown_08617F97, + Unknown_08618020, + Unknown_08618092, + Unknown_086180D7, + Unknown_08617EA3 +}; + +extern const u8 gUnknown_08DD87C0[]; +extern const u8 gUnknown_08DD8EE0[]; +extern const u8 gUnknown_08DD8780[]; +extern const u8 gUnknown_08DD90E0[]; +extern const u8 gUnknown_08DD9718[]; +extern const u8 gUnknown_08DD9080[]; +extern const u8 gUnknown_08DD98B4[]; +extern const u8 gUnknown_08DD9E58[]; +extern const u8 gUnknown_08DD9874[]; +extern const u8 gUnknown_08DDA02C[]; +extern const u8 gUnknown_08DDA63C[]; +extern const u8 gUnknown_08DD9FEC[]; +extern const u8 gUnknown_08DDA840[]; +extern const u8 gUnknown_08DDAE40[]; +extern const u8 gUnknown_08DDA800[]; +extern const u8 gUnknown_08DDB020[]; +extern const u8 gUnknown_08DDB2C4[]; +extern const u8 gUnknown_08DDAFE0[]; + +const u8 *const gUnknown_08618178[][3] = { + { + gUnknown_08DD87C0, + gUnknown_08DD8EE0, + gUnknown_08DD8780 + }, { + gUnknown_08DD90E0, + gUnknown_08DD9718, + gUnknown_08DD9080 + }, { + gUnknown_08DD98B4, + gUnknown_08DD9E58, + gUnknown_08DD9874 + }, { + gUnknown_08DDA02C, + gUnknown_08DDA63C, + gUnknown_08DD9FEC + }, { + gUnknown_08DDA840, + gUnknown_08DDAE40, + gUnknown_08DDA800 + }, { + gUnknown_08DDB020, + gUnknown_08DDB2C4, + gUnknown_08DDAFE0 + }, +}; + extern const u8 gUnknown_089A6550[0xC0]; extern const u8 gMultiBootProgram_BerryGlitchFix_Script[0x3b34]; extern const u8 gMultiBootProgram_BerryGlitchFix_Start[]; extern const u8 gMultiBootProgram_BerryGlitchFix_End[]; -extern const u8 gUnknown_08617E78[]; -extern const u8 gUnknown_08617E8D[]; -extern const u8 gUnknown_08617E9B[]; -extern const struct BgTemplate gUnknown_08618108[2]; -extern const struct WindowTemplate gUnknown_08618110[7]; -extern const u16 gUnknown_08618138[16]; -extern const u8 gUnknown_08618158[3]; -extern const u8 gUnknown_0861815B[3]; -extern const u8 *const gUnknown_08618160[6]; -extern const u8 *const gUnknown_08618178[6][3]; // .text -- cgit v1.2.3 From d48c4ab7a95c0b3cc59e96ca2bf30fdbc7ff1581 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 18 Sep 2017 15:28:55 -0400 Subject: Slight cleanup and relabeling of functions --- src/berry_fix_program.c | 136 ++++++++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c index fa13c7e1e..931e92746 100644 --- a/src/berry_fix_program.c +++ b/src/berry_fix_program.c @@ -24,30 +24,30 @@ typedef struct { // Static RAM declarations -extern berryfix_t *gUnknown_030012B8; +static berryfix_t *berry_fix_mb_manager; // Static ROM declarations -static void sub_81BF3DC(void); -static void sub_81BF5A4(void); -static int sub_81BF7A4(int); -static void sub_81BF7E8(int); -static void sub_81BF8D8(void); +static void berry_fix_main(void); +static void berry_fix_gpu_set(void); +static int berry_fix_text_update(int); +static void berry_fix_text_print(int); +static void berry_fix_bg_hide(void); // .rodata -const u8 gUnknown_08617E78[] = _("Berry Program Update"); -const u8 gUnknown_08617E8D[] = _("Ruby/Sapphire"); -const u8 gUnknown_08617E9B[] = _("Emerald"); +static const u8 gUnknown_08617E78[] = _("Berry Program Update"); +static const u8 gUnknown_08617E8D[] = _("Ruby/Sapphire"); +static const u8 gUnknown_08617E9B[] = _("Emerald"); -const u8 Unknown_08617EA3[] = _("The Berry Program on your POKéMON\nRuby/Sapphire Game Pak will be updated.\n{COLOR RED}{SHADOW LIGHT_RED}Press the A Button."); -const u8 Unknown_08617F07[] = _("Please ensure the connection of your\nGame Boy Advance system matches this.\n{COLOR RED}{SHADOW LIGHT_RED}YES: Press the A Button.\nNO: Turn off the power and try again."); -const u8 Unknown_08617F97[] = _("Please turn on the power of POKéMON\nRuby/Sapphire while holding START and\nSELECT simultaneously. Then, ensure\nthe picture above appears."); -const u8 Unknown_08618020[] = _("Transmitting. Please wait.\n{COLOR RED}{SHADOW LIGHT_RED}Please do not turn off the power or\nunplug the Game Boy Advance Game\nLink Cable."); -const u8 Unknown_08618092[] = _("Please follow the instructions on your\nPOKéMON Ruby/Sapphire screen."); -const u8 Unknown_086180D7[] = _("Transmission failure.\n{COLOR RED}{SHADOW LIGHT_RED}Please try again."); +static const u8 Unknown_08617EA3[] = _("The Berry Program on your POKéMON\nRuby/Sapphire Game Pak will be updated.\n{COLOR RED}{SHADOW LIGHT_RED}Press the A Button."); +static const u8 Unknown_08617F07[] = _("Please ensure the connection of your\nGame Boy Advance system matches this.\n{COLOR RED}{SHADOW LIGHT_RED}YES: Press the A Button.\nNO: Turn off the power and try again."); +static const u8 Unknown_08617F97[] = _("Please turn on the power of POKéMON\nRuby/Sapphire while holding START and\nSELECT simultaneously. Then, ensure\nthe picture above appears."); +static const u8 Unknown_08618020[] = _("Transmitting. Please wait.\n{COLOR RED}{SHADOW LIGHT_RED}Please do not turn off the power or\nunplug the Game Boy Advance Game\nLink Cable."); +static const u8 Unknown_08618092[] = _("Please follow the instructions on your\nPOKéMON Ruby/Sapphire screen."); +static const u8 Unknown_086180D7[] = _("Transmission failure.\n{COLOR RED}{SHADOW LIGHT_RED}Please try again."); -const struct BgTemplate gUnknown_08618108[] = { +static const struct BgTemplate gUnknown_08618108[] = { { 0, 0, 30, 0, 0, 0 }, { @@ -55,7 +55,7 @@ const struct BgTemplate gUnknown_08618108[] = { } }; -const struct WindowTemplate gUnknown_08618110[] = { +static const struct WindowTemplate gUnknown_08618110[] = { {0, 2, 4, 26, 2, 15, 0x001}, {0, 1, 11, 28, 8, 15, 0x035}, {0, 0, 8, 30, 2, 15, 0x115}, @@ -63,17 +63,17 @@ const struct WindowTemplate gUnknown_08618110[] = { {-1} }; -const u16 gUnknown_08618138[] = { +static const u16 gUnknown_08618138[] = { 0x7fff, 0x7fff, 0x318c, 0x675a, 0x043c, 0x3aff, 0x0664, 0x4bd2, 0x6546, 0x7b14, 0x7fff, 0x318c, 0x675a, 0x0000, 0x0000, 0x0000 }; -const u8 gUnknown_08618158[] = {10, 11, 12}; -const u8 gUnknown_0861815B[] = { 0, 10, 13}; +static const u8 gUnknown_08618158[] = {10, 11, 12}; +static const u8 gUnknown_0861815B[] = { 0, 10, 13}; -const u8 *const gUnknown_08618160[] = { +static const u8 *const gUnknown_08618160[] = { Unknown_08617F07, Unknown_08617F97, Unknown_08618020, @@ -101,7 +101,7 @@ extern const u8 gUnknown_08DDB020[]; extern const u8 gUnknown_08DDB2C4[]; extern const u8 gUnknown_08DDAFE0[]; -const u8 *const gUnknown_08618178[][3] = { +static const u8 *const gUnknown_08618178[][3] = { { gUnknown_08DD87C0, gUnknown_08DD8EE0, @@ -136,7 +136,7 @@ extern const u8 gMultiBootProgram_BerryGlitchFix_End[]; // .text -void sub_81BF384(void) +void InitBerryFixProgram(void) { DisableInterrupts(0xFFFF); EnableInterrupts(0x0001); @@ -146,82 +146,82 @@ void sub_81BF384(void) ResetTasks(); remove_some_task(); SetGpuReg(REG_OFFSET_DISPCNT, 0x0000); - gUnknown_030012B8 = AllocZeroed(0x50); - gUnknown_030012B8->state = 0; - gUnknown_030012B8->unk1 = 6; - SetMainCallback2(sub_81BF3DC); + berry_fix_mb_manager = AllocZeroed(0x50); + berry_fix_mb_manager->state = 0; + berry_fix_mb_manager->unk1 = 6; + SetMainCallback2(berry_fix_main); } -static void sub_81BF3DC(void) +static void berry_fix_main(void) { - switch (gUnknown_030012B8->state) + switch (berry_fix_mb_manager->state) { case 0: - sub_81BF5A4(); - gUnknown_030012B8->state = 1; + berry_fix_gpu_set(); + berry_fix_mb_manager->state = 1; break; case 1: - if (sub_81BF7A4(5) == 5 && (gMain.newKeys & A_BUTTON)) + if (berry_fix_text_update(5) == 5 && (gMain.newKeys & A_BUTTON)) { - gUnknown_030012B8->state = 2; + berry_fix_mb_manager->state = 2; } break; case 2: - if (sub_81BF7A4(0) == 0 && (gMain.newKeys & A_BUTTON)) + if (berry_fix_text_update(0) == 0 && (gMain.newKeys & A_BUTTON)) { - gUnknown_030012B8->state = 3; + berry_fix_mb_manager->state = 3; } break; case 3: - if (sub_81BF7A4(1) == 1) + if (berry_fix_text_update(1) == 1) { - gUnknown_030012B8->mb.masterp = gUnknown_089A6550; - gUnknown_030012B8->mb.server_type = 0; - MultiBootInit(&gUnknown_030012B8->mb); - gUnknown_030012B8->unk2 = 0; - gUnknown_030012B8->state = 4; + berry_fix_mb_manager->mb.masterp = gUnknown_089A6550; + berry_fix_mb_manager->mb.server_type = 0; + MultiBootInit(&berry_fix_mb_manager->mb); + berry_fix_mb_manager->unk2 = 0; + berry_fix_mb_manager->state = 4; } break; case 4: - MultiBootMain(&gUnknown_030012B8->mb); - if (gUnknown_030012B8->mb.probe_count != 0 || (!(gUnknown_030012B8->mb.response_bit & 2) || !(gUnknown_030012B8->mb.client_bit & 2))) + MultiBootMain(&berry_fix_mb_manager->mb); + if (berry_fix_mb_manager->mb.probe_count != 0 || (!(berry_fix_mb_manager->mb.response_bit & 2) || !(berry_fix_mb_manager->mb.client_bit & 2))) { - gUnknown_030012B8->unk2 = 0; + berry_fix_mb_manager->unk2 = 0; } - else if (++ gUnknown_030012B8->unk2 > 180) + else if (++ berry_fix_mb_manager->unk2 > 180) { - MultiBootStartMaster(&gUnknown_030012B8->mb, gMultiBootProgram_BerryGlitchFix_Start, (u32)(gMultiBootProgram_BerryGlitchFix_End - gMultiBootProgram_BerryGlitchFix_Start), 4, 1); - gUnknown_030012B8->state = 5; + MultiBootStartMaster(&berry_fix_mb_manager->mb, gMultiBootProgram_BerryGlitchFix_Start, (u32)(gMultiBootProgram_BerryGlitchFix_End - gMultiBootProgram_BerryGlitchFix_Start), 4, 1); + berry_fix_mb_manager->state = 5; } break; case 5: - if (sub_81BF7A4(2) == 2) { - MultiBootMain(&gUnknown_030012B8->mb); - if (MultiBootCheckComplete(&gUnknown_030012B8->mb)) { - gUnknown_030012B8->state = 6; + if (berry_fix_text_update(2) == 2) { + MultiBootMain(&berry_fix_mb_manager->mb); + if (MultiBootCheckComplete(&berry_fix_mb_manager->mb)) { + berry_fix_mb_manager->state = 6; } - else if (!(gUnknown_030012B8->mb.client_bit & 2)) { - gUnknown_030012B8->state = 7; + else if (!(berry_fix_mb_manager->mb.client_bit & 2)) { + berry_fix_mb_manager->state = 7; } } break; case 6: - if (sub_81BF7A4(3) == 3 && gMain.newKeys & A_BUTTON) + if (berry_fix_text_update(3) == 3 && gMain.newKeys & A_BUTTON) { DoSoftReset(); } break; case 7: - if (sub_81BF7A4(4) == 4 && gMain.newKeys & A_BUTTON) + if (berry_fix_text_update(4) == 4 && gMain.newKeys & A_BUTTON) { - gUnknown_030012B8->state = 1; + berry_fix_mb_manager->state = 1; } break; } } #ifdef NONMATCHING -static void sub_81BF5A4(void) +static void berry_fix_gpu_set(void) { s32 width; @@ -268,7 +268,7 @@ static void sub_81BF5A4(void) } #else -__attribute__((naked)) static void sub_81BF5A4(void) +__attribute__((naked)) static void berry_fix_gpu_set(void) { asm(".syntax unified\n" "\tpush {r4-r6,lr}\n" @@ -476,26 +476,26 @@ __attribute__((naked)) static void sub_81BF5A4(void) } #endif -static int sub_81BF7A4(int checkval) +static int berry_fix_text_update(int checkval) { - if (gUnknown_030012B8->unk1 == checkval) + if (berry_fix_mb_manager->unk1 == checkval) { return checkval; } - if (gUnknown_030012B8->unk1 == 6) + if (berry_fix_mb_manager->unk1 == 6) { - sub_81BF7E8(checkval); - gUnknown_030012B8->unk1 = checkval; + berry_fix_text_print(checkval); + berry_fix_mb_manager->unk1 = checkval; } else { - sub_81BF8D8(); - gUnknown_030012B8->unk1 = 6; + berry_fix_bg_hide(); + berry_fix_mb_manager->unk1 = 6; } - return gUnknown_030012B8->unk1; + return berry_fix_mb_manager->unk1; } -static void sub_81BF7E8(int scene) +static void berry_fix_text_print(int scene) { FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32); FillWindowPixelBuffer(1, 0xAA); @@ -525,7 +525,7 @@ static void sub_81BF7E8(int scene) ShowBg(1); } -static void sub_81BF8D8() +static void berry_fix_bg_hide() { HideBg(0); HideBg(1); -- cgit v1.2.3 From 9a0438af6abb2a90e1004ae686e504bf8e2335da Mon Sep 17 00:00:00 2001 From: yenatch Date: Mon, 18 Sep 2017 17:44:55 -0400 Subject: battle_3: tabs --- src/battle_3.c | 66 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index d5d14e040..a2ddd1c2d 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -1689,11 +1689,11 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) if (gBankAttacker >= gNoOfAllBanks) gBankAttacker = bank; switch (gLastUsedAbility) - { - case 0xFF: //weather from overworld + { + case 0xFF: //weather from overworld //_08042A86 - switch (weather_get_current()) - { + switch (weather_get_current()) + { case 3: case 5: case 13: @@ -1723,34 +1723,34 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) effect++; } break; - } - if (effect) + } + if (effect) { gBattleCommunication[MULTISTRING_CHOOSER] = weather_get_current(); b_push_move_exec(gUnknown_082DACE7); } - break; - case ABILITY_DRIZZLE: + break; + case ABILITY_DRIZZLE: //_08042B78 - if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)) + if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)) { gBattleWeather = (WEATHER_RAIN_PERMANENT | WEATHER_RAIN_TEMPORARY); b_push_move_exec(BattleScript_DrizzleActivates); gBattleScripting.bank = bank; effect++; } - break; - case ABILITY_SAND_STREAM: + break; + case ABILITY_SAND_STREAM: //_08042BA8 - if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT)) + if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT)) { gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY); b_push_move_exec(BattleScript_SandstreamActivates); gBattleScripting.bank = bank; effect++; } - break; - case ABILITY_DROUGHT: + break; + case ABILITY_DROUGHT: //_08042BD8 if (!(gBattleWeather & WEATHER_SUN_PERMANENT)) { @@ -1759,16 +1759,16 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattleScripting.bank = bank; effect++; } - break; - case ABILITY_INTIMIDATE: + break; + case ABILITY_INTIMIDATE: //_08042C08 if (!(gSpecialStatuses[bank].intimidatedPoke)) { gStatuses3[bank] |= STATUS3_INTIMIDATE_POKES; gSpecialStatuses[bank].intimidatedPoke = 1; } - break; - case ABILITY_FORECAST: + break; + case ABILITY_FORECAST: //_08042C3C effect = CastformDataTypeChange(bank); if (effect != 0) @@ -1777,20 +1777,20 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattleScripting.bank = bank; gBattleStruct->formToChangeInto = effect - 1; } - break; - case ABILITY_TRACE: - if (!(gSpecialStatuses[bank].traced)) + break; + case ABILITY_TRACE: + if (!(gSpecialStatuses[bank].traced)) { gStatuses3[bank] |= STATUS3_TRACE; gSpecialStatuses[bank].traced = 1; } - break; - case ABILITY_CLOUD_NINE: - case ABILITY_AIR_LOCK: - { - u8 i; + break; + case ABILITY_CLOUD_NINE: + case ABILITY_AIR_LOCK: + { + u8 i; - for (i = 0; i < gNoOfAllBanks; i++) + for (i = 0; i < gNoOfAllBanks; i++) { // TODO: i should be in r6 here //asm("":::"r4","r5"); @@ -1803,10 +1803,10 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) break; } } - } - break; - } - break; + } + break; + } + break; case ABILITYEFFECT_ENDTURN: // 1 //_08042CDC if (gBattleMons[bank].hp != 0) @@ -2435,7 +2435,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) { asm( "\n\ - .syntax unified\n\ + .syntax unified\n\ push {r4-r7,lr}\n\ mov r7, r10\n\ mov r6, r9\n\ @@ -5459,7 +5459,7 @@ _0804443A:\n\ pop {r1}\n\ bx r1\n\ .pool\n\ - .syntax divided"); + .syntax divided"); } #endif // NONMATCHING -- cgit v1.2.3 From 2e7127284f98cb4c8c02b1a41a19fdc73ed4eb79 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Mon, 18 Sep 2017 23:48:47 +0200 Subject: egg hatch almost decompiled --- src/egg_hatch.c | 381 ++++++++++++++++++++++++++++++++++++++++++++++++++------ src/pokemon_3.c | 2 - src/text.c | 3 +- 3 files changed, 347 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/egg_hatch.c b/src/egg_hatch.c index 0b924fced..fc079444c 100644 --- a/src/egg_hatch.c +++ b/src/egg_hatch.c @@ -31,20 +31,14 @@ struct EggHatchData u8 CB2_state; u8 CB2_PalCounter; u8 eggPartyID; - u8 field_5; - u8 field_6; + u8 unused_5; + u8 unused_6; u8 eggShardVelocityID; - u8 field_8; - u8 field_9; - u8 field_A; - u8 field_B; + u8 windowId; + u8 unused_9; + u8 unused_A; u16 species; - u8 field_E; - u8 field_F; - u8 field_10; - u8 field_11; - u8 field_12; - u8 field_13; + struct TextColor textColor; }; extern struct EggHatchData* gEggHatchData; @@ -68,31 +62,36 @@ extern const u32 gUnknown_08331F60[]; // tilemap gameboy circle extern u8* GetMonNick(struct Pokemon* mon, u8* dst); extern u8* GetBoxMonNick(struct BoxPokemon* boxMon, u8* dst); extern u8 sav1_map_get_name(void); +extern s8 sub_8198C58(void); extern void sub_81DB5E8(u8* str1, u8* str2, u8); extern void sub_806A068(u16, u8); extern void fade_screen(u8, u8); extern void overworld_free_bg_tilemaps(void); extern void sub_80AF168(void); extern void init_uns_table_pokemon_copy(void); +extern void sub_805F094(void); extern void remove_some_task(void); extern void reset_temp_tile_data_buffers(void); +extern void c2_exit_to_overworld_2_switch(void); +extern void play_some_sound(void); extern void copy_decompressed_tile_data_to_vram_autofree(u8 bg_id, const void* src, u16 size, u16 offset, u8 mode); - - void Task_EggHatch(u8 taskID); - void CB2_EggHatch_0(void); - void CB2_EggHatch_1(void); - void SpriteCB_Egg_0(struct Sprite* sprite); - void SpriteCB_Egg_1(struct Sprite* sprite); - void SpriteCB_Egg_2(struct Sprite* sprite); - void SpriteCB_Egg_3(struct Sprite* sprite); - void SpriteCB_Egg_4(struct Sprite* sprite); - void SpriteCB_Egg_5(struct Sprite* sprite); - void SpriteCB_EggShard(struct Sprite* sprite); - void EggHatchPrintMessage2(u8* src); - void EggHatchPrintMessage1(u8* src); - bool8 EggHatchUpdateWindowText(void); - void CreateRandomEggShardSprite(void); - void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex); +extern void CreateYesNoMenu(const u8*, u16, u8, u8); +extern void DoNamingScreen(u8, const u8*, u16, u8, u32, MainCallback); +extern void AddTextPrinterParametrized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, struct TextColor* colors, s8 speed, u8 *str); + +static void Task_EggHatch(u8 taskID); +static void CB2_EggHatch_0(void); +static void CB2_EggHatch_1(void); +static void SpriteCB_Egg_0(struct Sprite* sprite); +static void SpriteCB_Egg_1(struct Sprite* sprite); +static void SpriteCB_Egg_2(struct Sprite* sprite); +static void SpriteCB_Egg_3(struct Sprite* sprite); +static void SpriteCB_Egg_4(struct Sprite* sprite); +static void SpriteCB_Egg_5(struct Sprite* sprite); +static void SpriteCB_EggShard(struct Sprite* sprite); +static void EggHatchPrintMessage(u8 windowId, u8* string, u8 x, u8 y, u8 speed); +static void CreateRandomEggShardSprite(void); +static void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex); static void CreatedHatchedMon(struct Pokemon *egg, struct Pokemon *temp) { @@ -148,7 +147,7 @@ static void CreatedHatchedMon(struct Pokemon *egg, struct Pokemon *temp) *egg = *temp; } -void AddHatchedMonToParty(u8 id) +static void AddHatchedMonToParty(u8 id) { u8 isEgg = 0x46; // ? u16 pokeNum; @@ -212,7 +211,7 @@ bool8 sub_8071614(void) return sub_807158C(&gSaveBlock1Ptr->daycare, gSpecialVar_0x8004); } -u8 EggHatchCreateMonSprite(u8 a0, u8 switchID, u8 pokeID, u16* speciesLoc) +static u8 EggHatchCreateMonSprite(u8 a0, u8 switchID, u8 pokeID, u16* speciesLoc) { u8 r5 = 0; u8 spriteID = 0; @@ -251,21 +250,21 @@ u8 EggHatchCreateMonSprite(u8 a0, u8 switchID, u8 pokeID, u16* speciesLoc) return spriteID; } -void VBlankCB_EggHatch(void) +static void VBlankCB_EggHatch(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } -void EggHatch(void) +static void EggHatch(void) { ScriptContext2_Enable(); CreateTask(Task_EggHatch, 10); fade_screen(1, 0); } - void Task_EggHatch(u8 taskID) +static void Task_EggHatch(u8 taskID) { if (!gPaletteFade.active) { @@ -276,7 +275,7 @@ void EggHatch(void) } } - void CB2_EggHatch_0(void) +static void CB2_EggHatch_0(void) { switch (gMain.state) { @@ -315,7 +314,7 @@ void EggHatch(void) break; case 1: InitWindows(gUnknown_0832C06C); - gEggHatchData->field_8 = 0; + gEggHatchData->windowId = 0; gMain.state++; break; case 2: @@ -362,3 +361,315 @@ void EggHatch(void) BuildOamBuffer(); UpdatePaletteFade(); } + +static void EggHatchSetMonNickname(void) +{ + SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3); + sub_805F094(); + Free(gEggHatchData); + SetMainCallback2(c2_exit_to_overworld_2_switch); +} + +static void Task_EggHatchPlayBGM(u8 taskID) +{ + if (gTasks[taskID].data[0] == 0) + { + StopMapMusic(); + play_some_sound(); + } + if (gTasks[taskID].data[0] == 1) + PlayBGM(376); + if (gTasks[taskID].data[0] > 60) + { + PlayBGM(377); + DestroyTask(taskID); + // UB: task is destroyed, yet the value is incremented + } + gTasks[taskID].data[0]++; +} + +extern const struct SpriteTemplate gUnknown_0832BFFC; +extern const u8 gUnknown_0832C07C[]; +extern const u8 gOtherText_HatchedFromEgg[]; +extern const u8 gOtherText_NickHatchPrompt[]; + +static void CB2_EggHatch_1(void) +{ + u16 species; + u8 gender; + u32 personality; + + switch (gEggHatchData->CB2_state) + { + case 0: + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + gEggHatchData->eggSpriteID = CreateSprite(&gUnknown_0832BFFC, 120, 75, 5); + ShowBg(0); + ShowBg(1); + gEggHatchData->CB2_state++; + CreateTask(Task_EggHatchPlayBGM, 5); + break; + case 1: + if (!gPaletteFade.active) + { + FillWindowPixelBuffer(gEggHatchData->windowId, 0); + gEggHatchData->CB2_PalCounter = 0; + gEggHatchData->CB2_state++; + } + break; + case 2: + if (++gEggHatchData->CB2_PalCounter > 30) + { + gEggHatchData->CB2_state++; + gSprites[gEggHatchData->eggSpriteID].callback = SpriteCB_Egg_0; + } + break; + case 3: + if (gSprites[gEggHatchData->eggSpriteID].callback == SpriteCallbackDummy) + { + species = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_SPECIES); + DoMonFrontSpriteAnimation(&gSprites[gEggHatchData->pokeSpriteID], species, FALSE, 1); + gEggHatchData->CB2_state++; + } + break; + case 4: + if (gSprites[gEggHatchData->pokeSpriteID].callback == SpriteCallbackDummy) + { + gEggHatchData->CB2_state++; + } + break; + case 5: + GetMonNick(&gPlayerParty[gEggHatchData->eggPartyID], gStringVar1); + StringExpandPlaceholders(gStringVar4, gOtherText_HatchedFromEgg); + EggHatchPrintMessage(gEggHatchData->windowId, gStringVar4, 0, 3, 0xFF); + PlayFanfare(371); + gEggHatchData->CB2_state++; + PutWindowTilemap(gEggHatchData->windowId); + CopyWindowToVram(gEggHatchData->windowId, 3); + break; + case 6: + if (IsFanfareTaskInactive()) + gEggHatchData->CB2_state++; + break; + case 7: + if (IsFanfareTaskInactive()) + gEggHatchData->CB2_state++; + break; + case 8: + GetMonNick(&gPlayerParty[gEggHatchData->eggPartyID], gStringVar1); + StringExpandPlaceholders(gStringVar4, gOtherText_NickHatchPrompt); + EggHatchPrintMessage(gEggHatchData->windowId, gStringVar4, 0, 2, 1); + gEggHatchData->CB2_state++; + break; + case 9: + if (!IsTextPrinterActive(gEggHatchData->windowId)) + { + sub_809882C(gEggHatchData->windowId, 0x140, 0xE0); + CreateYesNoMenu(gUnknown_0832C07C, 0x140, 0xE, 0); + gEggHatchData->CB2_state++; + } + break; + case 10: + switch (sub_8198C58()) + { + case 0: + GetMonNick(&gPlayerParty[gEggHatchData->eggPartyID], gStringVar3); + species = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_SPECIES); + gender = GetMonGender(&gPlayerParty[gEggHatchData->eggPartyID]); + personality = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_PERSONALITY, 0); + DoNamingScreen(3, gStringVar3, species, gender, personality, EggHatchSetMonNickname); + break; + case 1: + case -1: + gEggHatchData->CB2_state++; + } + break; + case 11: + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + gEggHatchData->CB2_state++; + break; + case 12: + if (!gPaletteFade.active) + { + sub_805F094(); + RemoveWindow(gEggHatchData->windowId); + UnsetBgTilemapBuffer(0); + UnsetBgTilemapBuffer(1); + Free(gEggHatchData); + SetMainCallback2(c2_exit_to_overworld_2_switch); + } + break; + } + + RunTasks(); + RunTextPrinters(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static void SpriteCB_Egg_0(struct Sprite* sprite) +{ + if (++sprite->data0 > 20) + { + sprite->callback = SpriteCB_Egg_1; + sprite->data0 = 0; + } + else + { + sprite->data1 = (sprite->data1 + 20) & 0xFF; + sprite->pos2.x = Sin(sprite->data1, 1); + if (sprite->data0 == 15) + { + PlaySE(SE_BOWA); + StartSpriteAnim(sprite, 1); + CreateRandomEggShardSprite(); + } + } +} + +static void SpriteCB_Egg_1(struct Sprite* sprite) +{ + if (++sprite->data2 > 30) + { + if (++sprite->data0 > 20) + { + sprite->callback = SpriteCB_Egg_2; + sprite->data0 = 0; + sprite->data2 = 0; + } + else + { + sprite->data1 = (sprite->data1 + 20) & 0xFF; + sprite->pos2.x = Sin(sprite->data1, 2); + if (sprite->data0 == 15) + { + PlaySE(SE_BOWA); + StartSpriteAnim(sprite, 2); + } + } + } +} + +static void SpriteCB_Egg_2(struct Sprite* sprite) +{ + if (++sprite->data2 > 30) + { + if (++sprite->data0 > 38) + { + u16 species; + + sprite->callback = SpriteCB_Egg_3; + sprite->data0 = 0; + species = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_SPECIES); + gSprites[gEggHatchData->pokeSpriteID].pos2.x = 0; + gSprites[gEggHatchData->pokeSpriteID].pos2.y = 0; + } + else + { + sprite->data1 = (sprite->data1 + 20) & 0xFF; + sprite->pos2.x = Sin(sprite->data1, 2); + if (sprite->data0 == 15) + { + PlaySE(SE_BOWA); + StartSpriteAnim(sprite, 2); + CreateRandomEggShardSprite(); + CreateRandomEggShardSprite(); + } + if (sprite->data0 == 30) + PlaySE(SE_BOWA); + } + } +} + +static void SpriteCB_Egg_3(struct Sprite* sprite) +{ + if (++sprite->data0 > 50) + { + sprite->callback = SpriteCB_Egg_4; + sprite->data0 = 0; + } +} + +static void SpriteCB_Egg_4(struct Sprite* sprite) +{ + s16 i; + if (sprite->data0 == 0) + BeginNormalPaletteFade(-1, -1, 0, 0x10, 0xFFFF); + if (sprite->data0 < 4u) + { + for (i = 0; i <= 3; i++) + CreateRandomEggShardSprite(); + } + sprite->data0++; + if (!gPaletteFade.active) + { + PlaySE(SE_TAMAGO); + sprite->invisible = 1; + sprite->callback = SpriteCB_Egg_5; + sprite->data0 = 0; + } +} + +static void SpriteCB_Egg_5(struct Sprite* sprite) +{ + if (sprite->data0 == 0) + { + gSprites[gEggHatchData->pokeSpriteID].invisible = 0; + StartSpriteAffineAnim(&gSprites[gEggHatchData->pokeSpriteID], 1); + } + if (sprite->data0 == 8) + BeginNormalPaletteFade(-1, -1, 0x10, 0, 0xFFFF); + if (sprite->data0 <= 9) + gSprites[gEggHatchData->pokeSpriteID].pos1.y -= 1; + if (sprite->data0 > 40) + sprite->callback = SpriteCallbackDummy; + sprite->data0++; +} + +static void SpriteCB_EggShard(struct Sprite* sprite) +{ + sprite->data4 += sprite->data1; + sprite->data5 += sprite->data2; + + sprite->pos2.x = sprite->data4 / 256; + sprite->pos2.y = sprite->data5 / 256; + + sprite->data2 += sprite->data3; + + if (sprite->pos1.y + sprite->pos2.y > sprite->pos1.y + 20 && sprite->data2 > 0) + DestroySprite(sprite); +} + +extern const s16 sEggShardVelocities[][2]; + +static void CreateRandomEggShardSprite(void) +{ + u16 spriteAnimIndex; + + s16 velocity1 = sEggShardVelocities[gEggHatchData->eggShardVelocityID][0]; + s16 velocity2 = sEggShardVelocities[gEggHatchData->eggShardVelocityID][1]; + gEggHatchData->eggShardVelocityID++; + spriteAnimIndex = Random() % 4; + CreateEggShardSprite(120, 60, velocity1, velocity2, 100, spriteAnimIndex); +} + +extern const struct SpriteTemplate gUnknown_0832C04C; + +static void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex) +{ + u8 spriteID = CreateSprite(&gUnknown_0832C04C, x, y, 4); + gSprites[spriteID].data1 = data1; + gSprites[spriteID].data2 = data2; + gSprites[spriteID].data3 = data3; + StartSpriteAnim(&gSprites[spriteID], spriteAnimIndex); +} + +static void EggHatchPrintMessage(u8 windowId, u8* string, u8 x, u8 y, u8 speed) +{ + FillWindowPixelBuffer(windowId, 0xFF); + gEggHatchData->textColor.fgColor = 0; + gEggHatchData->textColor.bgColor = 5; + gEggHatchData->textColor.shadowColor = 6; + AddTextPrinterParametrized2(windowId, 1, x, y, 0, 0, &gEggHatchData->textColor, speed, string); +} diff --git a/src/pokemon_3.c b/src/pokemon_3.c index 2d1dfb8b7..a2282539e 100644 --- a/src/pokemon_3.c +++ b/src/pokemon_3.c @@ -1511,8 +1511,6 @@ static void Task_PokemonSummaryAnimateAfterDelay(u8 taskId) } } -void DoMonFrontSpriteAnimation(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3); - void BattleAnimateFrontSprite(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3) { if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))) diff --git a/src/text.c b/src/text.c index cad8326e3..4b963d1a6 100644 --- a/src/text.c +++ b/src/text.c @@ -244,12 +244,11 @@ void RunTextPrinters(void) } } -bool8 IsTextPrinterActive(u8 id) +bool16 IsTextPrinterActive(u8 id) { return gTextPrinters[id].sub_union.sub.active; } - u32 RenderFont(struct TextPrinter *textPrinter) { u32 ret; -- cgit v1.2.3 From 8098a209da963bc1654d1139f3f0d885dfff7af3 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 18 Sep 2017 19:30:55 -0400 Subject: Remove warnings --- src/field_map_obj.c | 80 ++++++++++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 60e622f28..26bc513fb 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -127,52 +127,52 @@ static void npc_update_obj_anim_flag(struct MapObject *, struct Sprite *); // ROM data -void (*const gUnknown_08505438[NUM_FIELD_MAP_OBJECT_TEMPLATES])(struct Sprite *); -const u8 gUnknown_0850557C[NUM_FIELD_MAP_OBJECT_TEMPLATES]; -const u8 gUnknown_085055CD[NUM_FIELD_MAP_OBJECT_TEMPLATES]; -const struct MapObjectGraphicsInfo *const gMauvilleOldManGraphicsInfoPointers[7]; -const struct MapObjectGraphicsInfo *const gFieldObjectGraphicsInfoPointers[0xEF]; -u8 (*const gUnknown_0850D714[11])(s16, s16, s16, s16); +extern void (*const gUnknown_08505438[NUM_FIELD_MAP_OBJECT_TEMPLATES])(struct Sprite *); +extern const u8 gUnknown_0850557C[NUM_FIELD_MAP_OBJECT_TEMPLATES]; +extern const u8 gUnknown_085055CD[NUM_FIELD_MAP_OBJECT_TEMPLATES]; +extern const struct MapObjectGraphicsInfo *const gMauvilleOldManGraphicsInfoPointers[7]; +extern const struct MapObjectGraphicsInfo *const gFieldObjectGraphicsInfoPointers[0xEF]; +extern u8 (*const gUnknown_0850D714[11])(s16, s16, s16, s16); struct PairedPalettes { u16 tag; const u16 *data; }; -u8 gUnknown_084975C4[0x10]; -const struct SpriteTemplate gUnknown_084975D4; -void (*const gUnknown_084975EC[3])(struct Sprite *); -const struct SpritePalette gUnknown_0850BBC8[39]; -const struct PairedPalettes gUnknown_0850BD00[4]; -const struct PairedPalettes gUnknown_0850BD78[14]; -const u16 *const gUnknown_0850BE38[2]; -const s16 gUnknown_0850D6DC[4]; // {0x20, 0x40, 0x60, 0x80} -const s16 gUnknown_0850D6EC[4]; -const u8 gUnknown_0850D710[4]; // {DIR_SOUTH, DIR_NORTH, DIR_WEST, DIR_EAST} -const u8 gUnknown_0850D770[2]; // {DIR_SOUTH, DIR_NORTH} -const u8 gUnknown_0850D790[2]; // {DIR_WEST, DIR_EAST} -const u8 gUnknown_0850D7F0[2]; // {DIR_NORTH, DIR_WEST} -const u8 gUnknown_0850D808[2]; // {DIR_NORTH, DIR_EAST} -const u8 gUnknown_0850D820[2]; // {DIR_SOUTH, DIR_WEST} -const u8 gUnknown_0850D838[2]; // {DIR_SOUTH, DIR_EAST} -const u8 gUnknown_0850D850[4]; -const u8 gUnknown_0850D868[4]; -const u8 gUnknown_0850D880[4]; -const u8 gUnknown_0850D898[4]; -const u8 gUnknown_0850D8AC[5]; -const u8 gUnknown_0850D8C4[5]; -const u8 gUnknown_0850D8E8[4]; -bool8 (*const gUnknown_0850DA64[11])(struct MapObject *, struct Sprite *, u8, bool8(u8)); -bool8 (*const gUnknown_0850DB5C[4])(u8); -bool8 (*const gUnknown_0850DB6C[4])(u8); -const struct Coords16 gUnknown_0850DB7C[4]; -const u8 gUnknown_0850DC2F[4][4]; -const u8 gUnknown_0850DC3F[4][4]; -const u8 gUnknown_0850DBA0[5]; -bool8 (*const *const gUnknown_0850DC50[166])(struct MapObject *, struct Sprite *); -u8 (*const gUnknown_0850DEE8[5])(u8); -const s16 gUnknown_0850DFBC[3]; -const s16 gUnknown_0850DFC2[3]; +extern const u8 gUnknown_084975C4[0x10]; +extern const struct SpriteTemplate gUnknown_084975D4; +extern void (*const gUnknown_084975EC[3])(struct Sprite *); +extern const struct SpritePalette gUnknown_0850BBC8[39]; +extern const struct PairedPalettes gUnknown_0850BD00[4]; +extern const struct PairedPalettes gUnknown_0850BD78[14]; +extern const u16 *const gUnknown_0850BE38[2]; +extern const s16 gUnknown_0850D6DC[4]; // {0x20, 0x40, 0x60, 0x80} +extern const s16 gUnknown_0850D6EC[4]; +extern const u8 gUnknown_0850D710[4]; // {DIR_SOUTH, DIR_NORTH, DIR_WEST, DIR_EAST} +extern const u8 gUnknown_0850D770[2]; // {DIR_SOUTH, DIR_NORTH} +extern const u8 gUnknown_0850D790[2]; // {DIR_WEST, DIR_EAST} +extern const u8 gUnknown_0850D7F0[2]; // {DIR_NORTH, DIR_WEST} +extern const u8 gUnknown_0850D808[2]; // {DIR_NORTH, DIR_EAST} +extern const u8 gUnknown_0850D820[2]; // {DIR_SOUTH, DIR_WEST} +extern const u8 gUnknown_0850D838[2]; // {DIR_SOUTH, DIR_EAST} +extern const u8 gUnknown_0850D850[4]; +extern const u8 gUnknown_0850D868[4]; +extern const u8 gUnknown_0850D880[4]; +extern const u8 gUnknown_0850D898[4]; +extern const u8 gUnknown_0850D8AC[5]; +extern const u8 gUnknown_0850D8C4[5]; +extern const u8 gUnknown_0850D8E8[4]; +extern bool8 (*const gUnknown_0850DA64[11])(struct MapObject *, struct Sprite *, u8, bool8(u8)); +extern bool8 (*const gUnknown_0850DB5C[4])(u8); +extern bool8 (*const gUnknown_0850DB6C[4])(u8); +extern const struct Coords16 gUnknown_0850DB7C[4]; +extern const u8 gUnknown_0850DC2F[4][4]; +extern const u8 gUnknown_0850DC3F[4][4]; +extern const u8 gUnknown_0850DBA0[5]; +extern bool8 (*const *const gUnknown_0850DC50[166])(struct MapObject *, struct Sprite *); +extern u8 (*const gUnknown_0850DEE8[5])(u8); +extern const s16 gUnknown_0850DFBC[3]; +extern const s16 gUnknown_0850DFC2[3]; // Code -- cgit v1.2.3 From 9e96bd540ad3ae258ce7b2e8184cd162caa63c48 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 18 Sep 2017 19:39:20 -0400 Subject: Battle Dome Cards BEGIN --- src/battle_dome_cards.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/battle_dome_cards.c (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c new file mode 100644 index 000000000..0afad23f6 --- /dev/null +++ b/src/battle_dome_cards.c @@ -0,0 +1,37 @@ + +// Includes +#include "global.h" + +// Static type declarations + +struct BattleDomeCard { + u8 unk_00[12]; +}; + +// Static RAM declarations + +extern struct BattleDomeCard gUnknown_0203CD04[8]; + +// Static ROM declarations + +// .rodata + +extern const struct BattleDomeCard gUnknown_0860B058; + +// .text + +void nullsub_122(void) +{ + +} + +bool8 dp13_810BB8C(void) +{ + int i; + + for (i = 0; i < 8; i ++) + { + gUnknown_0203CD04[i] = gUnknown_0860B058; + } + return FALSE; +} -- cgit v1.2.3 From e033c721219f4412a0cb2cbbdcbec583ec60c87a Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 18 Sep 2017 20:00:46 -0400 Subject: load_pokemon_image_TODO --- src/battle_dome_cards.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 0afad23f6..6ceb929ad 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -1,6 +1,15 @@ // Includes #include "global.h" +#include "sprite.h" +#include "species.h" +#include "pokemon.h" +#include "decompress.h" + +extern const struct CompressedSpriteSheet gMonFrontPicTable[NUM_SPECIES]; +extern const struct CompressedSpriteSheet gMonBackPicTable[NUM_SPECIES]; +extern const struct CompressedSpriteSheet gTrainerFrontPicTable[]; +extern const struct CompressedSpriteSheet gTrainerBackPicTable[]; // Static type declarations @@ -20,7 +29,7 @@ extern const struct BattleDomeCard gUnknown_0860B058; // .text -void nullsub_122(void) +void nullsub_122(struct Sprite *sprite) { } @@ -35,3 +44,44 @@ bool8 dp13_810BB8C(void) } return FALSE; } + +bool8 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, void *dest, bool8 isTrainer, bool8 ignoreDeoxys) +{ + if (!isTrainer) + { + if (isFrontPic) + { + if (!ignoreDeoxys) + { + LoadSpecialPokePic(&gMonFrontPicTable[species], dest, species, personality, isFrontPic); + } + else + { + LoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species], dest, species, personality, isFrontPic); + } + } + else + { + if (!ignoreDeoxys) + { + LoadSpecialPokePic(&gMonBackPicTable[species], dest, species, personality, isFrontPic); + } + else + { + LoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[species], dest, species, personality, isFrontPic); + } + } + } + else + { + if (isFrontPic) + { + DecompressPicFromTable(&gTrainerFrontPicTable[species], dest, species); + } + else + { + DecompressPicFromTable(&gTrainerBackPicTable[species], dest, species); + } + } + return FALSE; +} -- cgit v1.2.3 From 7de2140b868a77ea99e4965b06602af9d7de2926 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 18 Sep 2017 21:26:11 -0400 Subject: sub_818D0C4 --- src/battle_dome_cards.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 6ceb929ad..085afeb0c 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -3,13 +3,14 @@ #include "global.h" #include "sprite.h" #include "species.h" -#include "pokemon.h" +#include "palette.h" #include "decompress.h" extern const struct CompressedSpriteSheet gMonFrontPicTable[NUM_SPECIES]; extern const struct CompressedSpriteSheet gMonBackPicTable[NUM_SPECIES]; extern const struct CompressedSpriteSheet gTrainerFrontPicTable[]; extern const struct CompressedSpriteSheet gTrainerBackPicTable[]; +extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; // Static type declarations @@ -20,6 +21,7 @@ struct BattleDomeCard { // Static RAM declarations extern struct BattleDomeCard gUnknown_0203CD04[8]; +extern struct SpriteTemplate gUnknown_0203CCEC; // Static ROM declarations @@ -34,7 +36,7 @@ void nullsub_122(struct Sprite *sprite) } -bool8 dp13_810BB8C(void) +bool16 dp13_810BB8C(void) { int i; @@ -45,7 +47,7 @@ bool8 dp13_810BB8C(void) return FALSE; } -bool8 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, void *dest, bool8 isTrainer, bool8 ignoreDeoxys) +bool16 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, void *dest, bool8 isTrainer, bool8 ignoreDeoxys) { if (!isTrainer) { @@ -85,3 +87,38 @@ bool8 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, vo } return FALSE; } + +bool16 sub_818D09C(u16 species, u32 personality, bool8 isFrontPic, void *dest, bool8 isTrainer) +{ + return load_pokemon_image_TODO(species, personality, isFrontPic, dest, isTrainer, FALSE); +} + +void sub_818D0C4(u16 species, u32 otId, u32 personality, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) +{ + if (!isTrainer) + { + if (paletteTag == 0xFFFF) + { + gUnknown_0203CCEC.paletteTag |= 0xFFFF; + LoadCompressedPalette(species_and_otid_get_pal(species, otId, personality), 0x100 + paletteSlot * 0x10, 0x20); + } + else + { + gUnknown_0203CCEC.paletteTag = paletteTag; + LoadCompressedObjectPalette(sub_806E7CC(species, otId, personality)); + } + } + else + { + if (paletteTag == 0xFFFF) + { + gUnknown_0203CCEC.paletteTag |= 0xFFFF; + LoadCompressedPalette(gTrainerFrontPicPaletteTable[species].data, 0x100 + paletteSlot * 0x10, 0x20); + } + else + { + gUnknown_0203CCEC.paletteTag = paletteTag; + LoadCompressedObjectPalette(&gTrainerFrontPicPaletteTable[species]); + } + } +} -- cgit v1.2.3 From 16b0b386be02390ab847a68b279f51aea54c3a95 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 18 Sep 2017 21:28:28 -0400 Subject: sub_818D180 --- src/battle_dome_cards.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 085afeb0c..810ee82eb 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -122,3 +122,15 @@ void sub_818D0C4(u16 species, u32 otId, u32 personality, u8 paletteSlot, u16 pal } } } + +void sub_818D180(u16 species, u32 otId, u32 personality, u8 paletteSlot, bool8 isTrainer) +{ + if (!isTrainer) + { + LoadCompressedPalette(species_and_otid_get_pal(species, otId, personality), paletteSlot * 0x10, 0x20); + } + else + { + LoadCompressedPalette(gTrainerFrontPicPaletteTable[species].data, paletteSlot * 0x10, 0x20); + } +} -- cgit v1.2.3 From 8aeb5ea3017dfb7ea9fd8b8f1ef6bc9d4a0fbba9 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 18 Sep 2017 21:31:28 -0400 Subject: uns_builder_assign_animtable1 --- src/battle_dome_cards.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 810ee82eb..e92773a1b 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -11,6 +11,8 @@ extern const struct CompressedSpriteSheet gMonBackPicTable[NUM_SPECIES]; extern const struct CompressedSpriteSheet gTrainerFrontPicTable[]; extern const struct CompressedSpriteSheet gTrainerBackPicTable[]; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; +extern const union AnimCmd *const gUnknown_082FF70C[]; +extern const union AnimCmd *const *const gUnknown_0830536C[]; // Static type declarations @@ -134,3 +136,15 @@ void sub_818D180(u16 species, u32 otId, u32 personality, u8 paletteSlot, bool8 i LoadCompressedPalette(gTrainerFrontPicPaletteTable[species].data, paletteSlot * 0x10, 0x20); } } + +void uns_builder_assign_animtable1(bool8 isTrainer) +{ + if (!isTrainer) + { + gUnknown_0203CCEC.anims = gUnknown_082FF70C; + } + else + { + gUnknown_0203CCEC.anims = gUnknown_0830536C[0]; + } +} -- cgit v1.2.3 From c593b51dc538961641d4f679a5b0366295179c5e Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 18 Sep 2017 22:23:13 -0400 Subject: oamt_spawn_poke_or_trainer_picture --- src/battle_dome_cards.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index e92773a1b..764e3dfe4 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -2,6 +2,7 @@ // Includes #include "global.h" #include "sprite.h" +#include "malloc.h" #include "species.h" #include "palette.h" #include "decompress.h" @@ -13,11 +14,16 @@ extern const struct CompressedSpriteSheet gTrainerBackPicTable[]; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; extern const union AnimCmd *const gUnknown_082FF70C[]; extern const union AnimCmd *const *const gUnknown_0830536C[]; +extern const struct OamData gUnknown_0860B064; // Static type declarations struct BattleDomeCard { - u8 unk_00[12]; + u8 *frames; + const struct SpriteFrameImage *images; + u16 paletteTag; + u8 spriteId; + u8 active; }; // Static RAM declarations @@ -148,3 +154,63 @@ void uns_builder_assign_animtable1(bool8 isTrainer) gUnknown_0203CCEC.anims = gUnknown_0830536C[0]; } } + +u16 oamt_spawn_poke_or_trainer_picture(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer, bool8 ignoreDeoxys) +{ + u8 i; + u8 *framePics; + struct SpriteFrameImage *images; + int j; + u8 spriteId; + + for (i = 0; i < 8; i ++) + { + if (!gUnknown_0203CD04[i].active) + { + break; + } + } + if (i == 8) + { + return 0xFFFF; + } + framePics = Alloc(4 * 0x800); + if (!framePics) + { + return 0xFFFF; + } + images = Alloc(4 * sizeof(struct SpriteFrameImage)); + if (!images) + { + Free(framePics); + return 0xFFFF; + } + if (load_pokemon_image_TODO(species, personality, isFrontPic, framePics, isTrainer, ignoreDeoxys)) + { + // debug trap? + return 0xFFFF; + } + for (j = 0; j < 4; j ++) + { + images[j].data = framePics + 0x800 * j; + images[j].size = 0x800; + } + gUnknown_0203CCEC.tileTag = 0xFFFF; + gUnknown_0203CCEC.oam = &gUnknown_0860B064; + uns_builder_assign_animtable1(isTrainer); + gUnknown_0203CCEC.images = images; + gUnknown_0203CCEC.affineAnims = gDummySpriteAffineAnimTable; + gUnknown_0203CCEC.callback = nullsub_122; + sub_818D0C4(species, otId, personality, paletteSlot, paletteTag, isTrainer); + spriteId = CreateSprite(&gUnknown_0203CCEC, x, y, 0); + if (paletteTag == 0xFFFF) + { + gSprites[spriteId].oam.paletteNum = paletteSlot; + } + gUnknown_0203CD04[i].frames = framePics; + gUnknown_0203CD04[i].images = images; + gUnknown_0203CD04[i].paletteTag = paletteTag; + gUnknown_0203CD04[i].spriteId = spriteId; + gUnknown_0203CD04[i].active = TRUE; + return spriteId; +} -- cgit v1.2.3 From 52dc68aa89a4e568673f1155542856504bd3da3f Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 18 Sep 2017 22:41:54 -0400 Subject: sub_818D3E4 --- src/battle_dome_cards.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 764e3dfe4..7eee245ee 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -15,6 +15,10 @@ extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; extern const union AnimCmd *const gUnknown_082FF70C[]; extern const union AnimCmd *const *const gUnknown_0830536C[]; extern const struct OamData gUnknown_0860B064; +extern const struct OamData gUnknown_0860B06C; +extern const union AnimCmd *const *const gUnknown_08309AAC[NUM_SPECIES]; +extern const union AffineAnimCmd *const gUnknown_082FF694[]; +extern const union AffineAnimCmd *const gUnknown_082FF618[]; // Static type declarations @@ -214,3 +218,91 @@ u16 oamt_spawn_poke_or_trainer_picture(u16 species, u32 otId, u32 personality, b gUnknown_0203CD04[i].active = TRUE; return spriteId; } + +u16 sub_818D384(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) +{ + return oamt_spawn_poke_or_trainer_picture(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, isTrainer, FALSE); +} + +u16 sub_818D3E4(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag) +{ + u8 *framePics; + struct SpriteFrameImage *images; + int j; + u8 i; + u8 spriteId; + u8 flags2; + + for (i = 0; i < 8; i ++) + { + if (!gUnknown_0203CD04[i].active) + { + break; + } + } + if (i == 8) + { + return 0xFFFF; + } + framePics = Alloc(4 * 0x800); + if (!framePics) + { + return 0xFFFF; + } + if (flags & 0x80) + { + flags &= 0x7F; + flags2 = 3; + } + else + { + flags2 = flags; + } + images = Alloc(4 * sizeof(struct SpriteFrameImage)); + if (!images) + { + Free(framePics); + return 0xFFFF; + } + if (load_pokemon_image_TODO(species, personality, flags, framePics, FALSE, FALSE)) + { + // debug trap? + return 0xFFFF; + } + for (j = 0; j < 4; j ++) + { + images[j].data = framePics + 0x800 * j; + images[j].size = 0x800; + } + gUnknown_0203CCEC.tileTag = 0xFFFF; + gUnknown_0203CCEC.anims = gUnknown_08309AAC[species]; + gUnknown_0203CCEC.images = images; + if (flags2 == 0x01) + { + gUnknown_0203CCEC.affineAnims = gUnknown_082FF694; + gUnknown_0203CCEC.oam = &gUnknown_0860B06C; + } + else if (flags2 == 0x00) + { + gUnknown_0203CCEC.affineAnims = gUnknown_082FF618; + gUnknown_0203CCEC.oam = &gUnknown_0860B06C; + } + else + { + gUnknown_0203CCEC.oam = &gUnknown_0860B064; + gUnknown_0203CCEC.affineAnims = gDummySpriteAffineAnimTable; + } + gUnknown_0203CCEC.callback = nullsub_122; + sub_818D0C4(species, otId, personality, paletteSlot, paletteTag, FALSE); + spriteId = CreateSprite(&gUnknown_0203CCEC, x, y, 0); + if (paletteTag == 0xFFFF) + { + gSprites[spriteId].oam.paletteNum = paletteSlot; + } + gUnknown_0203CD04[i].frames = framePics; + gUnknown_0203CD04[i].images = images; + gUnknown_0203CD04[i].paletteTag = paletteTag; + gUnknown_0203CD04[i].spriteId = spriteId; + gUnknown_0203CD04[i].active = TRUE; + return spriteId; +} -- cgit v1.2.3 From 7e157f202703f75933302d509f8b2bf26cf40655 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 18 Sep 2017 22:49:42 -0400 Subject: Decorate local EWRAM objects in battle_dome_cards.c as EWRAM --- src/battle_dome_cards.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 7eee245ee..f27e1e4fa 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -12,13 +12,13 @@ extern const struct CompressedSpriteSheet gMonBackPicTable[NUM_SPECIES]; extern const struct CompressedSpriteSheet gTrainerFrontPicTable[]; extern const struct CompressedSpriteSheet gTrainerBackPicTable[]; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; +extern const union AffineAnimCmd *const gUnknown_082FF618[]; +extern const union AffineAnimCmd *const gUnknown_082FF694[]; extern const union AnimCmd *const gUnknown_082FF70C[]; +extern const union AnimCmd *const *const gUnknown_08309AAC[NUM_SPECIES]; extern const union AnimCmd *const *const gUnknown_0830536C[]; extern const struct OamData gUnknown_0860B064; extern const struct OamData gUnknown_0860B06C; -extern const union AnimCmd *const *const gUnknown_08309AAC[NUM_SPECIES]; -extern const union AffineAnimCmd *const gUnknown_082FF694[]; -extern const union AffineAnimCmd *const gUnknown_082FF618[]; // Static type declarations @@ -32,8 +32,8 @@ struct BattleDomeCard { // Static RAM declarations -extern struct BattleDomeCard gUnknown_0203CD04[8]; -extern struct SpriteTemplate gUnknown_0203CCEC; +static EWRAM_DATA struct SpriteTemplate gUnknown_0203CCEC = {}; +EWRAM_DATA struct BattleDomeCard gUnknown_0203CD04[8] = {}; // Static ROM declarations -- cgit v1.2.3 From 6ef3f9dd50a0cb2d8695401d3740407fa73cde9c Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 08:13:53 -0400 Subject: sub_818D5B0 --- src/battle_dome_cards.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index f27e1e4fa..a01115a99 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -24,7 +24,7 @@ extern const struct OamData gUnknown_0860B06C; struct BattleDomeCard { u8 *frames; - const struct SpriteFrameImage *images; + struct SpriteFrameImage *images; u16 paletteTag; u8 spriteId; u8 active; @@ -306,3 +306,33 @@ u16 sub_818D3E4(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, gUnknown_0203CD04[i].active = TRUE; return spriteId; } + +u16 sub_818D5B0(u16 spriteId) +{ + u8 i; + u8 *framePics; + struct SpriteFrameImage *images; + + for (i = 0; i < 8; i ++) + { + if (gUnknown_0203CD04[i].spriteId == spriteId) + { + break; + } + } + if (i == 8) + { + return 0xFFFF; + } + framePics = gUnknown_0203CD04[i].frames; + images = gUnknown_0203CD04[i].images; + if (gUnknown_0203CD04[i].paletteTag != 0xFFFF) + { + FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(gSprites[spriteId].oam.paletteNum)); + } + DestroySprite(&gSprites[spriteId]); + Free(framePics); + Free(images); + gUnknown_0203CD04[i] = gUnknown_0860B058; + return 0; +} -- cgit v1.2.3 From ee47fe93778f938ac99be89e24761a46b44b1816 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 08:22:43 -0400 Subject: sub_818D65C --- src/battle_dome_cards.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index a01115a99..b8f0c4ff8 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -2,6 +2,7 @@ // Includes #include "global.h" #include "sprite.h" +#include "window.h" #include "malloc.h" #include "species.h" #include "palette.h" @@ -336,3 +337,13 @@ u16 sub_818D5B0(u16 spriteId) gUnknown_0203CD04[i] = gUnknown_0860B058; return 0; } + +u16 sub_818D65C(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer) +{ + if (sub_818D09C(species, personality, isFrontPic, (void *)GetWindowAttribute(windowId, WINDOW_TILE_DATA), FALSE)) + { + return 0xFFFF; + } + sub_818D180(species, otId, personality, paletteSlot, isTrainer); + return 0; +} -- cgit v1.2.3 From 148b995189f72acdad967f1c4bce0b5e0216cc2c Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Tue, 19 Sep 2017 14:27:46 +0200 Subject: finish egg hatch, clean up headers --- src/bg.c | 297 ++++++++++++++++++++--------------------- src/dma3_manager.c | 4 +- src/egg_hatch.c | 382 +++++++++++++++++++++++++++++++++++++++++------------ src/gpu_regs.c | 25 ++-- src/trig.c | 3 - 5 files changed, 459 insertions(+), 252 deletions(-) (limited to 'src') diff --git a/src/bg.c b/src/bg.c index 9f6d12062..74e3ea830 100644 --- a/src/bg.c +++ b/src/bg.c @@ -1,10 +1,12 @@ #include "global.h" #include "bg.h" #include "dma3.h" +#include "gpu_regs.h" -#define DISPCNT_ALL_BG_AND_MODE_BITS 0x0F07 +#define DISPCNT_ALL_BG_AND_MODE_BITS (DISPCNT_BG_ALL_ON | 0x7) -struct BgControl { +struct BgControl +{ struct BgConfig { u16 visible:1; u16 unknown_1:1; @@ -24,7 +26,8 @@ struct BgControl { u16 bgVisibilityAndMode; }; -struct BgConfig2 { +struct BgConfig2 +{ u32 baseTile:10; u32 basePalette:4; u32 unk_3:18; @@ -34,54 +37,36 @@ struct BgConfig2 { u32 bg_y; }; -static struct BgControl gGpuBgConfigs; -static struct BgConfig2 gGpuBgConfigs2[4]; -static u32 gDmaBusyBitfield[4]; +static IWRAM_DATA struct BgControl sGpuBgConfigs; +static IWRAM_DATA struct BgConfig2 sGpuBgConfigs2[4]; +static IWRAM_DATA u32 sDmaBusyBitfield[4]; u32 gUnneededFireRedVariable; -static const struct BgConfig gZeroedBgControlStruct = { 0 }; - -extern void SetGpuReg(u8 regOffset, u16 value); -extern void SetGpuReg_ForcedBlank(u8 regOffset, u16 value); -extern u16 GetGpuReg(u8 regOffset); -extern int CheckForSpaceForDma3Request(s16 index); - -bool32 IsInvalidBg32(u8); -void ResetBgControlStructs(); -u16 GetBgMetricTextMode(u8, u8); -u32 GetBgMetricAffineMode(u8, u8); -u32 GetBgType(u8); -void SetTextModeAndHideBgs(); -bool8 IsInvalidBg(u8); -bool32 IsTileMapOutsideWram(u8); -void CopyRectToBgTilemapBufferRect(u8, void*, u8, u8, u8, u8, u8, u8, u8, u8, u8, u16, u16); -void CopyTileMapEntry(u16*, u16*, s32, u32, u32); -u32 GetTileMapIndexFromCoords(s32, s32, s32, u32, u32); -void WriteSequenceToBgTilemapBuffer(u8, u16, u8, u8, u8, u8, u8, s16); +static const struct BgConfig sZeroedBgControlStruct = { 0 }; void ResetBgs(void) { ResetBgControlStructs(); - gGpuBgConfigs.bgVisibilityAndMode = 0; + sGpuBgConfigs.bgVisibilityAndMode = 0; SetTextModeAndHideBgs(); } -void SetBgModeInternal(u8 bgMode) +static void SetBgModeInternal(u8 bgMode) { - gGpuBgConfigs.bgVisibilityAndMode &= 0xFFF8; - gGpuBgConfigs.bgVisibilityAndMode |= bgMode; + sGpuBgConfigs.bgVisibilityAndMode &= 0xFFF8; + sGpuBgConfigs.bgVisibilityAndMode |= bgMode; } u8 GetBgMode(void) { - return gGpuBgConfigs.bgVisibilityAndMode & 0x7; + return sGpuBgConfigs.bgVisibilityAndMode & 0x7; } void ResetBgControlStructs(void) { - struct BgConfig* bgConfigs = &gGpuBgConfigs.configs[0]; - struct BgConfig zeroedConfig = gZeroedBgControlStruct; + struct BgConfig* bgConfigs = &sGpuBgConfigs.configs[0]; + struct BgConfig zeroedConfig = sZeroedBgControlStruct; int i; for (i = 0; i < 4; i++) @@ -94,7 +79,7 @@ void Unused_ResetBgControlStruct(u8 bg) { if (IsInvalidBg(bg) == FALSE) { - gGpuBgConfigs.configs[bg] = gZeroedBgControlStruct; + sGpuBgConfigs.configs[bg] = sZeroedBgControlStruct; } } @@ -104,68 +89,68 @@ void SetBgControlAttributes(u8 bg, u8 charBaseIndex, u8 mapBaseIndex, u8 screenS { if (charBaseIndex != 0xFF) { - gGpuBgConfigs.configs[bg].charBaseIndex = charBaseIndex & 0x3; + sGpuBgConfigs.configs[bg].charBaseIndex = charBaseIndex & 0x3; } if (mapBaseIndex != 0xFF) { - gGpuBgConfigs.configs[bg].mapBaseIndex = mapBaseIndex & 0x1F; + sGpuBgConfigs.configs[bg].mapBaseIndex = mapBaseIndex & 0x1F; } if (screenSize != 0xFF) { - gGpuBgConfigs.configs[bg].screenSize = screenSize & 0x3; + sGpuBgConfigs.configs[bg].screenSize = screenSize & 0x3; } if (paletteMode != 0xFF) { - gGpuBgConfigs.configs[bg].paletteMode = paletteMode; + sGpuBgConfigs.configs[bg].paletteMode = paletteMode; } if (priority != 0xFF) { - gGpuBgConfigs.configs[bg].priority = priority & 0x3; + sGpuBgConfigs.configs[bg].priority = priority & 0x3; } if (mosaic != 0xFF) { - gGpuBgConfigs.configs[bg].mosaic = mosaic & 0x1; + sGpuBgConfigs.configs[bg].mosaic = mosaic & 0x1; } if (wraparound != 0xFF) { - gGpuBgConfigs.configs[bg].wraparound = wraparound; + sGpuBgConfigs.configs[bg].wraparound = wraparound; } - gGpuBgConfigs.configs[bg].unknown_2 = 0; - gGpuBgConfigs.configs[bg].unknown_3 = 0; + sGpuBgConfigs.configs[bg].unknown_2 = 0; + sGpuBgConfigs.configs[bg].unknown_3 = 0; - gGpuBgConfigs.configs[bg].visible = 1; + sGpuBgConfigs.configs[bg].visible = 1; } } u16 GetBgControlAttribute(u8 bg, u8 attributeId) { - if (IsInvalidBg(bg) == FALSE && gGpuBgConfigs.configs[bg].visible != FALSE) + if (IsInvalidBg(bg) == FALSE && sGpuBgConfigs.configs[bg].visible != FALSE) { switch (attributeId) { case BG_CTRL_ATTR_VISIBLE: - return gGpuBgConfigs.configs[bg].visible; + return sGpuBgConfigs.configs[bg].visible; case BG_CTRL_ATTR_CHARBASEINDEX: - return gGpuBgConfigs.configs[bg].charBaseIndex; + return sGpuBgConfigs.configs[bg].charBaseIndex; case BG_CTRL_ATTR_MAPBASEINDEX: - return gGpuBgConfigs.configs[bg].mapBaseIndex; + return sGpuBgConfigs.configs[bg].mapBaseIndex; case BG_CTRL_ATTR_SCREENSIZE: - return gGpuBgConfigs.configs[bg].screenSize; + return sGpuBgConfigs.configs[bg].screenSize; case BG_CTRL_ATTR_PALETTEMODE: - return gGpuBgConfigs.configs[bg].paletteMode; + return sGpuBgConfigs.configs[bg].paletteMode; case BG_CTRL_ATTR_PRIORITY: - return gGpuBgConfigs.configs[bg].priority; + return sGpuBgConfigs.configs[bg].priority; case BG_CTRL_ATTR_MOSAIC: - return gGpuBgConfigs.configs[bg].mosaic; + return sGpuBgConfigs.configs[bg].mosaic; case BG_CTRL_ATTR_WRAPAROUND: - return gGpuBgConfigs.configs[bg].wraparound; + return sGpuBgConfigs.configs[bg].wraparound; } } @@ -177,15 +162,15 @@ u8 LoadBgVram(u8 bg, const void *src, u16 size, u16 destOffset, u8 mode) u16 offset; s8 cursor; - if (IsInvalidBg(bg) == FALSE && gGpuBgConfigs.configs[bg].visible != FALSE) + if (IsInvalidBg(bg) == FALSE && sGpuBgConfigs.configs[bg].visible != FALSE) { switch (mode) { case 0x1: - offset = gGpuBgConfigs.configs[bg].charBaseIndex * BG_CHAR_SIZE; + offset = sGpuBgConfigs.configs[bg].charBaseIndex * BG_CHAR_SIZE; break; case 0x2: - offset = gGpuBgConfigs.configs[bg].mapBaseIndex * BG_SCREEN_SIZE; + offset = sGpuBgConfigs.configs[bg].mapBaseIndex * BG_SCREEN_SIZE; break; default: cursor = -1; @@ -210,51 +195,51 @@ end: return cursor; } -void ShowBgInternal(u8 bg) +static void ShowBgInternal(u8 bg) { u16 value; - if (IsInvalidBg(bg) == FALSE && gGpuBgConfigs.configs[bg].visible != FALSE) + if (IsInvalidBg(bg) == FALSE && sGpuBgConfigs.configs[bg].visible != FALSE) { - value = gGpuBgConfigs.configs[bg].priority | - (gGpuBgConfigs.configs[bg].charBaseIndex << 2) | - (gGpuBgConfigs.configs[bg].mosaic << 6) | - (gGpuBgConfigs.configs[bg].paletteMode << 7) | - (gGpuBgConfigs.configs[bg].mapBaseIndex << 8) | - (gGpuBgConfigs.configs[bg].wraparound << 13) | - (gGpuBgConfigs.configs[bg].screenSize << 14); + value = sGpuBgConfigs.configs[bg].priority | + (sGpuBgConfigs.configs[bg].charBaseIndex << 2) | + (sGpuBgConfigs.configs[bg].mosaic << 6) | + (sGpuBgConfigs.configs[bg].paletteMode << 7) | + (sGpuBgConfigs.configs[bg].mapBaseIndex << 8) | + (sGpuBgConfigs.configs[bg].wraparound << 13) | + (sGpuBgConfigs.configs[bg].screenSize << 14); SetGpuReg((bg << 1) + 0x8, value); - gGpuBgConfigs.bgVisibilityAndMode |= 1 << (bg + 8); - gGpuBgConfigs.bgVisibilityAndMode &= DISPCNT_ALL_BG_AND_MODE_BITS; + sGpuBgConfigs.bgVisibilityAndMode |= 1 << (bg + 8); + sGpuBgConfigs.bgVisibilityAndMode &= DISPCNT_ALL_BG_AND_MODE_BITS; } } -void HideBgInternal(u8 bg) +static void HideBgInternal(u8 bg) { if (IsInvalidBg(bg) == FALSE) { - gGpuBgConfigs.bgVisibilityAndMode &= ~(1 << (bg + 8)); - gGpuBgConfigs.bgVisibilityAndMode &= DISPCNT_ALL_BG_AND_MODE_BITS; + sGpuBgConfigs.bgVisibilityAndMode &= ~(1 << (bg + 8)); + sGpuBgConfigs.bgVisibilityAndMode &= DISPCNT_ALL_BG_AND_MODE_BITS; } } -void SyncBgVisibilityAndMode() +static void SyncBgVisibilityAndMode(void) { - SetGpuReg(0, (GetGpuReg(0) & ~DISPCNT_ALL_BG_AND_MODE_BITS) | gGpuBgConfigs.bgVisibilityAndMode); + SetGpuReg(0, (GetGpuReg(0) & ~DISPCNT_ALL_BG_AND_MODE_BITS) | sGpuBgConfigs.bgVisibilityAndMode); } -void SetTextModeAndHideBgs() +void SetTextModeAndHideBgs(void) { SetGpuReg(0, GetGpuReg(0) & ~DISPCNT_ALL_BG_AND_MODE_BITS); } -void SetBgAffineInternal(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, s16 dispCenterY, s16 scaleX, s16 scaleY, u16 rotationAngle) +static void SetBgAffineInternal(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, s16 dispCenterY, s16 scaleX, s16 scaleY, u16 rotationAngle) { struct BgAffineSrcData src; struct BgAffineDstData dest; - switch (gGpuBgConfigs.bgVisibilityAndMode & 0x7) + switch (sGpuBgConfigs.bgVisibilityAndMode & 0x7) { case 1: if (bg != 2) @@ -309,7 +294,7 @@ void ResetBgsAndClearDma3BusyFlags(u32 leftoverFireRedLeafGreenVariable) for (i = 0; i < 4; i++) { - gDmaBusyBitfield[i] = 0; + sDmaBusyBitfield[i] = 0; } gUnneededFireRedVariable = leftoverFireRedLeafGreenVariable; @@ -336,18 +321,18 @@ void InitBgsFromTemplates(u8 bgMode, const struct BgTemplate *templates, u8 numT 0, 0); - gGpuBgConfigs2[bg].baseTile = templates[i].baseTile; - gGpuBgConfigs2[bg].basePalette = 0; - gGpuBgConfigs2[bg].unk_3 = 0; + sGpuBgConfigs2[bg].baseTile = templates[i].baseTile; + sGpuBgConfigs2[bg].basePalette = 0; + sGpuBgConfigs2[bg].unk_3 = 0; - gGpuBgConfigs2[bg].tilemap = NULL; - gGpuBgConfigs2[bg].bg_x = 0; - gGpuBgConfigs2[bg].bg_y = 0; + sGpuBgConfigs2[bg].tilemap = NULL; + sGpuBgConfigs2[bg].bg_x = 0; + sGpuBgConfigs2[bg].bg_y = 0; } } } -void InitBgFromTemplate(struct BgTemplate *template) +void InitBgFromTemplate(const struct BgTemplate *template) { u8 bg = template->bg; @@ -362,13 +347,13 @@ void InitBgFromTemplate(struct BgTemplate *template) 0, 0); - gGpuBgConfigs2[bg].baseTile = template->baseTile; - gGpuBgConfigs2[bg].basePalette = 0; - gGpuBgConfigs2[bg].unk_3 = 0; + sGpuBgConfigs2[bg].baseTile = template->baseTile; + sGpuBgConfigs2[bg].basePalette = 0; + sGpuBgConfigs2[bg].unk_3 = 0; - gGpuBgConfigs2[bg].tilemap = NULL; - gGpuBgConfigs2[bg].bg_x = 0; - gGpuBgConfigs2[bg].bg_y = 0; + sGpuBgConfigs2[bg].tilemap = NULL; + sGpuBgConfigs2[bg].bg_x = 0; + sGpuBgConfigs2[bg].bg_y = 0; } } @@ -384,11 +369,11 @@ u16 LoadBgTiles(u8 bg, const void* src, u16 size, u16 destOffset) if (GetBgControlAttribute(bg, BG_CTRL_ATTR_PALETTEMODE) == 0) { - tileOffset = (gGpuBgConfigs2[bg].baseTile + destOffset) * 0x20; + tileOffset = (sGpuBgConfigs2[bg].baseTile + destOffset) * 0x20; } else { - tileOffset = (gGpuBgConfigs2[bg].baseTile + destOffset) * 0x40; + tileOffset = (sGpuBgConfigs2[bg].baseTile + destOffset) * 0x40; } cursor = LoadBgVram(bg, src, size, tileOffset, DISPCNT_MODE_1); @@ -398,7 +383,7 @@ u16 LoadBgTiles(u8 bg, const void* src, u16 size, u16 destOffset) return -1; } - gDmaBusyBitfield[cursor / 0x20] |= (1 << (cursor % 0x20)); + sDmaBusyBitfield[cursor / 0x20] |= (1 << (cursor % 0x20)); if (gUnneededFireRedVariable == 1) { @@ -408,7 +393,7 @@ u16 LoadBgTiles(u8 bg, const void* src, u16 size, u16 destOffset) return cursor; } -u16 LoadBgTilemap(u8 bg, void *src, u16 size, u16 destOffset) +u16 LoadBgTilemap(u8 bg, const void *src, u16 size, u16 destOffset) { u8 cursor; @@ -419,19 +404,19 @@ u16 LoadBgTilemap(u8 bg, void *src, u16 size, u16 destOffset) return -1; } - gDmaBusyBitfield[cursor / 0x20] |= (1 << (cursor % 0x20)); + sDmaBusyBitfield[cursor / 0x20] |= (1 << (cursor % 0x20)); return cursor; } -u16 Unused_LoadBgPalette(u8 bg, void *src, u16 size, u16 destOffset) +u16 Unused_LoadBgPalette(u8 bg, const void *src, u16 size, u16 destOffset) { u16 paletteOffset; s8 cursor; if (IsInvalidBg32(bg) == FALSE) { - paletteOffset = (gGpuBgConfigs2[bg].basePalette * 0x20) + (destOffset * 2); + paletteOffset = (sGpuBgConfigs2[bg].basePalette * 0x20) + (destOffset * 2); cursor = RequestDma3Copy(src, (void*)(paletteOffset + BG_PLTT), size, 0); if (cursor == -1) @@ -444,7 +429,7 @@ u16 Unused_LoadBgPalette(u8 bg, void *src, u16 size, u16 destOffset) return -1; } - gDmaBusyBitfield[cursor / 0x20] |= (1 << (cursor % 0x20)); + sDmaBusyBitfield[cursor / 0x20] |= (1 << (cursor % 0x20)); return (u8)cursor; } @@ -463,7 +448,7 @@ bool8 IsDma3ManagerBusyWithBgCopy(void) div = i / 0x20; mod = i % 0x20; - if ((gDmaBusyBitfield[div] & (1 << mod)) != FALSE) + if ((sDmaBusyBitfield[div] & (1 << mod)) != FALSE) { reqSpace = CheckForSpaceForDma3Request(i); if (reqSpace == -1) @@ -471,7 +456,7 @@ bool8 IsDma3ManagerBusyWithBgCopy(void) return TRUE; } - gDmaBusyBitfield[div] &= ~(1 << mod); + sDmaBusyBitfield[div] &= ~(1 << mod); } } @@ -497,7 +482,7 @@ _08001AE4:\n\ sub r0, r5, r0\n\ lsl r0, #24\n\ lsr r0, #24\n\ - ldr r1, =gDmaBusyBitfield\n\ + ldr r1, =sDmaBusyBitfield\n\ lsr r2, #22\n\ add r4, r2, r1\n\ mov r6, #0x1\n\ @@ -603,7 +588,7 @@ u16 GetBgAttribute(u8 bg, u8 attributeId) case 9: return GetBgType(bg); case 10: - return gGpuBgConfigs2[bg].baseTile; + return sGpuBgConfigs2[bg].baseTile; default: return -1; } @@ -624,13 +609,13 @@ u32 ChangeBgX(u8 bg, u32 value, u8 op) { case 0: default: - gGpuBgConfigs2[bg].bg_x = value; + sGpuBgConfigs2[bg].bg_x = value; break; case 1: - gGpuBgConfigs2[bg].bg_x += value; + sGpuBgConfigs2[bg].bg_x += value; break; case 2: - gGpuBgConfigs2[bg].bg_x -= value; + sGpuBgConfigs2[bg].bg_x -= value; break; } @@ -639,23 +624,23 @@ u32 ChangeBgX(u8 bg, u32 value, u8 op) switch (bg) { case 0: - temp1 = gGpuBgConfigs2[0].bg_x >> 0x8; + temp1 = sGpuBgConfigs2[0].bg_x >> 0x8; SetGpuReg(REG_OFFSET_BG0HOFS, temp1); break; case 1: - temp1 = gGpuBgConfigs2[1].bg_x >> 0x8; + temp1 = sGpuBgConfigs2[1].bg_x >> 0x8; SetGpuReg(REG_OFFSET_BG1HOFS, temp1); break; case 2: if (mode == 0) { - temp1 = gGpuBgConfigs2[2].bg_x >> 0x8; + temp1 = sGpuBgConfigs2[2].bg_x >> 0x8; SetGpuReg(REG_OFFSET_BG2HOFS, temp1); } else { - temp1 = gGpuBgConfigs2[2].bg_x >> 0x10; - temp2 = gGpuBgConfigs2[2].bg_x & 0xFFFF; + temp1 = sGpuBgConfigs2[2].bg_x >> 0x10; + temp2 = sGpuBgConfigs2[2].bg_x & 0xFFFF; SetGpuReg(REG_OFFSET_BG2X_H, temp1); SetGpuReg(REG_OFFSET_BG2X_L, temp2); } @@ -663,20 +648,20 @@ u32 ChangeBgX(u8 bg, u32 value, u8 op) case 3: if (mode == 0) { - temp1 = gGpuBgConfigs2[3].bg_x >> 0x8; + temp1 = sGpuBgConfigs2[3].bg_x >> 0x8; SetGpuReg(REG_OFFSET_BG3HOFS, temp1); } else if (mode == 2) { - temp1 = gGpuBgConfigs2[3].bg_x >> 0x10; - temp2 = gGpuBgConfigs2[3].bg_x & 0xFFFF; + temp1 = sGpuBgConfigs2[3].bg_x >> 0x10; + temp2 = sGpuBgConfigs2[3].bg_x & 0xFFFF; SetGpuReg(REG_OFFSET_BG3X_H, temp1); SetGpuReg(REG_OFFSET_BG3X_L, temp2); } break; } - return gGpuBgConfigs2[bg].bg_x; + return sGpuBgConfigs2[bg].bg_x; } u32 GetBgX(u8 bg) @@ -685,7 +670,7 @@ u32 GetBgX(u8 bg) return -1; if (GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) == 0) return -1; - return gGpuBgConfigs2[bg].bg_x; + return sGpuBgConfigs2[bg].bg_x; } u32 ChangeBgY(u8 bg, u32 value, u8 op) @@ -703,13 +688,13 @@ u32 ChangeBgY(u8 bg, u32 value, u8 op) { case 0: default: - gGpuBgConfigs2[bg].bg_y = value; + sGpuBgConfigs2[bg].bg_y = value; break; case 1: - gGpuBgConfigs2[bg].bg_y += value; + sGpuBgConfigs2[bg].bg_y += value; break; case 2: - gGpuBgConfigs2[bg].bg_y -= value; + sGpuBgConfigs2[bg].bg_y -= value; break; } @@ -718,23 +703,23 @@ u32 ChangeBgY(u8 bg, u32 value, u8 op) switch (bg) { case 0: - temp1 = gGpuBgConfigs2[0].bg_y >> 0x8; + temp1 = sGpuBgConfigs2[0].bg_y >> 0x8; SetGpuReg(REG_OFFSET_BG0VOFS, temp1); break; case 1: - temp1 = gGpuBgConfigs2[1].bg_y >> 0x8; + temp1 = sGpuBgConfigs2[1].bg_y >> 0x8; SetGpuReg(REG_OFFSET_BG1VOFS, temp1); break; case 2: if (mode == 0) { - temp1 = gGpuBgConfigs2[2].bg_y >> 0x8; + temp1 = sGpuBgConfigs2[2].bg_y >> 0x8; SetGpuReg(REG_OFFSET_BG2VOFS, temp1); } else { - temp1 = gGpuBgConfigs2[2].bg_y >> 0x10; - temp2 = gGpuBgConfigs2[2].bg_y & 0xFFFF; + temp1 = sGpuBgConfigs2[2].bg_y >> 0x10; + temp2 = sGpuBgConfigs2[2].bg_y & 0xFFFF; SetGpuReg(REG_OFFSET_BG2Y_H, temp1); SetGpuReg(REG_OFFSET_BG2Y_L, temp2); } @@ -742,20 +727,20 @@ u32 ChangeBgY(u8 bg, u32 value, u8 op) case 3: if (mode == 0) { - temp1 = gGpuBgConfigs2[3].bg_y >> 0x8; + temp1 = sGpuBgConfigs2[3].bg_y >> 0x8; SetGpuReg(REG_OFFSET_BG3VOFS, temp1); } else if (mode == 2) { - temp1 = gGpuBgConfigs2[3].bg_y >> 0x10; - temp2 = gGpuBgConfigs2[3].bg_y & 0xFFFF; + temp1 = sGpuBgConfigs2[3].bg_y >> 0x10; + temp2 = sGpuBgConfigs2[3].bg_y & 0xFFFF; SetGpuReg(REG_OFFSET_BG3Y_H, temp1); SetGpuReg(REG_OFFSET_BG3Y_L, temp2); } break; } - return gGpuBgConfigs2[bg].bg_y; + return sGpuBgConfigs2[bg].bg_y; } u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) @@ -773,13 +758,13 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) { case 0: default: - gGpuBgConfigs2[bg].bg_y = value; + sGpuBgConfigs2[bg].bg_y = value; break; case 1: - gGpuBgConfigs2[bg].bg_y += value; + sGpuBgConfigs2[bg].bg_y += value; break; case 2: - gGpuBgConfigs2[bg].bg_y -= value; + sGpuBgConfigs2[bg].bg_y -= value; break; } @@ -788,24 +773,24 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) switch (bg) { case 0: - temp1 = gGpuBgConfigs2[0].bg_y >> 0x8; + temp1 = sGpuBgConfigs2[0].bg_y >> 0x8; SetGpuReg_ForcedBlank(REG_OFFSET_BG0VOFS, temp1); break; case 1: - temp1 = gGpuBgConfigs2[1].bg_y >> 0x8; + temp1 = sGpuBgConfigs2[1].bg_y >> 0x8; SetGpuReg_ForcedBlank(REG_OFFSET_BG1VOFS, temp1); break; case 2: if (mode == 0) { - temp1 = gGpuBgConfigs2[2].bg_y >> 0x8; + temp1 = sGpuBgConfigs2[2].bg_y >> 0x8; SetGpuReg_ForcedBlank(REG_OFFSET_BG2VOFS, temp1); } else { - temp1 = gGpuBgConfigs2[2].bg_y >> 0x10; - temp2 = gGpuBgConfigs2[2].bg_y & 0xFFFF; + temp1 = sGpuBgConfigs2[2].bg_y >> 0x10; + temp2 = sGpuBgConfigs2[2].bg_y & 0xFFFF; SetGpuReg_ForcedBlank(REG_OFFSET_BG2Y_H, temp1); SetGpuReg_ForcedBlank(REG_OFFSET_BG2Y_L, temp2); } @@ -813,20 +798,20 @@ u32 ChangeBgY_ScreenOff(u8 bg, u32 value, u8 op) case 3: if (mode == 0) { - temp1 = gGpuBgConfigs2[3].bg_y >> 0x8; + temp1 = sGpuBgConfigs2[3].bg_y >> 0x8; SetGpuReg_ForcedBlank(REG_OFFSET_BG3VOFS, temp1); } else if (mode == 2) { - temp1 = gGpuBgConfigs2[3].bg_y >> 0x10; - temp2 = gGpuBgConfigs2[3].bg_y & 0xFFFF; + temp1 = sGpuBgConfigs2[3].bg_y >> 0x10; + temp2 = sGpuBgConfigs2[3].bg_y & 0xFFFF; SetGpuReg_ForcedBlank(REG_OFFSET_BG3Y_H, temp1); SetGpuReg_ForcedBlank(REG_OFFSET_BG3Y_L, temp2); } break; } - return gGpuBgConfigs2[bg].bg_y; + return sGpuBgConfigs2[bg].bg_y; } u32 GetBgY(u8 bg) @@ -835,7 +820,7 @@ u32 GetBgY(u8 bg) return -1; if (GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) == 0) return -1; - return gGpuBgConfigs2[bg].bg_y; + return sGpuBgConfigs2[bg].bg_y; } void SetBgAffine(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, s16 dispCenterY, s16 scaleX, s16 scaleY, u16 rotationAngle) @@ -922,7 +907,7 @@ void SetBgTilemapBuffer(u8 bg, void *tilemap) { if (IsInvalidBg32(bg) == FALSE && GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) != 0x0) { - gGpuBgConfigs2[bg].tilemap = tilemap; + sGpuBgConfigs2[bg].tilemap = tilemap; } } @@ -930,7 +915,7 @@ void UnsetBgTilemapBuffer(u8 bg) { if (IsInvalidBg32(bg) == FALSE && GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) != 0x0) { - gGpuBgConfigs2[bg].tilemap = NULL; + sGpuBgConfigs2[bg].tilemap = NULL; } } @@ -940,7 +925,7 @@ void* GetBgTilemapBuffer(u8 bg) return NULL; if (GetBgControlAttribute(bg, BG_CTRL_ATTR_VISIBLE) == 0) return NULL; - return gGpuBgConfigs2[bg].tilemap; + return sGpuBgConfigs2[bg].tilemap; } void CopyToBgTilemapBuffer(u8 bg, const void *src, u16 mode, u16 destOffset) @@ -949,11 +934,11 @@ void CopyToBgTilemapBuffer(u8 bg, const void *src, u16 mode, u16 destOffset) { if (mode != 0) { - CpuCopy16(src, (void *)(gGpuBgConfigs2[bg].tilemap + (destOffset * 2)), mode); + CpuCopy16(src, (void *)(sGpuBgConfigs2[bg].tilemap + (destOffset * 2)), mode); } else { - LZ77UnCompWram(src, (void *)(gGpuBgConfigs2[bg].tilemap + (destOffset * 2))); + LZ77UnCompWram(src, (void *)(sGpuBgConfigs2[bg].tilemap + (destOffset * 2))); } } } @@ -976,7 +961,7 @@ void CopyBgTilemapBufferToVram(u8 bg) sizeToLoad = 0; break; } - LoadBgVram(bg, gGpuBgConfigs2[bg].tilemap, sizeToLoad, 0, 2); + LoadBgVram(bg, sGpuBgConfigs2[bg].tilemap, sizeToLoad, 0, 2); } } @@ -997,7 +982,7 @@ void CopyToBgTilemapBufferRect(u8 bg, void* src, u8 destX, u8 destY, u8 width, u { for (destX16 = destX; destX16 < (destX + width); destX16++) { - ((u16*)gGpuBgConfigs2[bg].tilemap)[((destY16 * 0x20) + destX16)] = *((u16*)srcCopy)++; + ((u16*)sGpuBgConfigs2[bg].tilemap)[((destY16 * 0x20) + destX16)] = *((u16*)srcCopy)++; } } break; @@ -1008,7 +993,7 @@ void CopyToBgTilemapBufferRect(u8 bg, void* src, u8 destX, u8 destY, u8 width, u { for (destX16 = destX; destX16 < (destX + width); destX16++) { - ((u8*)gGpuBgConfigs2[bg].tilemap)[((destY16 * mode) + destX16)] = *((u8*)srcCopy)++; + ((u8*)sGpuBgConfigs2[bg].tilemap)[((destY16 * mode) + destX16)] = *((u8*)srcCopy)++; } } break; @@ -1045,7 +1030,7 @@ void CopyRectToBgTilemapBufferRect(u8 bg, void* src, u8 srcX, u8 srcY, u8 srcWid { for (destX16 = destX; destX16 < (destX + rectWidth); destX16++) { - CopyTileMapEntry(&((u16*)srcCopy)[(srcY * rectWidth) + srcX], &((u16*)gGpuBgConfigs2[bg].tilemap)[GetTileMapIndexFromCoords(destX16, destY16, attribute, mode, mode2)], palette1, tileOffset, palette2); + CopyTileMapEntry(&((u16*)srcCopy)[(srcY * rectWidth) + srcX], &((u16*)sGpuBgConfigs2[bg].tilemap)[GetTileMapIndexFromCoords(destX16, destY16, attribute, mode, mode2)], palette1, tileOffset, palette2); } } break; @@ -1056,7 +1041,7 @@ void CopyRectToBgTilemapBufferRect(u8 bg, void* src, u8 srcX, u8 srcY, u8 srcWid { for (destX16 = destX; destX16 < (destX + rectWidth); destX16++) { - CopyTileMapEntry(&((u16*)srcCopy)[(srcY * rectWidth) + srcX], &((u16*)gGpuBgConfigs2[bg].tilemap)[GetTileMapIndexFromCoords(destX16, destY16, attribute, mode, mode2)], palette1, tileOffset, palette2); + CopyTileMapEntry(&((u16*)srcCopy)[(srcY * rectWidth) + srcX], &((u16*)sGpuBgConfigs2[bg].tilemap)[GetTileMapIndexFromCoords(destX16, destY16, attribute, mode, mode2)], palette1, tileOffset, palette2); } } break; @@ -1184,7 +1169,7 @@ _080025F8:\n\ bge _0800265A\n\ ldr r2, [sp, #0x4]\n\ lsl r0, r2, #4\n\ - ldr r1, =gGpuBgConfigs2+4\n\ + ldr r1, =sGpuBgConfigs2+4\n\ add r0, r1\n\ mov r10, r0\n\ ldr r7, [sp, #0x20]\n\ @@ -1256,7 +1241,7 @@ _08002674:\n\ sub r2, r7, r2\n\ str r2, [sp, #0x34]\n\ str r0, [sp, #0x38]\n\ - ldr r7, =gGpuBgConfigs2+4\n\ + ldr r7, =sGpuBgConfigs2+4\n\ mov r10, r7\n\ ldr r0, [sp, #0x4]\n\ lsl r0, #4\n\ @@ -1326,7 +1311,7 @@ void FillBgTilemapBufferRect_Palette0(u8 bg, u16 tileNum, u8 x, u8 y, u8 width, { for (x16 = x; x16 < (x + width); x16++) { - ((u16*)gGpuBgConfigs2[bg].tilemap)[((y16 * 0x20) + x16)] = tileNum; + ((u16*)sGpuBgConfigs2[bg].tilemap)[((y16 * 0x20) + x16)] = tileNum; } } break; @@ -1336,7 +1321,7 @@ void FillBgTilemapBufferRect_Palette0(u8 bg, u16 tileNum, u8 x, u8 y, u8 width, { for (x16 = x; x16 < (x + width); x16++) { - ((u8*)gGpuBgConfigs2[bg].tilemap)[((y16 * mode) + x16)] = tileNum; + ((u8*)sGpuBgConfigs2[bg].tilemap)[((y16 * mode) + x16)] = tileNum; } } break; @@ -1371,7 +1356,7 @@ void WriteSequenceToBgTilemapBuffer(u8 bg, u16 firstTileNum, u8 x, u8 y, u8 widt { for (x16 = x; x16 < (x + width); x16++) { - CopyTileMapEntry(&firstTileNum, &((u16*)gGpuBgConfigs2[bg].tilemap)[(u16)GetTileMapIndexFromCoords(x16, y16, attribute, mode, mode2)], paletteSlot, 0, 0); + CopyTileMapEntry(&firstTileNum, &((u16*)sGpuBgConfigs2[bg].tilemap)[(u16)GetTileMapIndexFromCoords(x16, y16, attribute, mode, mode2)], paletteSlot, 0, 0); firstTileNum = (firstTileNum & 0xFC00) + ((firstTileNum + tileNumDelta) & 0x3FF); } } @@ -1382,7 +1367,7 @@ void WriteSequenceToBgTilemapBuffer(u8 bg, u16 firstTileNum, u8 x, u8 y, u8 widt { for (x16 = x; x16 < (x + width); x16++) { - ((u8*)gGpuBgConfigs2[bg].tilemap)[(y16 * mode3) + x16] = firstTileNum; + ((u8*)sGpuBgConfigs2[bg].tilemap)[(y16 * mode3) + x16] = firstTileNum; firstTileNum = (firstTileNum & 0xFC00) + ((firstTileNum + tileNumDelta) & 0x3FF); } } @@ -1614,9 +1599,9 @@ bool32 IsInvalidBg32(u8 bg) bool32 IsTileMapOutsideWram(u8 bg) { - if (gGpuBgConfigs2[bg].tilemap > (void*)IWRAM_END) + if (sGpuBgConfigs2[bg].tilemap > (void*)IWRAM_END) return TRUE; - if (gGpuBgConfigs2[bg].tilemap == 0x0) + if (sGpuBgConfigs2[bg].tilemap == 0x0) return TRUE; return FALSE; } diff --git a/src/dma3_manager.c b/src/dma3_manager.c index 0d3cf264b..7cce06c15 100644 --- a/src/dma3_manager.c +++ b/src/dma3_manager.c @@ -91,8 +91,8 @@ void ProcessDma3Requests(void) DmaFill16(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size); break; } - gDma3Requests[gDma3RequestCursor].src = 0; - gDma3Requests[gDma3RequestCursor].dest = 0; + gDma3Requests[gDma3RequestCursor].src = NULL; + gDma3Requests[gDma3RequestCursor].dest = NULL; gDma3Requests[gDma3RequestCursor].size = 0; gDma3Requests[gDma3RequestCursor].mode = 0; gDma3Requests[gDma3RequestCursor].value = 0; diff --git a/src/egg_hatch.c b/src/egg_hatch.c index fc079444c..a84e71856 100644 --- a/src/egg_hatch.c +++ b/src/egg_hatch.c @@ -22,6 +22,7 @@ #include "bg.h" #include "m4a.h" #include "window.h" +#include "abilities.h" #include "battle.h" // to get rid of later struct EggHatchData @@ -41,23 +42,18 @@ struct EggHatchData struct TextColor textColor; }; -extern struct EggHatchData* gEggHatchData; - extern struct SpriteTemplate gUnknown_0202499C; extern void (*gFieldCallback)(void); extern const struct CompressedSpriteSheet gMonFrontPicTable[]; -extern const struct BgTemplate gUnknown_0832C064[2]; -extern const struct WindowTemplate gUnknown_0832C06C[2]; extern const u8 gUnknown_08C00000[]; extern const u8 gUnknown_08C00524[]; extern const u8 gUnknown_08C004E0[]; -extern const struct SpriteSheet gUnknown_0832BFE4; // hatching egg -extern const struct SpriteSheet gUnknown_0832BFEC; // egg shell -extern const struct SpritePalette gUnknown_0832BFF4; // hatching egg extern const u16 gUnknown_08DD7300[]; // palette, gameboy advance extern const u32 gUnknown_08DD7360[]; // tileset gameboy advance extern const u32 gUnknown_08331F60[]; // tilemap gameboy circle +extern const u8 gOtherText_HatchedFromEgg[]; +extern const u8 gOtherText_NickHatchPrompt[]; extern u8* GetMonNick(struct Pokemon* mon, u8* dst); extern u8* GetBoxMonNick(struct BoxPokemon* boxMon, u8* dst); @@ -75,9 +71,11 @@ extern void reset_temp_tile_data_buffers(void); extern void c2_exit_to_overworld_2_switch(void); extern void play_some_sound(void); extern void copy_decompressed_tile_data_to_vram_autofree(u8 bg_id, const void* src, u16 size, u16 offset, u8 mode); -extern void CreateYesNoMenu(const u8*, u16, u8, u8); +extern void CreateYesNoMenu(const struct WindowTemplate*, u16, u8, u8); extern void DoNamingScreen(u8, const u8*, u16, u8, u32, MainCallback); extern void AddTextPrinterParametrized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, struct TextColor* colors, s8 speed, u8 *str); +extern u16 sub_80D22D0(void); +extern u8 sub_80C7050(u8); static void Task_EggHatch(u8 taskID); static void CB2_EggHatch_0(void); @@ -93,6 +91,213 @@ static void EggHatchPrintMessage(u8 windowId, u8* string, u8 x, u8 y, u8 speed); 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; + +// rom data +static const u16 sEggPalette[] = INCBIN_U16("graphics/pokemon/palettes/egg_palette.gbapal"); +static const u8 sEggHatchTiles[] = INCBIN_U8("graphics/misc/egg_hatch.4bpp"); +static const u8 sEggShardTiles[] = INCBIN_U8("graphics/misc/egg_shard.4bpp"); + +static const struct OamData sOamData_EggHatch = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 2, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_EggHatch0[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_EggHatch1[] = +{ + ANIMCMD_FRAME(16, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_EggHatch2[] = +{ + ANIMCMD_FRAME(32, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_EggHatch3[] = +{ + ANIMCMD_FRAME(48, 5), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_EggHatch[] = +{ + sSpriteAnim_EggHatch0, + sSpriteAnim_EggHatch1, + sSpriteAnim_EggHatch2, + sSpriteAnim_EggHatch3, +}; + +static const struct SpriteSheet sEggHatch_Sheet = +{ + .data = sEggHatchTiles, + .size = 2048, + .tag = 12345, +}; + +static const struct SpriteSheet sEggShards_Sheet = +{ + .data = sEggShardTiles, + .size = 128, + .tag = 23456, +}; + +static const struct SpritePalette sEgg_SpritePalette = +{ + .data = sEggPalette, + .tag = 54321 +}; + +static const struct SpriteTemplate sSpriteTemplate_EggHatch = +{ + .tileTag = 12345, + .paletteTag = 54321, + .oam = &sOamData_EggHatch, + .anims = sSpriteAnimTable_EggHatch, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct OamData sOamData_EggShard = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 0, + .tileNum = 0, + .priority = 2, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_EggShard0[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_EggShard1[] = +{ + ANIMCMD_FRAME(1, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_EggShard2[] = +{ + ANIMCMD_FRAME(2, 5), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_EggShard3[] = +{ + ANIMCMD_FRAME(3, 5), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_EggShard[] = +{ + sSpriteAnim_EggShard0, + sSpriteAnim_EggShard1, + sSpriteAnim_EggShard2, + sSpriteAnim_EggShard3, +}; + +static const struct SpriteTemplate sSpriteTemplate_EggShard = +{ + .tileTag = 23456, + .paletteTag = 54321, + .oam = &sOamData_EggShard, + .anims = sSpriteAnimTable_EggShard, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_EggShard +}; + +static const struct BgTemplate sBgTemplates_EggHatch[2] = +{ + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 24, + .screenSize = 3, + .paletteMode = 0, + .priority = 0, + .baseTile = 0 + }, + + { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 8, + .screenSize = 1, + .paletteMode = 0, + .priority = 2, + .baseTile = 0 + }, +}; + +static const struct WindowTemplate sWinTemplates_EggHatch[2] = +{ + {0, 2, 0xF, 0x1A, 4, 0, 0x40}, + DUMMY_WIN_TEMPLATE +}; + +static const struct WindowTemplate sYesNoWinTemplate = +{ + 0, 0x15, 9, 5, 4, 0xF, 0x1A8 +}; + +static const s16 sEggShardVelocities[][2] = +{ + {Q_8_8(-1.5), Q_8_8(-3.75)}, + {Q_8_8(-5), Q_8_8(-3)}, + {Q_8_8(3.5), Q_8_8(-3)}, + {Q_8_8(-4), Q_8_8(-3.75)}, + {Q_8_8(2), Q_8_8(-1.5)}, + {Q_8_8(-0.5), Q_8_8(-6.75)}, + {Q_8_8(5), Q_8_8(-2.25)}, + {Q_8_8(-1.5), Q_8_8(-3.75)}, + {Q_8_8(4.5), Q_8_8(-1.5)}, + {Q_8_8(-1), Q_8_8(-6.75)}, + {Q_8_8(4), Q_8_8(-2.25)}, + {Q_8_8(-3.5), Q_8_8(-3.75)}, + {Q_8_8(1), Q_8_8(-1.5)}, + {Q_8_8(-3.515625), Q_8_8(-6.75)}, + {Q_8_8(4.5), Q_8_8(-2.25)}, + {Q_8_8(-0.5), Q_8_8(-7.5)}, + {Q_8_8(1), Q_8_8(-4.5)}, + {Q_8_8(-2.5), Q_8_8(-2.25)}, + {Q_8_8(2.5), Q_8_8(-7.5)}, +}; + +// code + static void CreatedHatchedMon(struct Pokemon *egg, struct Pokemon *temp) { u16 species; @@ -282,17 +487,17 @@ static void CB2_EggHatch_0(void) case 0: SetGpuReg(REG_OFFSET_DISPCNT, 0); - gEggHatchData = Alloc(sizeof(struct EggHatchData)); + sEggHatchData = Alloc(sizeof(struct EggHatchData)); init_uns_table_pokemon_copy(); - gEggHatchData->eggPartyID = gSpecialVar_0x8004; - gEggHatchData->eggShardVelocityID = 0; + sEggHatchData->eggPartyID = gSpecialVar_0x8004; + sEggHatchData->eggShardVelocityID = 0; SetVBlankCallback(VBlankCB_EggHatch); gSpecialVar_0x8005 = GetCurrentMapMusic(); reset_temp_tile_data_buffers(); ResetBgsAndClearDma3BusyFlags(0); - InitBgsFromTemplates(0, gUnknown_0832C064, 2); + InitBgsFromTemplates(0, sBgTemplates_EggHatch, ARRAY_COUNT(sBgTemplates_EggHatch)); ChangeBgX(1, 0, 0); ChangeBgY(1, 0, 0); @@ -313,8 +518,8 @@ static void CB2_EggHatch_0(void) gMain.state++; break; case 1: - InitWindows(gUnknown_0832C06C); - gEggHatchData->windowId = 0; + InitWindows(sWinTemplates_EggHatch); + sEggHatchData->windowId = 0; gMain.state++; break; case 2: @@ -324,22 +529,22 @@ static void CB2_EggHatch_0(void) gMain.state++; break; case 3: - LoadSpriteSheet(&gUnknown_0832BFE4); - LoadSpriteSheet(&gUnknown_0832BFEC); - LoadSpritePalette(&gUnknown_0832BFF4); + LoadSpriteSheet(&sEggHatch_Sheet); + LoadSpriteSheet(&sEggShards_Sheet); + LoadSpritePalette(&sEgg_SpritePalette); gMain.state++; break; case 4: CopyBgTilemapBufferToVram(0); - AddHatchedMonToParty(gEggHatchData->eggPartyID); + AddHatchedMonToParty(sEggHatchData->eggPartyID); gMain.state++; break; case 5: - EggHatchCreateMonSprite(0, 0, gEggHatchData->eggPartyID, &gEggHatchData->species); + EggHatchCreateMonSprite(0, 0, sEggHatchData->eggPartyID, &sEggHatchData->species); gMain.state++; break; case 6: - gEggHatchData->pokeSpriteID = EggHatchCreateMonSprite(0, 1, gEggHatchData->eggPartyID, &gEggHatchData->species); + sEggHatchData->pokeSpriteID = EggHatchCreateMonSprite(0, 1, sEggHatchData->eggPartyID, &sEggHatchData->species); gMain.state++; break; case 7: @@ -352,7 +557,7 @@ static void CB2_EggHatch_0(void) break; case 8: SetMainCallback2(CB2_EggHatch_1); - gEggHatchData->CB2_state = 0; + sEggHatchData->CB2_state = 0; break; } RunTasks(); @@ -366,7 +571,7 @@ static void EggHatchSetMonNickname(void) { SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3); sub_805F094(); - Free(gEggHatchData); + Free(sEggHatchData); SetMainCallback2(c2_exit_to_overworld_2_switch); } @@ -388,114 +593,109 @@ static void Task_EggHatchPlayBGM(u8 taskID) gTasks[taskID].data[0]++; } -extern const struct SpriteTemplate gUnknown_0832BFFC; -extern const u8 gUnknown_0832C07C[]; -extern const u8 gOtherText_HatchedFromEgg[]; -extern const u8 gOtherText_NickHatchPrompt[]; - static void CB2_EggHatch_1(void) { u16 species; u8 gender; u32 personality; - switch (gEggHatchData->CB2_state) + switch (sEggHatchData->CB2_state) { case 0: BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); - gEggHatchData->eggSpriteID = CreateSprite(&gUnknown_0832BFFC, 120, 75, 5); + sEggHatchData->eggSpriteID = CreateSprite(&sSpriteTemplate_EggHatch, 120, 75, 5); ShowBg(0); ShowBg(1); - gEggHatchData->CB2_state++; + sEggHatchData->CB2_state++; CreateTask(Task_EggHatchPlayBGM, 5); break; case 1: if (!gPaletteFade.active) { - FillWindowPixelBuffer(gEggHatchData->windowId, 0); - gEggHatchData->CB2_PalCounter = 0; - gEggHatchData->CB2_state++; + FillWindowPixelBuffer(sEggHatchData->windowId, 0); + sEggHatchData->CB2_PalCounter = 0; + sEggHatchData->CB2_state++; } break; case 2: - if (++gEggHatchData->CB2_PalCounter > 30) + if (++sEggHatchData->CB2_PalCounter > 30) { - gEggHatchData->CB2_state++; - gSprites[gEggHatchData->eggSpriteID].callback = SpriteCB_Egg_0; + sEggHatchData->CB2_state++; + gSprites[sEggHatchData->eggSpriteID].callback = SpriteCB_Egg_0; } break; case 3: - if (gSprites[gEggHatchData->eggSpriteID].callback == SpriteCallbackDummy) + if (gSprites[sEggHatchData->eggSpriteID].callback == SpriteCallbackDummy) { - species = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_SPECIES); - DoMonFrontSpriteAnimation(&gSprites[gEggHatchData->pokeSpriteID], species, FALSE, 1); - gEggHatchData->CB2_state++; + species = GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_SPECIES); + DoMonFrontSpriteAnimation(&gSprites[sEggHatchData->pokeSpriteID], species, FALSE, 1); + sEggHatchData->CB2_state++; } break; case 4: - if (gSprites[gEggHatchData->pokeSpriteID].callback == SpriteCallbackDummy) + if (gSprites[sEggHatchData->pokeSpriteID].callback == SpriteCallbackDummy) { - gEggHatchData->CB2_state++; + sEggHatchData->CB2_state++; } break; case 5: - GetMonNick(&gPlayerParty[gEggHatchData->eggPartyID], gStringVar1); + GetMonNick(&gPlayerParty[sEggHatchData->eggPartyID], gStringVar1); StringExpandPlaceholders(gStringVar4, gOtherText_HatchedFromEgg); - EggHatchPrintMessage(gEggHatchData->windowId, gStringVar4, 0, 3, 0xFF); + EggHatchPrintMessage(sEggHatchData->windowId, gStringVar4, 0, 3, 0xFF); PlayFanfare(371); - gEggHatchData->CB2_state++; - PutWindowTilemap(gEggHatchData->windowId); - CopyWindowToVram(gEggHatchData->windowId, 3); + sEggHatchData->CB2_state++; + PutWindowTilemap(sEggHatchData->windowId); + CopyWindowToVram(sEggHatchData->windowId, 3); break; case 6: if (IsFanfareTaskInactive()) - gEggHatchData->CB2_state++; + sEggHatchData->CB2_state++; break; case 7: if (IsFanfareTaskInactive()) - gEggHatchData->CB2_state++; + sEggHatchData->CB2_state++; break; case 8: - GetMonNick(&gPlayerParty[gEggHatchData->eggPartyID], gStringVar1); + GetMonNick(&gPlayerParty[sEggHatchData->eggPartyID], gStringVar1); StringExpandPlaceholders(gStringVar4, gOtherText_NickHatchPrompt); - EggHatchPrintMessage(gEggHatchData->windowId, gStringVar4, 0, 2, 1); - gEggHatchData->CB2_state++; + EggHatchPrintMessage(sEggHatchData->windowId, gStringVar4, 0, 2, 1); + sEggHatchData->CB2_state++; break; case 9: - if (!IsTextPrinterActive(gEggHatchData->windowId)) + if (!IsTextPrinterActive(sEggHatchData->windowId)) { - sub_809882C(gEggHatchData->windowId, 0x140, 0xE0); - CreateYesNoMenu(gUnknown_0832C07C, 0x140, 0xE, 0); - gEggHatchData->CB2_state++; + sub_809882C(sEggHatchData->windowId, 0x140, 0xE0); + CreateYesNoMenu(&sYesNoWinTemplate, 0x140, 0xE, 0); + sEggHatchData->CB2_state++; } break; case 10: switch (sub_8198C58()) { case 0: - GetMonNick(&gPlayerParty[gEggHatchData->eggPartyID], gStringVar3); - species = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_SPECIES); - gender = GetMonGender(&gPlayerParty[gEggHatchData->eggPartyID]); - personality = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_PERSONALITY, 0); + GetMonNick(&gPlayerParty[sEggHatchData->eggPartyID], gStringVar3); + species = GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_SPECIES); + gender = GetMonGender(&gPlayerParty[sEggHatchData->eggPartyID]); + personality = GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_PERSONALITY, 0); DoNamingScreen(3, gStringVar3, species, gender, personality, EggHatchSetMonNickname); break; case 1: case -1: - gEggHatchData->CB2_state++; + sEggHatchData->CB2_state++; } break; case 11: BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); - gEggHatchData->CB2_state++; + sEggHatchData->CB2_state++; break; case 12: if (!gPaletteFade.active) { sub_805F094(); - RemoveWindow(gEggHatchData->windowId); + RemoveWindow(sEggHatchData->windowId); UnsetBgTilemapBuffer(0); UnsetBgTilemapBuffer(1); - Free(gEggHatchData); + Free(sEggHatchData); SetMainCallback2(c2_exit_to_overworld_2_switch); } break; @@ -561,9 +761,9 @@ static void SpriteCB_Egg_2(struct Sprite* sprite) sprite->callback = SpriteCB_Egg_3; sprite->data0 = 0; - species = GetMonData(&gPlayerParty[gEggHatchData->eggPartyID], MON_DATA_SPECIES); - gSprites[gEggHatchData->pokeSpriteID].pos2.x = 0; - gSprites[gEggHatchData->pokeSpriteID].pos2.y = 0; + species = GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_SPECIES); + gSprites[sEggHatchData->pokeSpriteID].pos2.x = 0; + gSprites[sEggHatchData->pokeSpriteID].pos2.y = 0; } else { @@ -615,13 +815,13 @@ static void SpriteCB_Egg_5(struct Sprite* sprite) { if (sprite->data0 == 0) { - gSprites[gEggHatchData->pokeSpriteID].invisible = 0; - StartSpriteAffineAnim(&gSprites[gEggHatchData->pokeSpriteID], 1); + gSprites[sEggHatchData->pokeSpriteID].invisible = 0; + StartSpriteAffineAnim(&gSprites[sEggHatchData->pokeSpriteID], 1); } if (sprite->data0 == 8) BeginNormalPaletteFade(-1, -1, 0x10, 0, 0xFFFF); if (sprite->data0 <= 9) - gSprites[gEggHatchData->pokeSpriteID].pos1.y -= 1; + gSprites[sEggHatchData->pokeSpriteID].pos1.y -= 1; if (sprite->data0 > 40) sprite->callback = SpriteCallbackDummy; sprite->data0++; @@ -641,24 +841,20 @@ static void SpriteCB_EggShard(struct Sprite* sprite) DestroySprite(sprite); } -extern const s16 sEggShardVelocities[][2]; - static void CreateRandomEggShardSprite(void) { u16 spriteAnimIndex; - s16 velocity1 = sEggShardVelocities[gEggHatchData->eggShardVelocityID][0]; - s16 velocity2 = sEggShardVelocities[gEggHatchData->eggShardVelocityID][1]; - gEggHatchData->eggShardVelocityID++; + s16 velocity1 = sEggShardVelocities[sEggHatchData->eggShardVelocityID][0]; + s16 velocity2 = sEggShardVelocities[sEggHatchData->eggShardVelocityID][1]; + sEggHatchData->eggShardVelocityID++; spriteAnimIndex = Random() % 4; CreateEggShardSprite(120, 60, velocity1, velocity2, 100, spriteAnimIndex); } -extern const struct SpriteTemplate gUnknown_0832C04C; - static void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 spriteAnimIndex) { - u8 spriteID = CreateSprite(&gUnknown_0832C04C, x, y, 4); + u8 spriteID = CreateSprite(&sSpriteTemplate_EggShard, x, y, 4); gSprites[spriteID].data1 = data1; gSprites[spriteID].data2 = data2; gSprites[spriteID].data3 = data3; @@ -668,8 +864,30 @@ static void CreateEggShardSprite(u8 x, u8 y, s16 data1, s16 data2, s16 data3, u8 static void EggHatchPrintMessage(u8 windowId, u8* string, u8 x, u8 y, u8 speed) { FillWindowPixelBuffer(windowId, 0xFF); - gEggHatchData->textColor.fgColor = 0; - gEggHatchData->textColor.bgColor = 5; - gEggHatchData->textColor.shadowColor = 6; - AddTextPrinterParametrized2(windowId, 1, x, y, 0, 0, &gEggHatchData->textColor, speed, string); + sEggHatchData->textColor.fgColor = 0; + sEggHatchData->textColor.bgColor = 5; + sEggHatchData->textColor.shadowColor = 6; + AddTextPrinterParametrized2(windowId, 1, x, y, 0, 0, &sEggHatchData->textColor, speed, string); +} + +u8 GetEggStepsToSubtract(void) +{ + u8 count, i; + for (count = CalculatePlayerPartyCount(), i = 0; i < count; i++) + { + if (!GetMonData(&gPlayerParty[i], MON_DATA_SANITY_BIT3)) + { + u8 ability = GetMonAbility(&gPlayerParty[i]); + if (ability == ABILITY_MAGMA_ARMOR || ability == ABILITY_FLAME_BODY) + return 2; + } + } + return 1; +} + +u16 sub_80722E0(void) +{ + u16 value = sub_80D22D0(); + value += sub_80C7050(6); + return value; } diff --git a/src/gpu_regs.c b/src/gpu_regs.c index be1f153d4..805f23b48 100644 --- a/src/gpu_regs.c +++ b/src/gpu_regs.c @@ -1,4 +1,5 @@ #include "global.h" +#include "gpu_regs.h" #define GPU_REG_BUF_SIZE 0x60 @@ -14,14 +15,15 @@ static bool8 sShouldSyncRegIE; static u16 sRegIE; static void CopyBufferedValueToGpuReg(u8 regOffset); -static void SyncRegIE(); +static void SyncRegIE(void); static void UpdateRegDispstatIntrBits(u16 regIE); -void InitGpuRegManager() +void InitGpuRegManager(void) { s32 i; - for (i = 0; i < GPU_REG_BUF_SIZE; i++) { + for (i = 0; i < GPU_REG_BUF_SIZE; i++) + { sGpuRegBuffer[i] = 0; sGpuRegWaitingList[i] = EMPTY_SLOT; } @@ -33,20 +35,25 @@ void InitGpuRegManager() static void CopyBufferedValueToGpuReg(u8 regOffset) { - if (regOffset == REG_OFFSET_DISPSTAT) { + if (regOffset == REG_OFFSET_DISPSTAT) + { REG_DISPSTAT &= ~(DISPSTAT_HBLANK_INTR | DISPSTAT_VBLANK_INTR); REG_DISPSTAT |= GPU_REG_BUF(REG_OFFSET_DISPSTAT); - } else { + } + else + { GPU_REG(regOffset) = GPU_REG_BUF(regOffset); } } -void CopyBufferedValuesToGpuRegs() +void CopyBufferedValuesToGpuRegs(void) { - if (!sGpuRegBufferLocked) { + if (!sGpuRegBufferLocked) + { s32 i; - for (i = 0; i < GPU_REG_BUF_SIZE; i++) { + for (i = 0; i < GPU_REG_BUF_SIZE; i++) + { u8 regOffset = sGpuRegWaitingList[i]; if (regOffset == EMPTY_SLOT) return; @@ -135,7 +142,7 @@ void ClearGpuRegBits(u8 regOffset, u16 mask) SetGpuReg(regOffset, regValue & ~mask); } -static void SyncRegIE() +static void SyncRegIE(void) { if (sShouldSyncRegIE) { u16 temp = REG_IME; diff --git a/src/trig.c b/src/trig.c index e16a69e63..93cf06893 100644 --- a/src/trig.c +++ b/src/trig.c @@ -1,9 +1,6 @@ #include "global.h" #include "trig.h" -// Converts a number to Q8.8 fixed-point format -#define Q_8_8(n) ((s16)((n) * 256)) - // Converts a number to Q4.12 fixed-point format #define Q_4_12(n) ((s16)((n) * 4096)) -- cgit v1.2.3 From b2b6774efc5d6cd1bf9ca7f9c1c925dfd237428c Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 08:32:49 -0400 Subject: sub_818D6CC --- src/battle_dome_cards.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index b8f0c4ff8..4b2e9f41c 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -60,7 +60,7 @@ bool16 dp13_810BB8C(void) return FALSE; } -bool16 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, void *dest, bool8 isTrainer, bool8 ignoreDeoxys) +bool16 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, u8 *dest, bool8 isTrainer, bool8 ignoreDeoxys) { if (!isTrainer) { @@ -101,7 +101,7 @@ bool16 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, v return FALSE; } -bool16 sub_818D09C(u16 species, u32 personality, bool8 isFrontPic, void *dest, bool8 isTrainer) +bool16 sub_818D09C(u16 species, u32 personality, bool8 isFrontPic, u8 *dest, bool8 isTrainer) { return load_pokemon_image_TODO(species, personality, isFrontPic, dest, isTrainer, FALSE); } @@ -340,10 +340,25 @@ u16 sub_818D5B0(u16 spriteId) u16 sub_818D65C(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer) { - if (sub_818D09C(species, personality, isFrontPic, (void *)GetWindowAttribute(windowId, WINDOW_TILE_DATA), FALSE)) + if (sub_818D09C(species, personality, isFrontPic, (u8 *)GetWindowAttribute(windowId, WINDOW_TILE_DATA), FALSE)) { return 0xFFFF; } sub_818D180(species, otId, personality, paletteSlot, isTrainer); return 0; } + +u16 sub_818D6CC(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId, bool8 isTrainer) +{ + u8 *framePics; + + framePics = Alloc(4 * 0x800); + if (framePics && !sub_818D09C(species, personality, isFrontPic, framePics, isTrainer)) + { + BlitBitmapRectToWindow(windowId, framePics, 0, 0, 0x40, 0x40, destX, destY, 0x40, 0x40); + sub_818D180(species, otId, personality, paletteSlot, isTrainer); + Free(framePics); + return 0; + } + return 0xFFFF; +} -- cgit v1.2.3 From 8634f722905247646305824afd62ebec60810212 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 08:35:27 -0400 Subject: sub_818D778 --- src/battle_dome_cards.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 4b2e9f41c..1e6a98810 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -362,3 +362,8 @@ u16 sub_818D6CC(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 de } return 0xFFFF; } + +u16 sub_818D778(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 ignoreDeoxys) +{ + return oamt_spawn_poke_or_trainer_picture(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE, ignoreDeoxys); +} -- cgit v1.2.3 From 057894f3c583f99b4c626181fc86cfc0744c2ea1 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 08:36:45 -0400 Subject: sub_818D7D8 --- src/battle_dome_cards.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 1e6a98810..7df33e403 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -367,3 +367,8 @@ u16 sub_818D778(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, { return oamt_spawn_poke_or_trainer_picture(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE, ignoreDeoxys); } + +u16 sub_818D7D8(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag) +{ + return sub_818D778(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE); +} -- cgit v1.2.3 From 63ff09e806b2f8bd38e50fec7aa7d63367060df4 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 08:53:31 -0400 Subject: Nearly finished with battle_dome_cards --- src/battle_dome_cards.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 7df33e403..280eac163 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -20,6 +20,7 @@ extern const union AnimCmd *const *const gUnknown_08309AAC[NUM_SPECIES]; extern const union AnimCmd *const *const gUnknown_0830536C[]; extern const struct OamData gUnknown_0860B064; extern const struct OamData gUnknown_0860B06C; +extern const u8 gUnknown_0831F578[]; // Static type declarations @@ -372,3 +373,52 @@ u16 sub_818D7D8(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, { return sub_818D778(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE); } + +u16 sub_818D820(u16 spriteId) +{ + return sub_818D5B0(spriteId); +} + +u16 sub_818D834(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId) +{ + return sub_818D65C(species, otId, personality, isFrontPic, paletteSlot, windowId, FALSE); +} + +u16 sub_818D864(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId) +{ + return sub_818D6CC(species, otId, personality, isFrontPic, destX, destY, paletteSlot, windowId, FALSE); +} + +u16 sub_818D8AC(u16 species, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag) +{ + return sub_818D384(species, 0, 0, isFrontPic, x, y, paletteSlot, paletteTag, TRUE); +} + +u16 sub_818D8F0(u16 spriteId) +{ + return sub_818D5B0(spriteId); +} + +u16 sub_818D904(u16 species, bool8 isFrontPic, u8 paletteSlot, u8 windowId) +{ + return sub_818D65C(species, 0, 0, isFrontPic, paletteSlot, windowId, TRUE); +} + +u16 sub_818D938(u16 species, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId) +{ + return sub_818D6CC(species, 0, 0, isFrontPic, destX, destY, paletteSlot, windowId, TRUE); +} + +//u8 sub_818D97C(u8 a0, u8 a1) +//{ +// u8 id; +// if (a1 == 1 && a0) +// { +// id = gUnknown_0831F578[0x3F]; +// } +// else +// { +// id = gUnknown_0831F578[0x3C]; +// } +// return id; +//} -- cgit v1.2.3 From bff89725ec31f87c296ec45f107f81dfe3cd54d6 Mon Sep 17 00:00:00 2001 From: scnorton Date: Tue, 19 Sep 2017 09:46:17 -0400 Subject: Add battle_dome_cards header to expose symbols as needed --- src/battle_dome_cards.c | 64 +++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 280eac163..c0557ac70 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -7,6 +7,7 @@ #include "species.h" #include "palette.h" #include "decompress.h" +#include "battle_dome_cards.h" extern const struct CompressedSpriteSheet gMonFrontPicTable[NUM_SPECIES]; extern const struct CompressedSpriteSheet gMonBackPicTable[NUM_SPECIES]; @@ -18,8 +19,6 @@ extern const union AffineAnimCmd *const gUnknown_082FF694[]; extern const union AnimCmd *const gUnknown_082FF70C[]; extern const union AnimCmd *const *const gUnknown_08309AAC[NUM_SPECIES]; extern const union AnimCmd *const *const gUnknown_0830536C[]; -extern const struct OamData gUnknown_0860B064; -extern const struct OamData gUnknown_0860B06C; extern const u8 gUnknown_0831F578[]; // Static type declarations @@ -35,17 +34,23 @@ struct BattleDomeCard { // Static RAM declarations static EWRAM_DATA struct SpriteTemplate gUnknown_0203CCEC = {}; -EWRAM_DATA struct BattleDomeCard gUnknown_0203CD04[8] = {}; +static EWRAM_DATA struct BattleDomeCard gUnknown_0203CD04[8] = {}; // Static ROM declarations // .rodata -extern const struct BattleDomeCard gUnknown_0860B058; +static const struct BattleDomeCard gUnknown_0860B058 = {}; +static const struct OamData gUnknown_0860B064 = { + .size = 3 +}; +static const struct OamData gUnknown_0860B06C = { + .affineMode = 1, .size = 3 +}; // .text -void nullsub_122(struct Sprite *sprite) +static void nullsub_122(struct Sprite *sprite) { } @@ -61,7 +66,7 @@ bool16 dp13_810BB8C(void) return FALSE; } -bool16 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, u8 *dest, bool8 isTrainer, bool8 ignoreDeoxys) +static bool16 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, u8 *dest, bool8 isTrainer, bool8 ignoreDeoxys) { if (!isTrainer) { @@ -102,12 +107,12 @@ bool16 load_pokemon_image_TODO(u16 species, u32 personality, bool8 isFrontPic, u return FALSE; } -bool16 sub_818D09C(u16 species, u32 personality, bool8 isFrontPic, u8 *dest, bool8 isTrainer) +static bool16 sub_818D09C(u16 species, u32 personality, bool8 isFrontPic, u8 *dest, bool8 isTrainer) { return load_pokemon_image_TODO(species, personality, isFrontPic, dest, isTrainer, FALSE); } -void sub_818D0C4(u16 species, u32 otId, u32 personality, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) +static void sub_818D0C4(u16 species, u32 otId, u32 personality, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) { if (!isTrainer) { @@ -137,7 +142,7 @@ void sub_818D0C4(u16 species, u32 otId, u32 personality, u8 paletteSlot, u16 pal } } -void sub_818D180(u16 species, u32 otId, u32 personality, u8 paletteSlot, bool8 isTrainer) +static void sub_818D180(u16 species, u32 otId, u32 personality, u8 paletteSlot, bool8 isTrainer) { if (!isTrainer) { @@ -149,7 +154,7 @@ void sub_818D180(u16 species, u32 otId, u32 personality, u8 paletteSlot, bool8 i } } -void uns_builder_assign_animtable1(bool8 isTrainer) +static void uns_builder_assign_animtable1(bool8 isTrainer) { if (!isTrainer) { @@ -161,7 +166,7 @@ void uns_builder_assign_animtable1(bool8 isTrainer) } } -u16 oamt_spawn_poke_or_trainer_picture(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer, bool8 ignoreDeoxys) +static u16 oamt_spawn_poke_or_trainer_picture(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer, bool8 ignoreDeoxys) { u8 i; u8 *framePics; @@ -221,7 +226,7 @@ u16 oamt_spawn_poke_or_trainer_picture(u16 species, u32 otId, u32 personality, b return spriteId; } -u16 sub_818D384(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) +static u16 sub_818D384(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) { return oamt_spawn_poke_or_trainer_picture(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, isTrainer, FALSE); } @@ -309,7 +314,7 @@ u16 sub_818D3E4(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, return spriteId; } -u16 sub_818D5B0(u16 spriteId) +static u16 sub_818D5B0(u16 spriteId) { u8 i; u8 *framePics; @@ -339,7 +344,7 @@ u16 sub_818D5B0(u16 spriteId) return 0; } -u16 sub_818D65C(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer) +static u16 sub_818D65C(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer) { if (sub_818D09C(species, personality, isFrontPic, (u8 *)GetWindowAttribute(windowId, WINDOW_TILE_DATA), FALSE)) { @@ -349,7 +354,7 @@ u16 sub_818D65C(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 pal return 0; } -u16 sub_818D6CC(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId, bool8 isTrainer) +static u16 sub_818D6CC(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId, bool8 isTrainer) { u8 *framePics; @@ -364,7 +369,7 @@ u16 sub_818D6CC(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 de return 0xFFFF; } -u16 sub_818D778(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 ignoreDeoxys) +static u16 sub_818D778(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 ignoreDeoxys) { return oamt_spawn_poke_or_trainer_picture(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE, ignoreDeoxys); } @@ -409,16 +414,17 @@ u16 sub_818D938(u16 species, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteS return sub_818D6CC(species, 0, 0, isFrontPic, destX, destY, paletteSlot, windowId, TRUE); } -//u8 sub_818D97C(u8 a0, u8 a1) -//{ -// u8 id; -// if (a1 == 1 && a0) -// { -// id = gUnknown_0831F578[0x3F]; -// } -// else -// { -// id = gUnknown_0831F578[0x3C]; -// } -// return id; -//} +u8 sub_818D97C(u8 a0, u8 a1) +{ + if (a1 == 1) + { + switch (a0) + { + default: + return gUnknown_0831F578[0x3F]; + case 0: + return gUnknown_0831F578[0x3C]; + } + } + return a0; +} -- cgit v1.2.3 From b3c788f2ca9e3d0ab6e43617ed7fedfe605bc249 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Tue, 19 Sep 2017 21:01:12 +0200 Subject: begin work on battle4, organize battle headers --- src/battle_3.c | 27 ++-- src/battle_4.c | 423 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 431 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index a2ddd1c2d..283305d6c 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -15,6 +15,7 @@ #include "battle_message.h" #include "battle_ai.h" #include "event_data.h" +#include "calculate_base_damage.h" extern const u8* gBattlescriptCurrInstr; extern const u8* gUnknown_02024220[BATTLE_BANKS_COUNT]; @@ -187,11 +188,8 @@ extern void SetMoveEffect(bool8 primary, u8 certainArg); extern bool8 UproarWakeUpCheck(u8 bank); extern void MarkBufferBankForExecution(u8 bank); extern u8 sub_803F90C(u8 bank); -extern u8 GetBankIdentity(u8); extern void sub_803F9EC(); extern bool8 sub_80423F4(u8 bank, u8, u8); -extern s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideFlags, u16 powerOverride, u8 typeOverride, u8 bankAtk, u8 bankDef); -extern u8 GetBankByPlayerAI(u8); extern u8 sub_806D864(u8); extern u8 sub_806D82C(u8); extern u8 weather_get_current(void); @@ -199,11 +197,6 @@ extern void sub_803E08C(void); extern void bc_move_exec_returning(void); extern s8 GetFlavourRelationByPersonality(u32 personality, u8 flavor); -u8 IsImprisoned(u8 bank, u16 move); -u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn); -u8 GetMoveTarget(u16 move, u8 useMoveTarget); -void b_push_move_exec(const u8* BS_ptr); - void b_movescr_stack_push(const u8* bsPtr) { BATTLESCRIPTS_STACK->ptr[BATTLESCRIPTS_STACK->size++] = bsPtr; @@ -6237,7 +6230,7 @@ u8 GetMoveTarget(u16 move, u8 useMoveTarget) switch (moveTarget) { - case 0: + case MOVE_TARGET_SELECTED: side = GetBankSide(gBankAttacker) ^ 1; if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp) targetBank = gSideTimers[side].followmeTarget; @@ -6258,19 +6251,19 @@ u8 GetMoveTarget(u16 move, u8 useMoveTarget) } } break; - case 1: - case 8: - case 32: - case 64: + case MOVE_TARGET_DEPENDS: + case MOVE_TARGET_BOTH: + case MOVE_TARGET_FOES_AND_ALLY: + case MOVE_TARGET_OPPONENTS_FIELD: targetBank = GetBankByPlayerAI((GetBankIdentity(gBankAttacker) & 1) ^ 1); if (gAbsentBankFlags & gBitTable[targetBank]) targetBank ^= 2; break; - case 4: + case MOVE_TARGET_RANDOM: side = GetBankSide(gBankAttacker) ^ 1; if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp) targetBank = gSideTimers[side].followmeTarget; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & 4) + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & MOVE_TARGET_RANDOM) { if (GetBankSide(gBankAttacker) == SIDE_PLAYER) { @@ -6292,8 +6285,8 @@ u8 GetMoveTarget(u16 move, u8 useMoveTarget) else targetBank = GetBankByPlayerAI((GetBankIdentity(gBankAttacker) & 1) ^ 1); break; - case 2: - case 16: + case MOVE_TARGET_USER: + case MOVE_TARGET_x10: targetBank = gBankAttacker; break; } diff --git a/src/battle_4.c b/src/battle_4.c index 92561251f..e693162cc 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -1,11 +1,141 @@ #include "global.h" #include "battle.h" #include "battle_move_effects.h" +#include "battle_message.h" +#include "battle_ai.h" #include "moves.h" #include "abilities.h" #include "item.h" #include "items.h" #include "hold_effects.h" +#include "util.h" +#include "pokemon.h" +#include "calculate_base_damage.h" +#include "rng.h" + +// variables + +extern u8 gCritMultiplier; +extern s32 gBattleMoveDamage; +extern u32 gStatuses3[BATTLE_BANKS_COUNT]; +extern u32 gBattleTypeFlags; +extern struct BattleEnigmaBerry gEnigmaBerries[BATTLE_BANKS_COUNT]; +extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT]; +extern u8 gActiveBank; +extern u32 gBattleExecBuffer; +extern u8 gNoOfAllBanks; +extern u16 gBattlePartyID[BATTLE_BANKS_COUNT]; +extern u8 gTurnOrder[BATTLE_BANKS_COUNT]; +extern u8 gUnknown_02024A76[BATTLE_BANKS_COUNT]; +extern u16 gCurrentMove; +extern u8 gLastUsedAbility; +extern u16 gBattleWeather; +extern u8 gStringBank; +extern u8 gEffectBank; +extern u8 gAbsentBankFlags; +extern u8 gMultiHitCounter; +extern u16 gChosenMovesByBanks[BATTLE_BANKS_COUNT]; +extern u16 gSideAffecting[2]; +extern u16 gPauseCounterBattle; +extern u16 gPaydayMoney; +extern u16 gRandomTurnNumber; +extern u8 gBattleOutcome; +extern u8 gBattleTerrain; +extern u16 gTrainerBattleOpponent; +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern const u8* gBattlescriptCurrInstr; +extern u8 gCurrMovePos; +extern u8 gFightStateTracker; +extern u32 gHitMarker; +extern u8 gBattleMoveFlags; +extern u8 gBattleCommunication[]; +extern u16 gUnknown_02024250[4]; +extern u16 gUnknown_02024258[4]; +extern u8 gStringBank; +extern u16 gDynamicBasePower; +extern u16 gLastUsedItem; +extern u16 gBattleMovePower; +extern s32 gHP_dealt; +extern s32 gTakenDmg[BATTLE_BANKS_COUNT]; +extern u8 gTakenDmgBanks[BATTLE_BANKS_COUNT]; +extern u8 gSentPokesToOpponent[2]; +extern u8 gBank1; +extern u16 gExpShareExp; +extern u8 gLeveledUpInBattle; +extern void (*gBattleMainFunc)(void); +extern u8 gPlayerPartyCount; +extern u16 gMoveToLearn; +extern u16 gRandomMove; +extern u8 gBankInMenu; +extern u8 gActionForBanks[4]; +extern u8 gCurrentMoveTurn; +extern u8 gBattleBufferB[4][0x200]; + +extern const struct BattleMove gBattleMoves[]; +extern const u16 gMissStrings[]; +extern const u8 gTrainerMoney[]; +extern const u8 gTypeEffectiveness[]; +extern const struct BaseStats gBaseStats[]; + +// functions + + +// BattleScripts +extern const u8 BattleScript_MoveEnd[]; +extern const u8 BattleScript_NoPPForMove[]; +extern const u8 BattleScript_MagicCoatBounce[]; +extern const u8 BattleScript_TookAttack[]; +extern const u8 BattleScript_SnatchedMove[]; +extern const u8 BattleScript_Pausex20[]; +extern const u8 BattleScript_SubstituteFade[]; +extern const u8 BattleScript_HangedOnMsg[]; +extern const u8 BattleScript_OneHitKOMsg[]; +extern const u8 BattleScript_EnduredMsg[]; +extern const u8 BattleScript_PSNPrevention[]; +extern const u8 BattleScript_BRNPrevention[]; +extern const u8 BattleScript_PRLZPrevention[]; +extern const u8 BattleScript_FlinchPrevention[]; +extern const u8 BattleScript_StatUp[]; +extern const u8 BattleScript_StatDown[]; +extern const u8 BattleScript_NoItemSteal[]; +extern const u8 BattleScript_ItemSteal[]; +extern const u8 BattleScript_RapidSpinAway[]; +extern const u8 BattleScript_TargetPRLZHeal[]; +extern const u8 BattleScript_KnockedOff[]; +extern const u8 BattleScript_LevelUp[]; +extern const u8 BattleScript_WrapFree[]; +extern const u8 BattleScript_LeechSeedFree[]; +extern const u8 BattleScript_SpikesFree[]; +extern const u8 BattleScript_ButItFailed[]; +extern const u8 BattleScript_ObliviousPreventsAttraction[]; +extern const u8 BattleScript_MistProtected[]; +extern const u8 BattleScript_AbilityNoStatLoss[]; +extern const u8 BattleScript_AbilityNoSpecificStatLoss[]; +extern const u8 BattleScript_TrainerBallBlock[]; +extern const u8 BattleScript_WallyBallThrow[]; +extern const u8 BattleScript_SuccessBallThrow[]; +extern const u8 BattleScript_ShakeBallThrow[]; + +// read via orr +#define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) +#define BSScriptRead8(ptr) (((u8)((ptr)[0]))) +#define BSScriptReadPtr(ptr) ((void *)BSScriptRead32(ptr)) + +// read via add +#define BS2ScriptRead32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24)) +#define BS2ScriptRead16(ptr) ((ptr)[0] + ((ptr)[1] << 8)) +#define BS2ScriptReadPtr(ptr) ((void *)BS2ScriptRead32(ptr)) + +#define TARGET_PROTECT_AFFECTED ((gProtectStructs[gBankTarget].protected && gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED)) + +#define TARGET_TURN_DAMAGED (((gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_physical.moveturnLostHP_special))) + +// this file's functions +bool8 IsTwoTurnsMove(u16 move); +void DestinyBondFlagUpdate(void); +u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. +void b_wonderguard_and_levitate(void); void atk00_attackcanceler(void); void atk01_accuracycheck(void); @@ -510,13 +640,13 @@ void (* const gBattleScriptingCommandsTable[])(void) = sub_8056EF8 }; -struct statFractions +struct StatFractions { u8 dividend; u8 divisor; }; -const struct statFractions gAccuracyStageRatios[] = +const struct StatFractions gAccuracyStageRatios[] = { { 33, 100}, // -6 { 36, 100}, // -5 @@ -599,3 +729,292 @@ const u32 gStatusFlagsForMoveEffects[] = 0x00000000, 0x00000000 }; + +void atk00_attackcanceler(void) +{ + s32 i; + + if (gBattleOutcome) + { + gFightStateTracker = 0xC; + return; + } + if (gBattleMons[gBankAttacker].hp == 0 && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) + { + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gBattlescriptCurrInstr = BattleScript_MoveEnd; + return; + } + if (AtkCanceller_UnableToUseMove()) + return; + if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBankTarget, 0, 0, 0)) + return; + if (!gBattleMons[gBankAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE && !(gHitMarker & 0x800200) + && !(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) + { + gBattlescriptCurrInstr = BattleScript_NoPPForMove; + gBattleMoveFlags |= MOVESTATUS_MISSED; + return; + } + + gHitMarker &= ~(HITMARKER_x800000); + + if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) + { + i = IsPokeDisobedient(); // why use the 'i' variable...? + switch (i) + { + case 0: + break; + case 2: + gHitMarker |= HITMARKER_OBEYS; + return; + default: + gBattleMoveFlags |= MOVESTATUS_MISSED; + return; + } + } + + gHitMarker |= HITMARKER_OBEYS; + + if (gProtectStructs[gBankTarget].bounceMove && gBattleMoves[gCurrentMove].flags & FLAG_MAGICCOAT_AFFECTED) + { + PressurePPLose(gBankAttacker, gBankTarget, MOVE_MAGIC_COAT); + gProtectStructs[gBankTarget].bounceMove = 0; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_MagicCoatBounce; + return; + } + + for (i = 0; i < gNoOfAllBanks; i++) + { + if ((gProtectStructs[gTurnOrder[i]].stealMove) && gBattleMoves[gCurrentMove].flags & FLAG_SNATCH_AFFECTED) + { + PressurePPLose(gBankAttacker, gTurnOrder[i], MOVE_SNATCH); + gProtectStructs[gTurnOrder[i]].stealMove = 0; + gBattleScripting.bank = gTurnOrder[i]; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_SnatchedMove; + return; + } + } + + if (gSpecialStatuses[gBankTarget].lightningRodRedirected) + { + gSpecialStatuses[gBankTarget].lightningRodRedirected = 0; + gLastUsedAbility = ABILITY_LIGHTNING_ROD; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_TookAttack; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else if (TARGET_PROTECT_AFFECTED + && (gCurrentMove != MOVE_CURSE || (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST)) + && ((!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)))) + { + CancelMultiTurnMoves(gBankAttacker); + gBattleMoveFlags |= MOVESTATUS_MISSED; + gUnknown_02024250[gBankTarget] = 0; + gUnknown_02024258[gBankTarget] = 0; + gBattleCommunication[6] = 1; + gBattlescriptCurrInstr++; + } + else + { + gBattlescriptCurrInstr++; + } +} + +void JumpIfMoveFailed(u8 adder, u16 move) +{ + const void* BS_ptr = gBattlescriptCurrInstr + adder; + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) + { + gUnknown_02024250[gBankTarget] = 0; + gUnknown_02024258[gBankTarget] = 0; + BS_ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + DestinyBondFlagUpdate(); + if (AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBankTarget, 0, 0, move)) + return; + } + gBattlescriptCurrInstr = BS_ptr; +} + +void atk40_jump_if_move_affected_by_protect(void) +{ + if (TARGET_PROTECT_AFFECTED) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + JumpIfMoveFailed(5, 0); + gBattleCommunication[6] = 1; + } + else + { + gBattlescriptCurrInstr += 5; + } +} + +bool8 JumpIfMoveAffectedByProtect(u16 move) +{ + bool8 affected = FALSE; + if (TARGET_PROTECT_AFFECTED) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + JumpIfMoveFailed(7, move); + gBattleCommunication[6] = 1; + affected = TRUE; + } + return affected; +} + +bool8 AccuracyCalcHelper(u16 move) +{ + if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker) + { + JumpIfMoveFailed(7, move); + return TRUE; + } + + if (!(gHitMarker & HITMARKER_IGNORE_ON_AIR) && gStatuses3[gBankTarget] & STATUS3_ON_AIR) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + JumpIfMoveFailed(7, move); + return TRUE; + } + + gHitMarker &= ~HITMARKER_IGNORE_ON_AIR; + + if (!(gHitMarker & HITMARKER_IGNORE_UNDERGROUND) && gStatuses3[gBankTarget] & STATUS3_UNDERGROUND) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + JumpIfMoveFailed(7, move); + return TRUE; + } + + gHitMarker &= ~HITMARKER_IGNORE_UNDERGROUND; + + if (!(gHitMarker & HITMARKER_IGNORE_UNDERWATER) && gStatuses3[gBankTarget] & STATUS3_UNDERWATER) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + JumpIfMoveFailed(7, move); + return TRUE; + } + + gHitMarker &= ~HITMARKER_IGNORE_UNDERWATER; + + if ((WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY) && gBattleMoves[move].effect == EFFECT_THUNDER) + || (gBattleMoves[move].effect == EFFECT_ALWAYS_HIT || gBattleMoves[move].effect == EFFECT_VITAL_THROW)) + { + JumpIfMoveFailed(7, move); + return TRUE; + } + + return FALSE; +} + +void atk01_accuracycheck(void) +{ + u16 move = BS2ScriptRead16(gBattlescriptCurrInstr + 5); + + if (move == 0xFFFE || move == 0xFFFF) + { + if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && move == 0xFFFF && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker) + gBattlescriptCurrInstr += 7; + else if (gStatuses3[gBankTarget] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else if (!JumpIfMoveAffectedByProtect(0)) + gBattlescriptCurrInstr += 7; + } + else + { + u8 type, moveAcc, holdEffect, quality; + s8 buff; + u16 calc; + + if (move == 0) + move = gCurrentMove; + + GET_MOVE_TYPE(move, type); + + if (JumpIfMoveAffectedByProtect(move)) + return; + if (AccuracyCalcHelper(move)) + return; + + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + { + u8 acc = gBattleMons[gBankAttacker].statStages[STAT_STAGE_ACC]; + buff = acc; + } + else + { + u8 acc = gBattleMons[gBankAttacker].statStages[STAT_STAGE_ACC]; + buff = acc + 6 - gBattleMons[gBankTarget].statStages[STAT_STAGE_EVASION]; + } + + if (buff < 0) + buff = 0; + if (buff > 0xC) + buff = 0xC; + + moveAcc = gBattleMoves[move].accuracy; + // check Thunder on sunny weather + if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY && gBattleMoves[move].effect == EFFECT_THUNDER) + moveAcc = 50; + + calc = gAccuracyStageRatios[buff].dividend * moveAcc; + calc /= gAccuracyStageRatios[buff].divisor; + + if (gBattleMons[gBankAttacker].ability == ABILITY_COMPOUND_EYES) + calc = (calc * 130) / 100; // 1.3 compound eyes boost + if (WEATHER_HAS_EFFECT && gBattleMons[gBankTarget].ability == ABILITY_SAND_VEIL && gBattleWeather & WEATHER_SANDSTORM_ANY) + calc = (calc * 80) / 100; // 1.2 sand veil loss + if (gBattleMons[gBankAttacker].ability == ABILITY_HUSTLE && type < 9) + calc = (calc * 80) / 100; // 1.2 hustle loss + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect; + quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_EVASION_UP) + calc = (calc * (100 - quality)) / 100; + + // final calculation + if ((Random() % 100 + 1) > calc) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && + (gBattleMoves[move].target == MOVE_TARGET_BOTH || gBattleMoves[move].target == MOVE_TARGET_FOES_AND_ALLY)) + gBattleCommunication[6] = 2; + else + gBattleCommunication[6] = 0; + + b_wonderguard_and_levitate(); + } + JumpIfMoveFailed(7, move); + } +} + +void atk02_attackstring(void) +{ + if (gBattleExecBuffer) + return; + if (!(gHitMarker & (HITMARKER_NO_ATTACKSTRING | HITMARKER_ATTACKSTRING_PRINTED))) + { + PrepareStringBattle(4, gBankAttacker); + gHitMarker |= HITMARKER_ATTACKSTRING_PRINTED; + } + gBattlescriptCurrInstr++; + gBattleCommunication[MSG_DISPLAY] = 0; +} -- cgit v1.2.3 From 3d32be86fcd40bf5979fff62a87d6390dd4171fe Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 19 Sep 2017 14:12:51 -0500 Subject: Continue baserom extraction --- src/pokemon_3.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/pokemon_3.c b/src/pokemon_3.c index 2d1dfb8b7..2c3e84de9 100644 --- a/src/pokemon_3.c +++ b/src/pokemon_3.c @@ -46,16 +46,16 @@ extern const struct SpindaSpot gSpindaSpotGraphics[]; extern const u8* const gStatNamesTable[]; extern const u8 gSpeciesNames[][11]; extern const u8 gUnknown_08329EC8[]; -extern const u8 gUnknown_085CB38A[]; -extern const u8 gUnknown_085CB3AA[]; -extern const u8 gUnknown_085CA459[]; -extern const u8 gUnknown_085CA424[]; +extern const u8 gText_StatRose[]; +extern const u8 gText_PkmnsStatChanged2[]; +extern const u8 gText_PkmnGettingPumped[]; +extern const u8 gText_PkmnShroudedInMist[]; extern const s8 gNatureStatTable[][5]; extern const s8 gUnknown_08329ECE[][3]; extern const u32 gBitTable[]; extern const u32 gTMHMLearnsets[][2]; extern const u8 BattleText_Wally[]; -extern const u8 BattleText_PreventedSwitch[]; +extern const u8 gText_PkmnsXPreventsSwitching[]; extern const struct CompressedSpritePalette gMonPaletteTable[]; extern const struct CompressedSpritePalette gMonShinyPaletteTable[]; extern const u16 gHMMoves[]; @@ -215,8 +215,8 @@ void sub_806CF24(s32 stat) { gBankTarget = gBankInMenu; StringCopy(gBattleTextBuff1, gStatNamesTable[gUnknown_08329EC8[stat]]); - StringCopy(gBattleTextBuff2, gUnknown_085CB38A); - StrCpyDecodeToDisplayedStringBattle(gUnknown_085CB3AA); + StringCopy(gBattleTextBuff2, gText_StatRose); + StrCpyDecodeToDisplayedStringBattle(gText_PkmnsStatChanged2); } u8 *sub_806CF78(u16 itemId) @@ -251,7 +251,7 @@ u8 *sub_806CF78(u16 itemId) else { gBankAttacker = gBankInMenu; - StrCpyDecodeToDisplayedStringBattle(gUnknown_085CA459); + StrCpyDecodeToDisplayedStringBattle(gText_PkmnGettingPumped); } } } @@ -259,7 +259,7 @@ u8 *sub_806CF78(u16 itemId) if (itemEffect[3] & 0x80) { gBankAttacker = gBankInMenu; - StrCpyDecodeToDisplayedStringBattle(gUnknown_085CA424); + StrCpyDecodeToDisplayedStringBattle(gText_PkmnShroudedInMist); } return gDisplayedStringBattle; @@ -1374,7 +1374,7 @@ void sub_806E994(void) gBattleTextBuff2[2] = gBankInMenu; gBattleTextBuff2[3] = pokemon_order_func(gBattlePartyID[gBankInMenu]); gBattleTextBuff2[4] = EOS; - StrCpyDecodeBattle(BattleText_PreventedSwitch, gStringVar4); + StrCpyDecodeBattle(gText_PkmnsXPreventsSwitching, gStringVar4); } struct PokeItem -- cgit v1.2.3 From e7e1938094081ba2e20232caca0239cb2290251f Mon Sep 17 00:00:00 2001 From: scnorton Date: Tue, 19 Sep 2017 16:17:23 -0400 Subject: Start decompilation of lilycove_lady --- src/lilycove_lady.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/lilycove_lady.c (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c new file mode 100644 index 000000000..7f4c4824a --- /dev/null +++ b/src/lilycove_lady.c @@ -0,0 +1,57 @@ +// +// Created by Scott Norton on 9/19/17. +// + +#include "global.h" +#include "event_data.h" +#include "lilycove_lady.h" + +void SetLilycoveQuizLady(void); +void SetLilycoveFavourLady(void); +void SetLilycoveContestLady(void); + +extern const u16 gUnknown_0860B074[]; +extern const u16 gUnknown_0860B07E[]; + +u8 GetLilycoveLadyId(void) +{ + return gSaveBlock1Ptr->lilycoveLady.common.id; +} + +void sub_818D9C0(void) +{ + LilycoveLady *lilycoveLady; + + VarSet(VAR_0x4010, gUnknown_0860B07E[GetLilycoveLadyId()]); + if (GetLilycoveLadyId() == LILYCOVE_LADY_CONTEST) + { + lilycoveLady = &gSaveBlock1Ptr->lilycoveLady; + VarSet(VAR_0x4011, gUnknown_0860B074[lilycoveLady->contest.category]); + gScriptResult = TRUE; + } + else + { + gScriptResult = FALSE; + } +} + +void SetLilycoveLady(void) +{ + u16 id; + + id = ((gSaveBlock2Ptr->playerTrainerId[1] << 8) | gSaveBlock2Ptr->playerTrainerId[0]); + id %= 6; + id >>= 1; + switch (id) + { + case LILYCOVE_LADY_QUIZ: + SetLilycoveQuizLady(); + break; + case LILYCOVE_LADY_FAVOUR: + SetLilycoveFavourLady(); + break; + case LILYCOVE_LADY_CONTEST: + SetLilycoveContestLady(); + break; + } +} -- cgit v1.2.3 From 99a7fcfdfa723390ecb25ec6819359b3521c8f34 Mon Sep 17 00:00:00 2001 From: scnorton Date: Tue, 19 Sep 2017 16:21:50 -0400 Subject: sub_818DA78, SetLilycoveLadyRandomly --- src/lilycove_lady.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 7f4c4824a..ab1c24914 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -4,11 +4,15 @@ #include "global.h" #include "event_data.h" +#include "rng.h" #include "lilycove_lady.h" void SetLilycoveQuizLady(void); void SetLilycoveFavourLady(void); void SetLilycoveContestLady(void); +void sub_818E004(void); +void sub_818DBC4(void); +void sub_818E674(void); extern const u16 gUnknown_0860B074[]; extern const u16 gUnknown_0860B07E[]; @@ -55,3 +59,38 @@ void SetLilycoveLady(void) break; } } + +void sub_818DA78(void) +{ + switch (GetLilycoveLadyId()) + { + case LILYCOVE_LADY_QUIZ: + sub_818E004(); + break; + case LILYCOVE_LADY_FAVOUR: + sub_818DBC4(); + break; + case LILYCOVE_LADY_CONTEST: + sub_818E674(); + break; + } +} + +void SetLilycoveLadyRandomly(void) +{ + u8 id; + + id = Random() % 3; + switch (id) + { + case LILYCOVE_LADY_QUIZ: + SetLilycoveQuizLady(); + break; + case LILYCOVE_LADY_FAVOUR: + SetLilycoveFavourLady(); + break; + case LILYCOVE_LADY_CONTEST: + SetLilycoveContestLady(); + break; + } +} -- cgit v1.2.3 From 0d0532731f99036d09d6bb2788de0221b6886105 Mon Sep 17 00:00:00 2001 From: scnorton Date: Tue, 19 Sep 2017 16:24:42 -0400 Subject: sub_818DAEC, sub_818DB04 --- src/lilycove_lady.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index ab1c24914..579eca5cb 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -94,3 +94,16 @@ void SetLilycoveLadyRandomly(void) break; } } + +void sub_818DAEC(void) +{ + gScriptResult = GetLilycoveLadyId(); +} + +u8 sub_818DB04(u16 *data) +{ + u8 len; + + for (len = 0; *data != 0; len ++, data ++); + return len; +} -- cgit v1.2.3 From b26eb6713bb866f1173b4c7192ce231d894d19ea Mon Sep 17 00:00:00 2001 From: scnorton Date: Tue, 19 Sep 2017 16:32:33 -0400 Subject: sub_818DB20 --- src/lilycove_lady.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 579eca5cb..2e0d336dd 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -14,8 +14,11 @@ void sub_818E004(void); void sub_818DBC4(void); void sub_818E674(void); -extern const u16 gUnknown_0860B074[]; -extern const u16 gUnknown_0860B07E[]; +extern const u16 gUnknown_0860B074[5]; +extern const u16 gUnknown_0860B07E[3]; +extern const u16 *const gUnknown_0860B2EC[6]; + +EWRAM_DATA LilycoveLady *gUnknown_0203CD64 = NULL; u8 GetLilycoveLadyId(void) { @@ -100,10 +103,21 @@ void sub_818DAEC(void) gScriptResult = GetLilycoveLadyId(); } -u8 sub_818DB04(u16 *data) +u8 sub_818DB04(const u16 *data) { u8 len; for (len = 0; *data != 0; len ++, data ++); return len; } + +void sub_818DB20(void) +{ + u8 size; + u8 idx; + + gUnknown_0203CD64->favour.unk_00c = Random() % 6; + size = sub_818DB04(gUnknown_0860B2EC[gUnknown_0203CD64->favour.unk_00c]); + idx = Random() % size; + gUnknown_0203CD64->favour.unk_010 = gUnknown_0860B2EC[gUnknown_0203CD64->favour.unk_00c][idx]; +} -- cgit v1.2.3 From 4e8a2c6934c4f8a44ed8d350fe96996beda21d0e Mon Sep 17 00:00:00 2001 From: scnorton Date: Tue, 19 Sep 2017 16:55:53 -0400 Subject: SetLilycoveFavourLady --- src/lilycove_lady.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 2e0d336dd..aec55a574 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -3,6 +3,7 @@ // #include "global.h" +#include "main.h" #include "event_data.h" #include "rng.h" #include "lilycove_lady.h" @@ -121,3 +122,23 @@ void sub_818DB20(void) idx = Random() % size; gUnknown_0203CD64->favour.unk_010 = gUnknown_0860B2EC[gUnknown_0203CD64->favour.unk_00c][idx]; } + +void SetLilycoveFavourLady(void) +{ + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + gUnknown_0203CD64->favour.id = LILYCOVE_LADY_FAVOUR; + gUnknown_0203CD64->favour.unk_001 = 0; + gUnknown_0203CD64->favour.unk_004 = 0xFF; + gUnknown_0203CD64->favour.unk_002 = 0; + gUnknown_0203CD64->favour.unk_003= 0; + gUnknown_0203CD64->favour.unk_00e = 0; + gUnknown_0203CD64->favour.language = gGameLanguage; + sub_818DB20(); +} + +void sub_818DBC4(void) +{ + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + gUnknown_0203CD64->favour.id = LILYCOVE_LADY_FAVOUR; + gUnknown_0203CD64->favour.unk_001 = 0; +} -- cgit v1.2.3 From b8e733283e31c4863f774c6cf2bbb17ba369681f Mon Sep 17 00:00:00 2001 From: scnorton Date: Tue, 19 Sep 2017 17:04:17 -0400 Subject: Another handful of favour lady functions --- src/lilycove_lady.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index aec55a574..16461728c 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -6,6 +6,7 @@ #include "main.h" #include "event_data.h" #include "rng.h" +#include "string_util.h" #include "lilycove_lady.h" void SetLilycoveQuizLady(void); @@ -17,6 +18,7 @@ void sub_818E674(void); extern const u16 gUnknown_0860B074[5]; extern const u16 gUnknown_0860B07E[3]; +extern const u8 *const gUnknown_0860B224[]; extern const u16 *const gUnknown_0860B2EC[6]; EWRAM_DATA LilycoveLady *gUnknown_0203CD64 = NULL; @@ -142,3 +144,31 @@ void sub_818DBC4(void) gUnknown_0203CD64->favour.id = LILYCOVE_LADY_FAVOUR; gUnknown_0203CD64->favour.unk_001 = 0; } + +u8 sub_818DBE8(void) +{ + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + if (gUnknown_0203CD64->favour.unk_001 == 2) + { + return 2; + } + else if (gUnknown_0203CD64->favour.unk_001 == 1) + { + return 1; + } + else + { + return 0; + } +} + +const u8 *sub_818DC1C(u8 idx) +{ + return gUnknown_0860B224[idx]; +} + +void sub_818DC2C(void) +{ + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + StringCopy(gStringVar1, sub_818DC1C(gUnknown_0203CD64->favour.unk_00c)); +} -- cgit v1.2.3 From 3b3423d1a751134ff7941b41bad72e0e75314647 Mon Sep 17 00:00:00 2001 From: scnorton Date: Tue, 19 Sep 2017 17:07:36 -0400 Subject: sub_818DC60 --- src/lilycove_lady.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 16461728c..578280115 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -7,6 +7,7 @@ #include "event_data.h" #include "rng.h" #include "string_util.h" +#include "text.h" #include "lilycove_lady.h" void SetLilycoveQuizLady(void); @@ -130,7 +131,7 @@ void SetLilycoveFavourLady(void) gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; gUnknown_0203CD64->favour.id = LILYCOVE_LADY_FAVOUR; gUnknown_0203CD64->favour.unk_001 = 0; - gUnknown_0203CD64->favour.unk_004 = 0xFF; + gUnknown_0203CD64->favour.unk_004[0] = EOS; gUnknown_0203CD64->favour.unk_002 = 0; gUnknown_0203CD64->favour.unk_003= 0; gUnknown_0203CD64->favour.unk_00e = 0; @@ -172,3 +173,15 @@ void sub_818DC2C(void) gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; StringCopy(gStringVar1, sub_818DC1C(gUnknown_0203CD64->favour.unk_00c)); } + +bool8 sub_818DC60(void) +{ + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + if (gUnknown_0203CD64->favour.unk_004[0] != EOS) + { + StringCopy7(gStringVar3, gSaveBlock1Ptr->lilycoveLady.favour.unk_004); + ConvertInternationalString(gStringVar3, gUnknown_0203CD64->favour.language); + return TRUE; + } + return FALSE; +} -- cgit v1.2.3 From b4875d82d50b0649c2289b9e470ca0a9ae23782d Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 20 Sep 2017 00:28:00 +0200 Subject: more battle 4 --- src/battle_3.c | 3 +- src/battle_4.c | 644 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/battle_ai.c | 3 - 3 files changed, 643 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index 283305d6c..4f0997aa0 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -14,6 +14,7 @@ #include "string_util.h" #include "battle_message.h" #include "battle_ai.h" +#include "battle_controllers.h" #include "event_data.h" #include "calculate_base_damage.h" @@ -183,10 +184,8 @@ extern u8 b_first_side(u8, u8, u8); extern void sub_803CEDC(u8, u8); extern void b_call_bc_move_exec(const u8 *); extern void BattleTurnPassed(void); -extern void EmitSetAttributes(u8 a, u8 request, u8 c, u8 bytes, void *data); extern void SetMoveEffect(bool8 primary, u8 certainArg); extern bool8 UproarWakeUpCheck(u8 bank); -extern void MarkBufferBankForExecution(u8 bank); extern u8 sub_803F90C(u8 bank); extern void sub_803F9EC(); extern bool8 sub_80423F4(u8 bank, u8, u8); diff --git a/src/battle_4.c b/src/battle_4.c index e693162cc..be7f712c6 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -12,6 +12,8 @@ #include "pokemon.h" #include "calculate_base_damage.h" #include "rng.h" +#include "battle_controllers.h" +#include "species.h" // variables @@ -135,7 +137,7 @@ extern const u8 BattleScript_ShakeBallThrow[]; bool8 IsTwoTurnsMove(u16 move); void DestinyBondFlagUpdate(void); u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. -void b_wonderguard_and_levitate(void); +static void CheckWonderGuardAndLevitate(void); void atk00_attackcanceler(void); void atk01_accuracycheck(void); @@ -1000,7 +1002,7 @@ void atk01_accuracycheck(void) else gBattleCommunication[6] = 0; - b_wonderguard_and_levitate(); + CheckWonderGuardAndLevitate(); } JumpIfMoveFailed(7, move); } @@ -1018,3 +1020,641 @@ void atk02_attackstring(void) gBattlescriptCurrInstr++; gBattleCommunication[MSG_DISPLAY] = 0; } + +void atk03_ppreduce(void) +{ + s32 to_deduct = 1; + + if (gBattleExecBuffer) + return; + + if (!gSpecialStatuses[gBankAttacker].flag20) + { + switch (gBattleMoves[gCurrentMove].target) + { + case MOVE_TARGET_FOES_AND_ALLY: + to_deduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_ON_FIELD, gBankAttacker, ABILITY_PRESSURE, 0, 0); + break; + case MOVE_TARGET_BOTH: + case MOVE_TARGET_OPPONENTS_FIELD: + to_deduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIZE, gBankAttacker, ABILITY_PRESSURE, 0, 0); + break; + default: + if (gBankAttacker != gBankTarget && gBattleMons[gBankTarget].ability == ABILITY_PRESSURE) + to_deduct++; + break; + } + } + + if (!(gHitMarker & (HITMARKER_NO_PPDEDUCT | HITMARKER_NO_ATTACKSTRING)) && gBattleMons[gBankAttacker].pp[gCurrMovePos]) + { + gProtectStructs[gBankAttacker].notFirstStrike = 1; + + if (gBattleMons[gBankAttacker].pp[gCurrMovePos] > to_deduct) + gBattleMons[gBankAttacker].pp[gCurrMovePos] -= to_deduct; + else + gBattleMons[gBankAttacker].pp[gCurrMovePos] = 0; + + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED) + && !((gDisableStructs[gBankAttacker].unk18_b) & gBitTable[gCurrMovePos])) + { + gActiveBank = gBankAttacker; + EmitSetAttributes(0, REQUEST_PPMOVE1_BATTLE + gCurrMovePos, 0, 1, &gBattleMons[gBankAttacker].pp[gCurrMovePos]); + MarkBufferBankForExecution(gBankAttacker); + } + } + + gHitMarker &= ~(HITMARKER_NO_PPDEDUCT); + gBattlescriptCurrInstr++; +} + +void atk04_critcalc(void) +{ + u8 holdEffect; + u16 item, critChance; + + item = gBattleMons[gBankAttacker].item; + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gEnigmaBerries[gBankAttacker].holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + gStringBank = gBankAttacker; + + critChance = 2 * ((gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0) + + (gBattleMoves[gCurrentMove].effect == EFFECT_HIGH_CRITICAL) + + (gBattleMoves[gCurrentMove].effect == EFFECT_SKY_ATTACK) + + (gBattleMoves[gCurrentMove].effect == EFFECT_BLAZE_KICK) + + (gBattleMoves[gCurrentMove].effect == EFFECT_POISON_TAIL) + + (holdEffect == HOLD_EFFECT_SCOPE_LENS) + + 2 * (holdEffect == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBankAttacker].species == SPECIES_CHANSEY) + + 2 * (holdEffect == HOLD_EFFECT_STICK && gBattleMons[gBankAttacker].species == SPECIES_FARFETCHD); + + if (critChance > 4) + critChance = 4; + + if ((gBattleMons[gBankTarget].ability != ABILITY_BATTLE_ARMOR && gBattleMons[gBankTarget].ability != ABILITY_SHELL_ARMOR) + && !(gStatuses3[gBankAttacker] & STATUS3_CANT_SCORE_A_CRIT) + && !(gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE)) + && !(Random() % gCriticalHitChance[critChance])) + gCritMultiplier = 2; + else + gCritMultiplier = 1; + + gBattlescriptCurrInstr++; +} + +void atk05_damagecalc1(void) +{ + u16 sideStatus = gSideAffecting[GET_BANK_SIDE(gBankTarget)]; + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, + sideStatus, gDynamicBasePower, + gBattleStruct->dynamicMoveType, gBankAttacker, gBankTarget); + gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting.dmgMultiplier; + + if (gStatuses3[gBankAttacker] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + gBattleMoveDamage *= 2; + if (gProtectStructs[gBankAttacker].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; + + gBattlescriptCurrInstr++; +} + +void AI_CalcDmg(u8 bankAtk, u8 bankDef) +{ + u16 sideStatus = gSideAffecting[GET_BANK_SIDE(bankDef)]; + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[bankAtk], &gBattleMons[bankDef], gCurrentMove, + sideStatus, gDynamicBasePower, + gBattleStruct->dynamicMoveType, bankAtk, bankDef); + gDynamicBasePower = 0; + gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting.dmgMultiplier; + + if (gStatuses3[bankAtk] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + gBattleMoveDamage *= 2; + if (gProtectStructs[bankAtk].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; +} + +void ModulateDmgByType(u8 multiplier) +{ + gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; + if (gBattleMoveDamage == 0 && multiplier != 0) + gBattleMoveDamage = 1; + + switch (multiplier) + { + case TYPE_MUL_NO_EFFECT: + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + gBattleMoveFlags &= ~MOVESTATUS_NOTVERYEFFECTIVE; + gBattleMoveFlags &= ~MOVESTATUS_SUPEREFFECTIVE; + break; + case TYPE_MUL_NOT_EFFECTIVE: + if (gBattleMoves[gCurrentMove].power && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + if (gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE) + gBattleMoveFlags &= ~MOVESTATUS_SUPEREFFECTIVE; + else + gBattleMoveFlags |= MOVESTATUS_NOTVERYEFFECTIVE; + } + break; + case TYPE_MUL_SUPER_EFFECTIVE: + if (gBattleMoves[gCurrentMove].power && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + if (gBattleMoveFlags & MOVESTATUS_NOTVERYEFFECTIVE) + gBattleMoveFlags &= ~MOVESTATUS_NOTVERYEFFECTIVE; + else + gBattleMoveFlags |= MOVESTATUS_SUPEREFFECTIVE; + } + break; + } +} + +#define TYPE_FORESIGHT 0xFE +#define TYPE_ENDTABLE 0xFF + +void atk06_typecalc(void) +{ + s32 i = 0; + u8 moveType; + + if (gCurrentMove == MOVE_STRUGGLE) + { + gBattlescriptCurrInstr++; + return; + } + + GET_MOVE_TYPE(gCurrentMove, moveType); + + // check stab + if (gBattleMons[gBankAttacker].type1 == moveType || gBattleMons[gBankAttacker].type2 == moveType) + { + gBattleMoveDamage = gBattleMoveDamage * 15; + gBattleMoveDamage = gBattleMoveDamage / 10; + } + + if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) + { + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gBattleMoveFlags |= (MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED); + gUnknown_02024250[gBankTarget] = 0; + gUnknown_02024258[gBankTarget] = 0; + gBattleCommunication[6] = moveType; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else + { + while (gTypeEffectiveness[i] != TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + break; + i += 3; + continue; + } + else if (gTypeEffectiveness[i] == moveType) + { + // check type1 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1) + ModulateDmgByType(gTypeEffectiveness[i + 2]); + // check type2 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && + gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2) + ModulateDmgByType(gTypeEffectiveness[i + 2]); + } + i += 3; + } + } + + if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2 + && (!(gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE) || ((gBattleMoveFlags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) + && gBattleMoves[gCurrentMove].power) + { + gLastUsedAbility = ABILITY_WONDER_GUARD; + gBattleMoveFlags |= MOVESTATUS_MISSED; + gUnknown_02024250[gBankTarget] = 0; + gUnknown_02024258[gBankTarget] = 0; + gBattleCommunication[6] = 3; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) + gProtectStructs[gBankAttacker].notEffective = 1; + + gBattlescriptCurrInstr++; +} + +static void CheckWonderGuardAndLevitate(void) +{ + u8 flags = 0; + s32 i = 0; + u8 moveType; + + if (gCurrentMove == MOVE_STRUGGLE || !gBattleMoves[gCurrentMove].power) + return; + + GET_MOVE_TYPE(gCurrentMove, moveType); + + if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) + { + gLastUsedAbility = ABILITY_LEVITATE; + gBattleCommunication[6] = moveType; + RecordAbilityBattle(gBankTarget, ABILITY_LEVITATE); + return; + } + + while (gTypeEffectiveness[i] != TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + break; + i += 3; + continue; + } + if (gTypeEffectiveness[i] == moveType) + { + // check no effect + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 0) + { + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + gProtectStructs[gBankAttacker].notEffective = 1; + } + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && + gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 && + gTypeEffectiveness[i + 2] == TYPE_MUL_NO_EFFECT) + { + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + gProtectStructs[gBankAttacker].notEffective = 1; + } + + // check super effective + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 20) + flags |= 1; + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == TYPE_MUL_SUPER_EFFECTIVE) + flags |= 1; + + // check not very effective + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 5) + flags |= 2; + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == TYPE_MUL_NOT_EFFECTIVE) + flags |= 2; + } + i += 3; + } + + if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2) + { + if (((flags & 2) || !(flags & 1)) && gBattleMoves[gCurrentMove].power) + { + gLastUsedAbility = ABILITY_WONDER_GUARD; + gBattleCommunication[6] = 3; + RecordAbilityBattle(gBankTarget, ABILITY_WONDER_GUARD); + } + } +} + +void ModulateDmgByType2(u8 multiplier, u16 move, u8* flags) // same as ModulateDmgByType except different arguments +{ + gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; + if (gBattleMoveDamage == 0 && multiplier != 0) + gBattleMoveDamage = 1; + + switch (multiplier) + { + case TYPE_MUL_NO_EFFECT: + *flags |= MOVESTATUS_NOTAFFECTED; + *flags &= ~MOVESTATUS_NOTVERYEFFECTIVE; + *flags &= ~MOVESTATUS_SUPEREFFECTIVE; + break; + case TYPE_MUL_NOT_EFFECTIVE: + if (gBattleMoves[move].power && !(*flags & MOVESTATUS_NOEFFECT)) + { + if (*flags & MOVESTATUS_SUPEREFFECTIVE) + *flags &= ~MOVESTATUS_SUPEREFFECTIVE; + else + *flags |= MOVESTATUS_NOTVERYEFFECTIVE; + } + break; + case TYPE_MUL_SUPER_EFFECTIVE: + if (gBattleMoves[move].power && !(*flags & MOVESTATUS_NOEFFECT)) + { + if (*flags & MOVESTATUS_NOTVERYEFFECTIVE) + *flags &= ~MOVESTATUS_NOTVERYEFFECTIVE; + else + *flags |= MOVESTATUS_SUPEREFFECTIVE; + } + break; + } +} + +u8 TypeCalc(u16 move, u8 bankAtk, u8 bankDef) +{ + s32 i = 0; + u8 flags = 0; + u8 moveType; + + if (move == MOVE_STRUGGLE) + return 0; + + moveType = gBattleMoves[move].type; + + // check stab + if (gBattleMons[bankAtk].type1 == moveType || gBattleMons[bankAtk].type2 == moveType) + { + gBattleMoveDamage = gBattleMoveDamage * 15; + gBattleMoveDamage = gBattleMoveDamage / 10; + } + + if (gBattleMons[bankDef].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) + { + flags |= (MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED); + } + else + { + while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[bankDef].status2 & STATUS2_FORESIGHT) + break; + i += 3; + continue; + } + + else if (gTypeEffectiveness[i] == moveType) + { + // check type1 + if (gTypeEffectiveness[i + 1] == gBattleMons[bankDef].type1) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + // check type2 + if (gTypeEffectiveness[i + 1] == gBattleMons[bankDef].type2 && + gBattleMons[bankDef].type1 != gBattleMons[bankDef].type2) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + } + i += 3; + } + } + + if (gBattleMons[bankDef].ability == ABILITY_WONDER_GUARD && !(flags & MOVESTATUS_MISSED) + && AttacksThisTurn(bankAtk, move) == 2 + && (!(flags & MOVESTATUS_SUPEREFFECTIVE) || ((flags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) + && gBattleMoves[move].power) + { + flags |= MOVESTATUS_MISSED; + } + return flags; +} + +u8 AI_TypeCalc(u16 move, u16 species, u8 ability) +{ + s32 i = 0; + u8 flags = 0; + u8 type1 = gBaseStats[species].type1, type2 = gBaseStats[species].type2; + u8 moveType; + + if (move == MOVE_STRUGGLE) + return 0; + + moveType = gBattleMoves[move].type; + + if (ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) + { + flags = MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED; + } + else + { + while (gTypeEffectiveness[i] != TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + i += 3; + continue; + } + if (gTypeEffectiveness[i] == moveType) + { + // check type1 + if (gTypeEffectiveness[i + 1] == type1) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + // check type2 + if (gTypeEffectiveness[i + 1] == type2 && type1 != type2) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + } + i += 3; + } + } + if (ability == ABILITY_WONDER_GUARD + && (!(flags & MOVESTATUS_SUPEREFFECTIVE) || ((flags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) + && gBattleMoves[move].power) + flags |= MOVESTATUS_NOTAFFECTED; + return flags; +} + +// Multiplies the damage by a random factor between 85% to 100% inclusive +static inline void ApplyRandomDmgMultiplier(void) +{ + u16 rand = Random(); + u16 randPercent = 100 - (rand % 16); + + if (gBattleMoveDamage != 0) + { + gBattleMoveDamage *= randPercent; + gBattleMoveDamage /= 100; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } +} + +void Unused_ApplyRandomDmgMultiplier(void) +{ + ApplyRandomDmgMultiplier(); +} + +void atk07_dmg_adjustment(void) +{ + u8 holdEffect, quality; + + ApplyRandomDmgMultiplier(); + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + { + RecordItemEffectBattle(gBankTarget, holdEffect); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + goto END; + if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE && !gProtectStructs[gBankTarget].endured + && !gSpecialStatuses[gBankTarget].focusBanded) + goto END; + + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + goto END; + + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + + if (gProtectStructs[gBankTarget].endured) + { + gBattleMoveFlags |= MOVESTATUS_ENDURED; + } + else if (gSpecialStatuses[gBankTarget].focusBanded) + { + gBattleMoveFlags |= MOVESTATUS_HUNGON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + + END: + gBattlescriptCurrInstr++; +} + +void atk08_dmg_adjustment2(void) // The same as 0x7 except it doesn't check for false swipe move effect. +{ + u8 holdEffect, quality; + + ApplyRandomDmgMultiplier(); + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + { + RecordItemEffectBattle(gBankTarget, holdEffect); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + goto END; + if (!gProtectStructs[gBankTarget].endured && !gSpecialStatuses[gBankTarget].focusBanded) + goto END; + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + goto END; + + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + + if (gProtectStructs[gBankTarget].endured) + { + gBattleMoveFlags |= MOVESTATUS_ENDURED; + } + else if (gSpecialStatuses[gBankTarget].focusBanded) + { + gBattleMoveFlags |= MOVESTATUS_HUNGON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + + END: + gBattlescriptCurrInstr++; +} + +void atk09_attackanimation(void) +{ + if (gBattleExecBuffer) + return; + + if ((gHitMarker & HITMARKER_NO_ANIMATIONS) && (gCurrentMove != MOVE_TRANSFORM && gCurrentMove != MOVE_SUBSTITUTE)) + { + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_Pausex20; + gBattleScripting.animTurn++; + gBattleScripting.animTargetsHit++; + } + else + { + if ((gBattleMoves[gCurrentMove].target & MOVE_TARGET_BOTH + || gBattleMoves[gCurrentMove].target & MOVE_TARGET_FOES_AND_ALLY + || gBattleMoves[gCurrentMove].target & MOVE_TARGET_DEPENDS) + && gBattleScripting.animTargetsHit) + { + gBattlescriptCurrInstr++; + return; + } + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + u8 multihit; + + gActiveBank = gBankAttacker; + + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + multihit = gMultiHitCounter; + else if (gMultiHitCounter != 0 && gMultiHitCounter != 1) + { + if (gBattleMons[gBankTarget].hp <= gBattleMoveDamage) + multihit = 1; + else + multihit = gMultiHitCounter; + } + else + multihit = gMultiHitCounter; + + EmitMoveAnimation(0, gCurrentMove, gBattleScripting.animTurn, gBattleMovePower, gBattleMoveDamage, gBattleMons[gBankAttacker].friendship, &gDisableStructs[gBankAttacker], multihit); + gBattleScripting.animTurn += 1; + gBattleScripting.animTargetsHit += 1; + MarkBufferBankForExecution(gBankAttacker); + gBattlescriptCurrInstr++; + } + else + { + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_Pausex20; + } + } +} + +void atk0A_waitanimation(void) +{ + if (gBattleExecBuffer == 0) + gBattlescriptCurrInstr++; +} + +void atk0B_healthbarupdate(void) +{ + register s16 healthValue asm("r1"); + + if (gBattleExecBuffer) + return; + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) + goto END; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) + { + PrepareStringBattle(0x80, gActiveBank); + goto END; + } + + healthValue = 10000; + if (healthValue <= gBattleMoveDamage) + healthValue = gBattleMoveDamage; + + EmitHealthBarUpdate(0, healthValue); + MarkBufferBankForExecution(gActiveBank); + + if (GetBankSide(gActiveBank) == SIDE_PLAYER && gBattleMoveDamage > 0) + gBattleResults.unk5_0 = 1; + + END: + gBattlescriptCurrInstr += 2; +} diff --git a/src/battle_ai.c b/src/battle_ai.c index 3b696b84e..75b5eb2ed 100644 --- a/src/battle_ai.c +++ b/src/battle_ai.c @@ -73,10 +73,7 @@ extern const struct BaseStats gBaseStats[]; extern const u32 gBitTable[]; extern u8 * const gBattleAI_ScriptsTable[]; -extern u8 GetBankIdentity(u8); extern u8 b_first_side(u8, u8, u8); -extern u8 GetBankByPlayerAI(u8); -extern void TypeCalc(u16 move, u8 bankAtk, u8 bankDef); extern void AI_CalcDmg(u8, u8); extern u8 CheckMoveLimitations(); -- cgit v1.2.3 From fcc94f9722609ffa67c045cf8a7539690a68b080 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 19 Sep 2017 19:31:53 -0500 Subject: Extract baseroms from battle_message and rename strings --- src/pokemon_2.c | 6 +++--- src/pokemon_3.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/pokemon_2.c b/src/pokemon_2.c index 30e788874..cf073570d 100644 --- a/src/pokemon_2.c +++ b/src/pokemon_2.c @@ -31,7 +31,7 @@ extern const union AnimCmd* gUnknown_082FF70C[]; extern const union AnimCmd* const * const gUnknown_08309AAC[]; extern const union AnimCmd* const * const gUnknown_08305D0C[]; extern const union AnimCmd* const * const gUnknown_0830536C[]; -extern const u8 gBadEggNickname[]; +extern const u8 gText_BadEgg[]; extern const u8 gText_EggNickname[]; extern u8 GetBankSide(u8 bank); @@ -409,8 +409,8 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) if (boxMon->isBadEgg) { for (retVal = 0; - retVal < POKEMON_NAME_LENGTH && gBadEggNickname[retVal] != EOS; - data[retVal] = gBadEggNickname[retVal], retVal++) {} + retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS; + data[retVal] = gText_BadEgg[retVal], retVal++) {} data[retVal] = EOS; } diff --git a/src/pokemon_3.c b/src/pokemon_3.c index 2c3e84de9..569222e33 100644 --- a/src/pokemon_3.c +++ b/src/pokemon_3.c @@ -54,7 +54,7 @@ extern const s8 gNatureStatTable[][5]; extern const s8 gUnknown_08329ECE[][3]; extern const u32 gBitTable[]; extern const u32 gTMHMLearnsets[][2]; -extern const u8 BattleText_Wally[]; +extern const u8 gText_BattleWallyName[]; extern const u8 gText_PkmnsXPreventsSwitching[]; extern const struct CompressedSpritePalette gMonPaletteTable[]; extern const struct CompressedSpritePalette gMonShinyPaletteTable[]; @@ -1177,7 +1177,7 @@ u16 GetBattleBGM(void) case CLASS_PKMN_TRAINER_RIVAL: if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) return 0x1E1; - if (!StringCompare(gTrainers[gTrainerBattleOpponent_A].trainerName, BattleText_Wally)) + if (!StringCompare(gTrainers[gTrainerBattleOpponent_A].trainerName, gText_BattleWallyName)) return 0x1DC; return 0x1E1; case CLASS_ELITE_FOUR: -- cgit v1.2.3 From 54bd2c17812bd399fa6e857332c3bdacc1df71b3 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 21:10:30 -0400 Subject: Address review by diego --- src/berry_fix_program.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c index 931e92746..f04308ae8 100644 --- a/src/berry_fix_program.c +++ b/src/berry_fix_program.c @@ -130,8 +130,7 @@ static const u8 *const gUnknown_08618178[][3] = { }; extern const u8 gUnknown_089A6550[0xC0]; -extern const u8 gMultiBootProgram_BerryGlitchFix_Script[0x3b34]; -extern const u8 gMultiBootProgram_BerryGlitchFix_Start[]; +extern const u8 gMultiBootProgram_BerryGlitchFix_Start[0x3b34]; extern const u8 gMultiBootProgram_BerryGlitchFix_End[]; // .text -- cgit v1.2.3 From 316f9f4d83d118437c266526cc0e6da1dfc90461 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 21:28:01 -0400 Subject: through sub_818DD14 --- src/lilycove_lady.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 578280115..c6b49e36f 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -7,6 +7,8 @@ #include "event_data.h" #include "rng.h" #include "string_util.h" +#include "item.h" +#include "items.h" #include "text.h" #include "lilycove_lady.h" @@ -134,7 +136,7 @@ void SetLilycoveFavourLady(void) gUnknown_0203CD64->favour.unk_004[0] = EOS; gUnknown_0203CD64->favour.unk_002 = 0; gUnknown_0203CD64->favour.unk_003= 0; - gUnknown_0203CD64->favour.unk_00e = 0; + gUnknown_0203CD64->favour.itemId = ITEM_NONE; gUnknown_0203CD64->favour.language = gGameLanguage; sub_818DB20(); } @@ -185,3 +187,27 @@ bool8 sub_818DC60(void) } return FALSE; } + +void sub_818DCAC(u8 *dest, u16 itemId) +{ + StringCopy(dest, ItemId_GetItem(itemId)->name); +} + +void sub_818DCC8(void) +{ + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + sub_818DCAC(gStringVar2, gUnknown_0203CD64->favour.itemId); +} + +void sub_818DCF4(const u8 *src, u8 *dest) +{ + memset(dest, 0xFF, 8); + StringCopy7(dest, src); +} + +void sub_818DD14(void) +{ + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + sub_818DCF4(gSaveBlock1Ptr->lilycoveLady.favour.unk_004, gStringVar3); + ConvertInternationalString(gStringVar3, gUnknown_0203CD64->favour.language); +} -- cgit v1.2.3 From 534dd2c4b0259f87657b2e8795d96217e8bf12cc Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 21:47:15 -0400 Subject: sub_818DD84 --- src/lilycove_lady.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index c6b49e36f..8a0851110 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -9,6 +9,7 @@ #include "string_util.h" #include "item.h" #include "items.h" +#include "item_menu.h" #include "text.h" #include "lilycove_lady.h" @@ -211,3 +212,46 @@ void sub_818DD14(void) sub_818DCF4(gSaveBlock1Ptr->lilycoveLady.favour.unk_004, gStringVar3); ConvertInternationalString(gStringVar3, gUnknown_0203CD64->favour.language); } + +bool8 sub_818DD54(void) +{ + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + return gUnknown_0203CD64->favour.unk_002 ? TRUE : FALSE; +} + +void sub_818DD78(void) +{ + sub_81AAC50(); +} + +bool8 sub_818DD84(u16 itemId) +{ + u8 len; + u8 i; + bool8 response; + + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + len = sub_818DB04(gUnknown_0860B2EC[gUnknown_0203CD64->favour.unk_00c]); + gUnknown_0203CD64->favour.unk_001 = 1; + sub_818DCAC(gStringVar2, itemId); + gUnknown_0203CD64->favour.itemId = itemId; + sub_818DCF4(gSaveBlock2Ptr->playerName, gUnknown_0203CD64->favour.unk_004); + gUnknown_0203CD64->favour.language = gGameLanguage; + response = FALSE; + for (i = 0; i < len; i ++) + { + if (gUnknown_0860B2EC[gUnknown_0203CD64->favour.unk_00c][i] == itemId) + { + response = TRUE; + gUnknown_0203CD64->favour.unk_003 ++; + gUnknown_0203CD64->favour.unk_002 = 1; + if (gUnknown_0203CD64->favour.unk_010 == itemId) + { + gUnknown_0203CD64->favour.unk_003 = 5; + } + break; + } + gUnknown_0203CD64->favour.unk_002 = 0; + } + return response; +} -- cgit v1.2.3 From 83a420400c302d4c59eb204f8fa18943d69fc6d0 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 21:58:32 -0400 Subject: through sub_818DEF4 --- src/lilycove_lady.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 8a0851110..10a0e7f45 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -5,6 +5,7 @@ #include "global.h" #include "main.h" #include "event_data.h" +#include "script.h" #include "rng.h" #include "string_util.h" #include "item.h" @@ -24,8 +25,10 @@ extern const u16 gUnknown_0860B074[5]; extern const u16 gUnknown_0860B07E[3]; extern const u8 *const gUnknown_0860B224[]; extern const u16 *const gUnknown_0860B2EC[6]; +extern const u16 gUnknown_0860B304[6]; EWRAM_DATA LilycoveLady *gUnknown_0203CD64 = NULL; +extern EWRAM_DATA u16 gScriptItemId; u8 GetLilycoveLadyId(void) { @@ -255,3 +258,44 @@ bool8 sub_818DD84(u16 itemId) } return response; } + +bool8 sub_818DE44(void) +{ + return sub_818DD84(gScriptItemId); +} + +bool8 sub_818DE5C(void) +{ + u8 checkval; + + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + checkval = gUnknown_0203CD64->favour.unk_003; + return checkval < 5 ? FALSE : TRUE; +} + +void sub_818DE88(u16 itemId) +{ + sub_818DCAC(gStringVar2, itemId); +} + +u16 sub_818DEA0(void) +{ + u16 itemId; + + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + itemId = gUnknown_0860B304[gUnknown_0203CD64->favour.unk_00c]; + sub_818DE88(itemId); + gUnknown_0203CD64->favour.unk_001 = 2; + return itemId; +} + +void sub_818DEDC(void) +{ + SetLilycoveFavourLady(); + gUnknown_0203CD64->favour.unk_001 = 1; +} + +void sub_818DEF4(void) +{ + EnableBothScriptContexts(); +} -- cgit v1.2.3 From 73ee165ef6b05417dc42be721e625712c6538ed6 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 22:25:31 -0400 Subject: sub_818DF00 --- src/lilycove_lady.c | 114 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 10a0e7f45..d64b0d3b3 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -26,8 +26,12 @@ extern const u16 gUnknown_0860B07E[3]; extern const u8 *const gUnknown_0860B224[]; extern const u16 *const gUnknown_0860B2EC[6]; extern const u16 gUnknown_0860B304[6]; +extern const u16 *const gUnknown_0860B1A4[16]; +extern const u16 gUnknown_0860B1E4[16]; +extern const u16 gUnknown_0860B204[16]; -EWRAM_DATA LilycoveLady *gUnknown_0203CD64 = NULL; +EWRAM_DATA struct LilycoveLadyFavour *gUnknown_0203CD64 = NULL; +EWRAM_DATA struct LilycoveLadyQuiz *gUnknown_0203CD68 = NULL; extern EWRAM_DATA u16 gScriptItemId; u8 GetLilycoveLadyId(void) @@ -126,40 +130,40 @@ void sub_818DB20(void) u8 size; u8 idx; - gUnknown_0203CD64->favour.unk_00c = Random() % 6; - size = sub_818DB04(gUnknown_0860B2EC[gUnknown_0203CD64->favour.unk_00c]); + gUnknown_0203CD64->unk_00c = Random() % 6; + size = sub_818DB04(gUnknown_0860B2EC[gUnknown_0203CD64->unk_00c]); idx = Random() % size; - gUnknown_0203CD64->favour.unk_010 = gUnknown_0860B2EC[gUnknown_0203CD64->favour.unk_00c][idx]; + gUnknown_0203CD64->unk_010 = gUnknown_0860B2EC[gUnknown_0203CD64->unk_00c][idx]; } void SetLilycoveFavourLady(void) { - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; - gUnknown_0203CD64->favour.id = LILYCOVE_LADY_FAVOUR; - gUnknown_0203CD64->favour.unk_001 = 0; - gUnknown_0203CD64->favour.unk_004[0] = EOS; - gUnknown_0203CD64->favour.unk_002 = 0; - gUnknown_0203CD64->favour.unk_003= 0; - gUnknown_0203CD64->favour.itemId = ITEM_NONE; - gUnknown_0203CD64->favour.language = gGameLanguage; + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; + gUnknown_0203CD64->id = LILYCOVE_LADY_FAVOUR; + gUnknown_0203CD64->unk_001 = 0; + gUnknown_0203CD64->unk_004[0] = EOS; + gUnknown_0203CD64->unk_002 = 0; + gUnknown_0203CD64->unk_003= 0; + gUnknown_0203CD64->itemId = ITEM_NONE; + gUnknown_0203CD64->language = gGameLanguage; sub_818DB20(); } void sub_818DBC4(void) { - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; - gUnknown_0203CD64->favour.id = LILYCOVE_LADY_FAVOUR; - gUnknown_0203CD64->favour.unk_001 = 0; + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; + gUnknown_0203CD64->id = LILYCOVE_LADY_FAVOUR; + gUnknown_0203CD64->unk_001 = 0; } u8 sub_818DBE8(void) { - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; - if (gUnknown_0203CD64->favour.unk_001 == 2) + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; + if (gUnknown_0203CD64->unk_001 == 2) { return 2; } - else if (gUnknown_0203CD64->favour.unk_001 == 1) + else if (gUnknown_0203CD64->unk_001 == 1) { return 1; } @@ -176,17 +180,17 @@ const u8 *sub_818DC1C(u8 idx) void sub_818DC2C(void) { - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; - StringCopy(gStringVar1, sub_818DC1C(gUnknown_0203CD64->favour.unk_00c)); + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; + StringCopy(gStringVar1, sub_818DC1C(gUnknown_0203CD64->unk_00c)); } bool8 sub_818DC60(void) { - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; - if (gUnknown_0203CD64->favour.unk_004[0] != EOS) + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; + if (gUnknown_0203CD64->unk_004[0] != EOS) { StringCopy7(gStringVar3, gSaveBlock1Ptr->lilycoveLady.favour.unk_004); - ConvertInternationalString(gStringVar3, gUnknown_0203CD64->favour.language); + ConvertInternationalString(gStringVar3, gUnknown_0203CD64->language); return TRUE; } return FALSE; @@ -199,8 +203,8 @@ void sub_818DCAC(u8 *dest, u16 itemId) void sub_818DCC8(void) { - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; - sub_818DCAC(gStringVar2, gUnknown_0203CD64->favour.itemId); + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; + sub_818DCAC(gStringVar2, gUnknown_0203CD64->itemId); } void sub_818DCF4(const u8 *src, u8 *dest) @@ -211,15 +215,15 @@ void sub_818DCF4(const u8 *src, u8 *dest) void sub_818DD14(void) { - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; sub_818DCF4(gSaveBlock1Ptr->lilycoveLady.favour.unk_004, gStringVar3); - ConvertInternationalString(gStringVar3, gUnknown_0203CD64->favour.language); + ConvertInternationalString(gStringVar3, gUnknown_0203CD64->language); } bool8 sub_818DD54(void) { - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; - return gUnknown_0203CD64->favour.unk_002 ? TRUE : FALSE; + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; + return gUnknown_0203CD64->unk_002 ? TRUE : FALSE; } void sub_818DD78(void) @@ -233,28 +237,28 @@ bool8 sub_818DD84(u16 itemId) u8 i; bool8 response; - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; - len = sub_818DB04(gUnknown_0860B2EC[gUnknown_0203CD64->favour.unk_00c]); - gUnknown_0203CD64->favour.unk_001 = 1; + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; + len = sub_818DB04(gUnknown_0860B2EC[gUnknown_0203CD64->unk_00c]); + gUnknown_0203CD64->unk_001 = 1; sub_818DCAC(gStringVar2, itemId); - gUnknown_0203CD64->favour.itemId = itemId; - sub_818DCF4(gSaveBlock2Ptr->playerName, gUnknown_0203CD64->favour.unk_004); - gUnknown_0203CD64->favour.language = gGameLanguage; + gUnknown_0203CD64->itemId = itemId; + sub_818DCF4(gSaveBlock2Ptr->playerName, gUnknown_0203CD64->unk_004); + gUnknown_0203CD64->language = gGameLanguage; response = FALSE; for (i = 0; i < len; i ++) { - if (gUnknown_0860B2EC[gUnknown_0203CD64->favour.unk_00c][i] == itemId) + if (gUnknown_0860B2EC[gUnknown_0203CD64->unk_00c][i] == itemId) { response = TRUE; - gUnknown_0203CD64->favour.unk_003 ++; - gUnknown_0203CD64->favour.unk_002 = 1; - if (gUnknown_0203CD64->favour.unk_010 == itemId) + gUnknown_0203CD64->unk_003 ++; + gUnknown_0203CD64->unk_002 = 1; + if (gUnknown_0203CD64->unk_010 == itemId) { - gUnknown_0203CD64->favour.unk_003 = 5; + gUnknown_0203CD64->unk_003 = 5; } break; } - gUnknown_0203CD64->favour.unk_002 = 0; + gUnknown_0203CD64->unk_002 = 0; } return response; } @@ -268,8 +272,8 @@ bool8 sub_818DE5C(void) { u8 checkval; - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; - checkval = gUnknown_0203CD64->favour.unk_003; + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; + checkval = gUnknown_0203CD64->unk_003; return checkval < 5 ? FALSE : TRUE; } @@ -282,20 +286,36 @@ u16 sub_818DEA0(void) { u16 itemId; - gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady; - itemId = gUnknown_0860B304[gUnknown_0203CD64->favour.unk_00c]; + gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; + itemId = gUnknown_0860B304[gUnknown_0203CD64->unk_00c]; sub_818DE88(itemId); - gUnknown_0203CD64->favour.unk_001 = 2; + gUnknown_0203CD64->unk_001 = 2; return itemId; } void sub_818DEDC(void) { SetLilycoveFavourLady(); - gUnknown_0203CD64->favour.unk_001 = 1; + gUnknown_0203CD64->unk_001 = 1; } void sub_818DEF4(void) { EnableBothScriptContexts(); } + +void sub_818DF00(void) +{ + u8 v0; + u8 i; + + v0 = Random() % 16; + for (i = 0; i < 9; i ++) + { + gUnknown_0203CD68->unk_002[i] = gUnknown_0860B1A4[v0][i]; + } + gUnknown_0203CD68->unk_014 = gUnknown_0860B1E4[v0]; + gUnknown_0203CD68->unk_028 = gUnknown_0860B204[v0]; + gUnknown_0203CD68->unk_02b = v0; + gUnknown_0203CD68->unk_018 = 0xFF; +} -- cgit v1.2.3 From 28d0fa33fef825dcb22d45db966ef814c461dd08 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 22:35:40 -0400 Subject: SetLilicoveQuizLady --- src/lilycove_lady.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index d64b0d3b3..901812ed6 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -319,3 +319,27 @@ void sub_818DF00(void) gUnknown_0203CD68->unk_02b = v0; gUnknown_0203CD68->unk_018 = 0xFF; } + +void SetLilycoveQuizLady(void) +{ + u8 i; + + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + gUnknown_0203CD68->id = LILYCOVE_LADY_QUIZ; + gUnknown_0203CD68->unk_001 = 0; + for (i = 0; i < 9; i ++) + { + gUnknown_0203CD68->unk_002[i] = -1; + } + gUnknown_0203CD68->unk_014 = -1; + gUnknown_0203CD68->unk_016 = -1; + for (i = 0; i < 4; i ++) + { + gUnknown_0203CD68->unk_020[i] = 0; + } + gUnknown_0203CD68->unk_028 = 0; + gUnknown_0203CD68->unk_02a = 0; + gUnknown_0203CD68->unk_02c = 0x10; + gUnknown_0203CD68->language = gGameLanguage; + sub_818DF00(); +} -- cgit v1.2.3 From 9b00767b55b70627aad81b67b87c06db9dca5742 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 22:57:22 -0400 Subject: sub_818E004; sanity --- src/lilycove_lady.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 901812ed6..c7a5ef68d 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -189,7 +189,7 @@ bool8 sub_818DC60(void) gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; if (gUnknown_0203CD64->unk_004[0] != EOS) { - StringCopy7(gStringVar3, gSaveBlock1Ptr->lilycoveLady.favour.unk_004); + StringCopy7(gStringVar3, gUnknown_0203CD64->unk_004); ConvertInternationalString(gStringVar3, gUnknown_0203CD64->language); return TRUE; } @@ -216,7 +216,7 @@ void sub_818DCF4(const u8 *src, u8 *dest) void sub_818DD14(void) { gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; - sub_818DCF4(gSaveBlock1Ptr->lilycoveLady.favour.unk_004, gStringVar3); + sub_818DCF4(gUnknown_0203CD64->unk_004, gStringVar3); ConvertInternationalString(gStringVar3, gUnknown_0203CD64->language); } @@ -343,3 +343,12 @@ void SetLilycoveQuizLady(void) gUnknown_0203CD68->language = gGameLanguage; sub_818DF00(); } + +void sub_818E004(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + gUnknown_0203CD68->id = LILYCOVE_LADY_QUIZ; + gUnknown_0203CD68->unk_001 = 0; + gUnknown_0203CD68->unk_02a = 0; + gUnknown_0203CD68->unk_016 = -1; +} -- cgit v1.2.3 From c05f2d44732020ed43f5500a26130ec94e34d657 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Tue, 19 Sep 2017 23:31:05 -0400 Subject: sub_818E06C --- src/lilycove_lady.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index c7a5ef68d..93c3cce67 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -20,6 +20,9 @@ void SetLilycoveContestLady(void); void sub_818E004(void); void sub_818DBC4(void); void sub_818E674(void); +bool32 sub_811F8D8(u16); +u8 sub_818E13C(void); +bool8 sub_818E1F4(void); extern const u16 gUnknown_0860B074[5]; extern const u16 gUnknown_0860B07E[3]; @@ -352,3 +355,62 @@ void sub_818E004(void) gUnknown_0203CD68->unk_02a = 0; gUnknown_0203CD68->unk_016 = -1; } + +u8 sub_818E038(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + if (gUnknown_0203CD68->unk_001 == 2) + { + return 2; + } + else if (gUnknown_0203CD68->unk_001 == 1) + { + return 1; + } + else + { + return 0; + } +} + +u8 sub_818E06C(void) +{ + int i; + int j; + u8 rv; + struct LilycoveLadyQuiz *quiz; + + quiz = &gSaveBlock1Ptr->lilycoveLady.quiz; + if (sub_811F8D8(quiz->unk_014) == 0) + { + i = quiz->unk_02b; + do + { + if (++ i >= 16) + { + i = 0; + } + } while (sub_811F8D8(gUnknown_0860B1E4[i]) == 0); + for (j = 0; j < 9; j ++) + { + quiz->unk_002[j] = gUnknown_0860B1A4[i][j]; + } + quiz->unk_014 = gUnknown_0860B1E4[i]; + quiz->unk_028 = gUnknown_0860B204[i]; + quiz->unk_02b = i; + quiz->unk_018 = 0xFF; + } + rv = sub_818E13C(); + if (rv == 0) + { + return 2; + } + else if (rv == 2 || sub_818E1F4()) + { + return 1; + } + else + { + return 0; + } +} -- cgit v1.2.3 From 28da80e19af3270b827e98c2e7c69c0199d14d05 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 20 Sep 2017 12:56:45 +0200 Subject: battle 4 up to SetMoveEffect --- src/battle_4.c | 399 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 382 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/battle_4.c b/src/battle_4.c index be7f712c6..5d867289b 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -14,6 +14,7 @@ #include "rng.h" #include "battle_controllers.h" #include "species.h" +#include "songs.h" // variables @@ -58,7 +59,7 @@ extern u8 gStringBank; extern u16 gDynamicBasePower; extern u16 gLastUsedItem; extern u16 gBattleMovePower; -extern s32 gHP_dealt; +extern s32 gHpDealt; extern s32 gTakenDmg[BATTLE_BANKS_COUNT]; extern u8 gTakenDmgBanks[BATTLE_BANKS_COUNT]; extern u8 gSentPokesToOpponent[2]; @@ -75,7 +76,7 @@ extern u8 gCurrentMoveTurn; extern u8 gBattleBufferB[4][0x200]; extern const struct BattleMove gBattleMoves[]; -extern const u16 gMissStrings[]; +extern const u16 gMissStringIds[]; extern const u8 gTrainerMoney[]; extern const u8 gTypeEffectiveness[]; extern const struct BaseStats gBaseStats[]; @@ -1630,31 +1631,395 @@ void atk0A_waitanimation(void) void atk0B_healthbarupdate(void) { - register s16 healthValue asm("r1"); + if (gBattleExecBuffer) + return; + + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) + { + PrepareStringBattle(0x80, gActiveBank); + } + else + { + s16 healthValue; + + s32 currDmg = gBattleMoveDamage; + s32 maxPossibleDmgValue = 10000; // not present in R/S, ensures that huge damage values don't change sign + + if (currDmg <= maxPossibleDmgValue) + healthValue = currDmg; + else + healthValue = maxPossibleDmgValue; + + EmitHealthBarUpdate(0, healthValue); + MarkBufferBankForExecution(gActiveBank); + + if (GetBankSide(gActiveBank) == SIDE_PLAYER && gBattleMoveDamage > 0) + gBattleResults.unk5_0 = 1; + } + } + + gBattlescriptCurrInstr += 2; +} + +void atk0C_datahpupdate(void) +{ + u32 moveType; if (gBattleExecBuffer) return; - if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) - goto END; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + if (gBattleStruct->dynamicMoveType == 0) + moveType = gBattleMoves[gCurrentMove].type; + else if (!(gBattleStruct->dynamicMoveType & 0x40)) + moveType = gBattleStruct->dynamicMoveType & 0x3F; + else + moveType = gBattleMoves[gCurrentMove].type; - if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) { - PrepareStringBattle(0x80, gActiveBank); - goto END; + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) + { + if (gDisableStructs[gActiveBank].substituteHP >= gBattleMoveDamage) + { + if (gSpecialStatuses[gActiveBank].moveturnLostHP == 0) + gSpecialStatuses[gActiveBank].moveturnLostHP = gBattleMoveDamage; + gDisableStructs[gActiveBank].substituteHP -= gBattleMoveDamage; + gHpDealt = gBattleMoveDamage; + } + else + { + if (gSpecialStatuses[gActiveBank].moveturnLostHP == 0) + gSpecialStatuses[gActiveBank].moveturnLostHP = gDisableStructs[gActiveBank].substituteHP; + gHpDealt = gDisableStructs[gActiveBank].substituteHP; + gDisableStructs[gActiveBank].substituteHP = 0; + } + // check substitute fading + if (gDisableStructs[gActiveBank].substituteHP == 0) + { + gBattlescriptCurrInstr += 2; + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_SubstituteFade; + return; + } + } + else + { + gHitMarker &= ~(HITMARKER_IGNORE_SUBSTITUTE); + if (gBattleMoveDamage < 0) // hp goes up + { + gBattleMons[gActiveBank].hp -= gBattleMoveDamage; + if (gBattleMons[gActiveBank].hp > gBattleMons[gActiveBank].maxHP) + gBattleMons[gActiveBank].hp = gBattleMons[gActiveBank].maxHP; + + } + else // hp goes down + { + if (gHitMarker & HITMARKER_x20) + { + gHitMarker &= ~(HITMARKER_x20); + } + else + { + gTakenDmg[gActiveBank] += gBattleMoveDamage; + if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_TARGET) + gTakenDmgBanks[gActiveBank] = gBankAttacker; + else + gTakenDmgBanks[gActiveBank] = gBankTarget; + } + + if (gBattleMons[gActiveBank].hp > gBattleMoveDamage) + { + gBattleMons[gActiveBank].hp -= gBattleMoveDamage; + gHpDealt = gBattleMoveDamage; + } + else + { + gHpDealt = gBattleMons[gActiveBank].hp; + gBattleMons[gActiveBank].hp = 0; + } + + if (!gSpecialStatuses[gActiveBank].moveturnLostHP && !(gHitMarker & HITMARKER_x100000)) + gSpecialStatuses[gActiveBank].moveturnLostHP = gHpDealt; + + if (moveType <= 8 && !(gHitMarker & HITMARKER_x100000) && gCurrentMove != MOVE_PAIN_SPLIT) + { + gProtectStructs[gActiveBank].physicalDmg = gHpDealt; + gSpecialStatuses[gActiveBank].moveturnLostHP_physical = gHpDealt; + if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_TARGET) + { + gProtectStructs[gActiveBank].physicalBank = gBankAttacker; + gSpecialStatuses[gActiveBank].moveturnPhysicalBank = gBankAttacker; + } + else + { + gProtectStructs[gActiveBank].physicalBank = gBankTarget; + gSpecialStatuses[gActiveBank].moveturnPhysicalBank = gBankTarget; + } + } + else if (moveType > 8 && !(gHitMarker & HITMARKER_x100000)) + { + gProtectStructs[gActiveBank].specialDmg = gHpDealt; + gSpecialStatuses[gActiveBank].moveturnLostHP_special = gHpDealt; + if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_TARGET) + { + gProtectStructs[gActiveBank].specialBank = gBankAttacker; + gSpecialStatuses[gActiveBank].moveturnSpecialBank = gBankAttacker; + } + else + { + gProtectStructs[gActiveBank].specialBank = gBankTarget; + gSpecialStatuses[gActiveBank].moveturnSpecialBank = gBankTarget; + } + } + } + gHitMarker &= ~(HITMARKER_x100000); + EmitSetAttributes(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBank].hp); + MarkBufferBankForExecution(gActiveBank); + } + } + else + { + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + if (gSpecialStatuses[gActiveBank].moveturnLostHP == 0) + gSpecialStatuses[gActiveBank].moveturnLostHP = 0xFFFF; + } + gBattlescriptCurrInstr += 2; +} + +void atk0D_critmessage(void) +{ + if (gBattleExecBuffer == 0) + { + if (gCritMultiplier == 2 && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + PrepareStringBattle(0xD9, gBankAttacker); + gBattleCommunication[MSG_DISPLAY] = 1; + } + gBattlescriptCurrInstr++; + } +} + +void atk0E_effectiveness_sound(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBank = gBankTarget; + if (!(gBattleMoveFlags & MOVESTATUS_MISSED)) + { + switch (gBattleMoveFlags & (u8)(~(MOVESTATUS_MISSED))) + { + case MOVESTATUS_SUPEREFFECTIVE: + EmitEffectivenessSound(0, SE_KOUKA_H); + MarkBufferBankForExecution(gActiveBank); + break; + case MOVESTATUS_NOTVERYEFFECTIVE: + EmitEffectivenessSound(0, SE_KOUKA_L); + MarkBufferBankForExecution(gActiveBank); + break; + case MOVESTATUS_NOTAFFECTED: + case MOVESTATUS_FAILED: + // no sound + break; + case MOVESTATUS_ENDURED: + case MOVESTATUS_ONEHITKO: + case MOVESTATUS_HUNGON: + default: + if (gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE) + { + EmitEffectivenessSound(0, SE_KOUKA_H); + MarkBufferBankForExecution(gActiveBank); + } + else if (gBattleMoveFlags & MOVESTATUS_NOTVERYEFFECTIVE) + { + EmitEffectivenessSound(0, SE_KOUKA_L); + MarkBufferBankForExecution(gActiveBank); + } + else if (!(gBattleMoveFlags & (MOVESTATUS_NOTAFFECTED | MOVESTATUS_FAILED))) + { + EmitEffectivenessSound(0, SE_KOUKA_M); + MarkBufferBankForExecution(gActiveBank); + } + break; + } + } + gBattlescriptCurrInstr++; +} + +void atk0F_resultmessage(void) +{ + u32 stringId = 0; + + if (gBattleExecBuffer) + return; + + if (gBattleMoveFlags & MOVESTATUS_MISSED && (!(gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) || gBattleCommunication[6] > 2)) + { + stringId = gMissStringIds[gBattleCommunication[6]]; + gBattleCommunication[MSG_DISPLAY] = 1; + } + else + { + gBattleCommunication[MSG_DISPLAY] = 1; + switch (gBattleMoveFlags & (u8)(~(MOVESTATUS_MISSED))) + { + case MOVESTATUS_SUPEREFFECTIVE: + stringId = 0xDE; + break; + case MOVESTATUS_NOTVERYEFFECTIVE: + stringId = 0xDD; + break; + case MOVESTATUS_ONEHITKO: + stringId = 0xDA; + break; + case MOVESTATUS_ENDURED: + stringId = 0x99; + break; + case MOVESTATUS_FAILED: + stringId = 0xE5; + break; + case MOVESTATUS_NOTAFFECTED: + stringId = 0x1B; + break; + case MOVESTATUS_HUNGON: + gLastUsedItem = gBattleMons[gBankTarget].item; + gStringBank = gBankTarget; + gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_HangedOnMsg; + return; + default: + if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) + { + stringId = 0x1B; + } + else if (gBattleMoveFlags & MOVESTATUS_ONEHITKO) + { + gBattleMoveFlags &= ~(MOVESTATUS_ONEHITKO); + gBattleMoveFlags &= ~(MOVESTATUS_SUPEREFFECTIVE); + gBattleMoveFlags &= ~(MOVESTATUS_NOTVERYEFFECTIVE); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_OneHitKOMsg; + return; + } + else if (gBattleMoveFlags & MOVESTATUS_ENDURED) + { + gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_EnduredMsg; + return; + } + else if (gBattleMoveFlags & MOVESTATUS_HUNGON) + { + gLastUsedItem = gBattleMons[gBankTarget].item; + gStringBank = gBankTarget; + gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_HangedOnMsg; + return; + } + else if (gBattleMoveFlags & MOVESTATUS_FAILED) + { + stringId = 0xE5; + } + else + { + gBattleCommunication[MSG_DISPLAY] = 0; + } + } + } + + if (stringId) + PrepareStringBattle(stringId, gBankAttacker); + + gBattlescriptCurrInstr++; +} + +void atk10_printstring(void) +{ + if (gBattleExecBuffer == 0) + { + u16 var = BS2ScriptRead16(gBattlescriptCurrInstr + 1); + PrepareStringBattle(var, gBankAttacker); + gBattlescriptCurrInstr += 3; + gBattleCommunication[MSG_DISPLAY] = 1; } +} - healthValue = 10000; - if (healthValue <= gBattleMoveDamage) - healthValue = gBattleMoveDamage; +void atk11_printstring_playeronly(void) +{ + gActiveBank = gBankAttacker; - EmitHealthBarUpdate(0, healthValue); + EmitPrintStringPlayerOnly(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1)); MarkBufferBankForExecution(gActiveBank); - if (GetBankSide(gActiveBank) == SIDE_PLAYER && gBattleMoveDamage > 0) - gBattleResults.unk5_0 = 1; + gBattlescriptCurrInstr += 3; + gBattleCommunication[MSG_DISPLAY] = 1; +} - END: - gBattlescriptCurrInstr += 2; +void atk12_waitmessage(void) +{ + if (gBattleExecBuffer == 0) + { + if (!gBattleCommunication[MSG_DISPLAY]) + { + gBattlescriptCurrInstr += 3; + } + else + { + u16 toWait = BS2ScriptRead16(gBattlescriptCurrInstr + 1); + if (++gPauseCounterBattle >= toWait) + { + gPauseCounterBattle = 0; + gBattlescriptCurrInstr += 3; + gBattleCommunication[MSG_DISPLAY] = 0; + } + } + } +} + +void atk13_printfromtable(void) +{ + if (gBattleExecBuffer == 0) + { + u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + ptr += gBattleCommunication[MULTISTRING_CHOOSER]; + + PrepareStringBattle(*(u16*)ptr, gBankAttacker); + + gBattlescriptCurrInstr += 5; + gBattleCommunication[MSG_DISPLAY] = 1; + } +} + +void atk14_printfromtable_playeronly(void) +{ + if (gBattleExecBuffer == 0) + { + u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + ptr += gBattleCommunication[MULTISTRING_CHOOSER]; + + gActiveBank = gBankAttacker; + EmitPrintStringPlayerOnly(0, *(u16*)ptr); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 5; + gBattleCommunication[MSG_DISPLAY] = 1; + } +} + +u8 BankGetTurnOrder(u8 bank) +{ + s32 i; + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gTurnOrder[i] == bank) + break; + } + return i; } -- cgit v1.2.3 From 0b81c2920aa87aae3403efdf60e40b58445efbbf Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 20 Sep 2017 10:45:00 -0400 Subject: sub_818E1F4 --- src/lilycove_lady.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 143 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 93c3cce67..196867369 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -23,6 +23,7 @@ void sub_818E674(void); bool32 sub_811F8D8(u16); u8 sub_818E13C(void); bool8 sub_818E1F4(void); +u8 sub_818E258(const u8 *); extern const u16 gUnknown_0860B074[5]; extern const u16 gUnknown_0860B07E[3]; @@ -32,6 +33,7 @@ extern const u16 gUnknown_0860B304[6]; extern const u16 *const gUnknown_0860B1A4[16]; extern const u16 gUnknown_0860B1E4[16]; extern const u16 gUnknown_0860B204[16]; +extern const u8 gUnknown_085EEB7E[8]; EWRAM_DATA struct LilycoveLadyFavour *gUnknown_0203CD64 = NULL; EWRAM_DATA struct LilycoveLadyQuiz *gUnknown_0203CD68 = NULL; @@ -144,7 +146,7 @@ void SetLilycoveFavourLady(void) gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; gUnknown_0203CD64->id = LILYCOVE_LADY_FAVOUR; gUnknown_0203CD64->unk_001 = 0; - gUnknown_0203CD64->unk_004[0] = EOS; + gUnknown_0203CD64->playerName[0] = EOS; gUnknown_0203CD64->unk_002 = 0; gUnknown_0203CD64->unk_003= 0; gUnknown_0203CD64->itemId = ITEM_NONE; @@ -190,9 +192,9 @@ void sub_818DC2C(void) bool8 sub_818DC60(void) { gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; - if (gUnknown_0203CD64->unk_004[0] != EOS) + if (gUnknown_0203CD64->playerName[0] != EOS) { - StringCopy7(gStringVar3, gUnknown_0203CD64->unk_004); + StringCopy7(gStringVar3, gUnknown_0203CD64->playerName); ConvertInternationalString(gStringVar3, gUnknown_0203CD64->language); return TRUE; } @@ -219,7 +221,7 @@ void sub_818DCF4(const u8 *src, u8 *dest) void sub_818DD14(void) { gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; - sub_818DCF4(gUnknown_0203CD64->unk_004, gStringVar3); + sub_818DCF4(gUnknown_0203CD64->playerName, gStringVar3); ConvertInternationalString(gStringVar3, gUnknown_0203CD64->language); } @@ -245,7 +247,7 @@ bool8 sub_818DD84(u16 itemId) gUnknown_0203CD64->unk_001 = 1; sub_818DCAC(gStringVar2, itemId); gUnknown_0203CD64->itemId = itemId; - sub_818DCF4(gSaveBlock2Ptr->playerName, gUnknown_0203CD64->unk_004); + sub_818DCF4(gSaveBlock2Ptr->playerName, gUnknown_0203CD64->playerName); gUnknown_0203CD64->language = gGameLanguage; response = FALSE; for (i = 0; i < len; i ++) @@ -311,7 +313,7 @@ void sub_818DF00(void) { u8 v0; u8 i; - + v0 = Random() % 16; for (i = 0; i < 9; i ++) { @@ -320,7 +322,7 @@ void sub_818DF00(void) gUnknown_0203CD68->unk_014 = gUnknown_0860B1E4[v0]; gUnknown_0203CD68->unk_028 = gUnknown_0860B204[v0]; gUnknown_0203CD68->unk_02b = v0; - gUnknown_0203CD68->unk_018 = 0xFF; + gUnknown_0203CD68->playerName[0] = EOS; } void SetLilycoveQuizLady(void) @@ -338,7 +340,7 @@ void SetLilycoveQuizLady(void) gUnknown_0203CD68->unk_016 = -1; for (i = 0; i < 4; i ++) { - gUnknown_0203CD68->unk_020[i] = 0; + gUnknown_0203CD68->playerTrainerId[i] = 0; } gUnknown_0203CD68->unk_028 = 0; gUnknown_0203CD68->unk_02a = 0; @@ -398,7 +400,7 @@ u8 sub_818E06C(void) quiz->unk_014 = gUnknown_0860B1E4[i]; quiz->unk_028 = gUnknown_0860B204[i]; quiz->unk_02b = i; - quiz->unk_018 = 0xFF; + quiz->playerName[0] = EOS; } rv = sub_818E13C(); if (rv == 0) @@ -414,3 +416,135 @@ u8 sub_818E06C(void) return 0; } } + +#ifdef NONMATCHING +u8 sub_818E13C(void) +{ + u8 retval; + u8 len; + u8 i; + + retval = 1; + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + if (gUnknown_0203CD68->playerName[0] == EOS) + { + StringCopy7(gStringVar1, gUnknown_085EEB7E); + retval = 0; + } + else + { + StringCopy7(gStringVar1, gUnknown_0203CD68->playerName); + ConvertInternationalString(gStringVar1, gUnknown_0203CD68->language); + len = sub_818E258(gUnknown_0203CD68->playerName); + if (len == sub_818E258(gSaveBlock2Ptr->playerName)) + { + for (i = 0; i < len; i ++) + { + if (gUnknown_0203CD68->playerName[i] != gSaveBlock2Ptr->playerName[i]) + { + retval = 2; + break; + } + } + } + + } + return retval; +} +#else +__attribute__((naked)) u8 sub_818E13C(void) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tmovs r7, 0x1\n" + "\tldr r5, =gUnknown_0203CD68\n" + "\tldr r0, =gSaveBlock1Ptr\n" + "\tldr r1, [r0]\n" + "\tldr r2, =0x00003b58\n" + "\tadds r0, r1, r2\n" + "\tstr r0, [r5]\n" + "\tldrb r0, [r0, 0x18]\n" + "\tcmp r0, 0xFF\n" + "\tbne _0818E174\n" + "\tldr r0, =gStringVar1\n" + "\tldr r1, =gUnknown_085EEB7E\n" + "\tbl StringCopy7\n" + "\tmovs r7, 0\n" + "\tb _0818E1DC\n" + "\t.pool\n" + "_0818E174:\n" + "\tldr r4, =gStringVar1\n" + "\tldr r0, =0x00003b70\n" + "\tadds r1, r0\n" + "\tadds r0, r4, 0\n" + "\tbl StringCopy7\n" + "\tldr r0, [r5]\n" + "\tadds r0, 0x2D\n" + "\tldrb r1, [r0]\n" + "\tadds r0, r4, 0\n" + "\tbl ConvertInternationalString\n" + "\tldr r0, [r5]\n" + "\tadds r0, 0x18\n" + "\tbl sub_818E258\n" + "\tlsls r0, 24\n" + "\tlsrs r4, r0, 24\n" + "\tldr r6, =gSaveBlock2Ptr\n" + "\tldr r0, [r6]\n" + "\tbl sub_818E258\n" + "\tlsls r0, 24\n" + "\tlsrs r0, 24\n" + "\tcmp r4, r0\n" + "\tbne _0818E1DC\n" + "\tldr r0, [r5]\n" + "\tmovs r2, 0\n" + "\tcmp r2, r4\n" + "\tbcs _0818E1DC\n" + "\tldr r1, [r6]\n" + "\tldrb r0, [r0, 0x18]\n" + "\tldrb r1, [r1]\n" + "\tcmp r0, r1\n" + "\tbne _0818E1DA\n" + "_0818E1BA:\n" + "\tadds r0, r2, 0x1\n" + "\tlsls r0, 24\n" + "\tlsrs r2, r0, 24\n" + "\tcmp r2, r4\n" + "\tbcs _0818E1DC\n" + "\tldr r0, =gUnknown_0203CD68\n" + "\tldr r1, [r0]\n" + "\tadds r1, 0x18\n" + "\tadds r1, r2\n" + "\tldr r0, =gSaveBlock2Ptr\n" + "\tldr r0, [r0]\n" + "\tadds r0, r2\n" + "\tldrb r1, [r1]\n" + "\tldrb r0, [r0]\n" + "\tcmp r1, r0\n" + "\tbeq _0818E1BA\n" + "_0818E1DA:\n" + "\tmovs r7, 0x2\n" + "_0818E1DC:\n" + "\tadds r0, r7, 0\n" + "\tpop {r4-r7}\n" + "\tpop {r1}\n" + "\tbx r1\n" + "\t.pool"); +} +#endif + +u8 sub_818E1F4(void) +{ + u8 response; + u8 i; + + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + response = 0; + for (i = 0; i < 4; i ++) + { + if (gUnknown_0203CD68->playerTrainerId[i] != gSaveBlock2Ptr->playerTrainerId[i]) + { + response = 1; + break; + } + } + return response; +} -- cgit v1.2.3 From 0895d8d861ca7db6d8fa2910f6275eb6b615340e Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 20 Sep 2017 11:25:46 -0400 Subject: sub_818E258 --- src/lilycove_lady.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 196867369..564b089a6 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -548,3 +548,12 @@ u8 sub_818E1F4(void) } return response; } + +u8 sub_818E258(const u8 *str) +{ + u8 len; + const u8 *ptr; + + for (len = 0, ptr = str; *ptr != EOS; len ++, ptr ++); + return len; +} -- cgit v1.2.3 From 8a31e58689af6e62c8c272c24397310c2a44f6f5 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 20 Sep 2017 11:30:09 -0400 Subject: sub_818E298 --- src/lilycove_lady.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 564b089a6..976ed4d88 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -320,7 +320,7 @@ void sub_818DF00(void) gUnknown_0203CD68->unk_002[i] = gUnknown_0860B1A4[v0][i]; } gUnknown_0203CD68->unk_014 = gUnknown_0860B1E4[v0]; - gUnknown_0203CD68->unk_028 = gUnknown_0860B204[v0]; + gUnknown_0203CD68->itemId = gUnknown_0860B204[v0]; gUnknown_0203CD68->unk_02b = v0; gUnknown_0203CD68->playerName[0] = EOS; } @@ -342,7 +342,7 @@ void SetLilycoveQuizLady(void) { gUnknown_0203CD68->playerTrainerId[i] = 0; } - gUnknown_0203CD68->unk_028 = 0; + gUnknown_0203CD68->itemId = ITEM_NONE; gUnknown_0203CD68->unk_02a = 0; gUnknown_0203CD68->unk_02c = 0x10; gUnknown_0203CD68->language = gGameLanguage; @@ -398,7 +398,7 @@ u8 sub_818E06C(void) quiz->unk_002[j] = gUnknown_0860B1A4[i][j]; } quiz->unk_014 = gUnknown_0860B1E4[i]; - quiz->unk_028 = gUnknown_0860B204[i]; + quiz->itemId = gUnknown_0860B204[i]; quiz->unk_02b = i; quiz->playerName[0] = EOS; } @@ -533,16 +533,16 @@ __attribute__((naked)) u8 sub_818E13C(void) u8 sub_818E1F4(void) { - u8 response; + bool8 response; u8 i; gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; - response = 0; + response = FALSE; for (i = 0; i < 4; i ++) { if (gUnknown_0203CD68->playerTrainerId[i] != gSaveBlock2Ptr->playerTrainerId[i]) { - response = 1; + response = TRUE; break; } } @@ -557,3 +557,19 @@ u8 sub_818E258(const u8 *str) for (len = 0, ptr = str; *ptr != EOS; len ++, ptr ++); return len; } + +void sub_818E274(void) +{ + StringCopy(gStringVar1, ItemId_GetItem(gUnknown_0203CD68->itemId)->name); +} + +bool8 sub_818E298(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + if (!sub_818E13C()) + { + gUnknown_0203CD68->language = gGameLanguage; + return TRUE; + } + return FALSE; +} -- cgit v1.2.3 From 213fef604247d31f6981bd83c703bb1d3e1bbd31 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 20 Sep 2017 11:44:20 -0400 Subject: through sub_818E308 --- src/lilycove_lady.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 976ed4d88..485a0c9d4 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -12,6 +12,7 @@ #include "items.h" #include "item_menu.h" #include "text.h" +#include "easy_chat.h" #include "lilycove_lady.h" void SetLilycoveQuizLady(void); @@ -573,3 +574,22 @@ bool8 sub_818E298(void) } return FALSE; } + +u8 sub_818E2D8(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + return gUnknown_0203CD68->unk_02a; +} + +void sub_818E2FC(void) +{ + easy_chat_input_maybe(); +} + +bool8 sub_818E308(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + CopyEasyChatWord(gStringVar1, gUnknown_0203CD68->unk_014); + CopyEasyChatWord(gStringVar2, gUnknown_0203CD68->unk_016); + return StringCompare(gStringVar1, gStringVar2) ? FALSE : TRUE; +} -- cgit v1.2.3 From fdea92edffb4360db50cb0e7dcc044dc7242defe Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 20 Sep 2017 11:48:11 -0400 Subject: through sub_818E3E0 --- src/lilycove_lady.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 485a0c9d4..c4a0b9c11 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -593,3 +593,32 @@ bool8 sub_818E308(void) CopyEasyChatWord(gStringVar2, gUnknown_0203CD68->unk_016); return StringCompare(gStringVar1, gStringVar2) ? FALSE : TRUE; } + +void sub_818E358(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + gSpecialVar_0x8005 = gUnknown_0203CD68->itemId; +} + +void sub_818E37C(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + gUnknown_0203CD68->unk_001 = 1; +} + +void sub_818E39C(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + gUnknown_0203CD68->unk_001 = 2; +} + +void sub_818E3BC(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + gUnknown_0203CD68->unk_016 = -1; +} + +void sub_818E3E0(void) +{ + sub_81AAC70(); +} -- cgit v1.2.3 From 5fb39d5ef9f7c19ecff2b347cf7785ea8fc63ad9 Mon Sep 17 00:00:00 2001 From: scnorton Date: Wed, 20 Sep 2017 12:56:45 -0400 Subject: sub_818E3EC --- src/lilycove_lady.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index c4a0b9c11..65f6e2e10 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -622,3 +622,17 @@ void sub_818E3E0(void) { sub_81AAC70(); } + +void sub_818E3EC(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + if (sub_818E298()) + { + gUnknown_0203CD68->unk_02c = gUnknown_0203CD68->unk_02b; + } + else + { + gUnknown_0203CD68->unk_02c = 0x10; + } + sub_818DF00(); +} -- cgit v1.2.3 From d22a9acc63b9f7c72e0d7ec81396b799af94e270 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 16:12:18 -0400 Subject: through sub_818E490 --- src/lilycove_lady.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 65f6e2e10..a0482a28f 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -636,3 +636,26 @@ void sub_818E3EC(void) } sub_818DF00(); } + +void sub_818E430(void) +{ + u8 i; + + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + for (i = 0; i < 9; i ++) + { + gUnknown_0203CD68->unk_002[i] = -1; + } + gUnknown_0203CD68->unk_014 = -1; +} + +void sub_818E47C(void) +{ + gSpecialVar_0x8004 = 0x11; + easy_chat_input_maybe(); +} + +void sub_818E490(void) +{ + RemoveBagItem(gScriptItemId, 1); +} -- cgit v1.2.3 From 44e75e1f0303248638d3ab4b7115a1c7db24dbf0 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 16:32:37 -0400 Subject: through sub_818E570 --- src/lilycove_lady.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index a0482a28f..61b5488a1 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -38,6 +38,8 @@ extern const u8 gUnknown_085EEB7E[8]; EWRAM_DATA struct LilycoveLadyFavour *gUnknown_0203CD64 = NULL; EWRAM_DATA struct LilycoveLadyQuiz *gUnknown_0203CD68 = NULL; +EWRAM_DATA struct LilycoveLadyContest *gUnknown_0203CD6C = NULL; + extern EWRAM_DATA u16 gScriptItemId; u8 GetLilycoveLadyId(void) @@ -659,3 +661,57 @@ void sub_818E490(void) { RemoveBagItem(gScriptItemId, 1); } + +void sub_818E4A4(void) +{ + u8 i; + + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + gUnknown_0203CD68->itemId = gScriptItemId; + for (i = 0; i < 4; i ++) + { + gUnknown_0203CD68->playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i]; + } + StringCopy7(gUnknown_0203CD68->playerName, gSaveBlock2Ptr->playerName); + gUnknown_0203CD68->language = gGameLanguage; +} + +void sub_818E510(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + gUnknown_0203CD68->unk_02a = 1; +} + +void sub_818E538(void) +{ + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + CopyEasyChatWord(gStringVar3, gUnknown_0203CD68->unk_014); +} + +void sub_818E564(void) +{ + EnableBothScriptContexts(); +} + +void sub_818E570(const struct LilycoveLadyQuiz *quiz) +{ + u8 i; + + gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; + if (quiz->unk_02c < 16 && gUnknown_0203CD68->id == LILYCOVE_LADY_QUIZ) + { + for (i = 0; i < 4; i ++) + { + if (quiz->unk_02c != gUnknown_0203CD68->unk_02b) + { + break; + } + gUnknown_0203CD68->unk_02b = Random() % 16; + } + if (quiz->unk_02c == gUnknown_0203CD68->unk_02b) + { + gUnknown_0203CD68->unk_02b = (gUnknown_0203CD68->unk_02b + 1) % 16; + } + gUnknown_0203CD68->unk_02c = quiz->unk_02c; + } +} -- cgit v1.2.3 From 7c8cbc6b88d745da215fc45730f84b598869438f Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 16:49:22 -0400 Subject: SetLilycoveContestLady --- src/lilycove_lady.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 61b5488a1..f6471828b 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -44,7 +44,7 @@ extern EWRAM_DATA u16 gScriptItemId; u8 GetLilycoveLadyId(void) { - return gSaveBlock1Ptr->lilycoveLady.common.id; + return gSaveBlock1Ptr->lilycoveLady.id; } void sub_818D9C0(void) @@ -148,7 +148,7 @@ void SetLilycoveFavourLady(void) { gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; gUnknown_0203CD64->id = LILYCOVE_LADY_FAVOUR; - gUnknown_0203CD64->unk_001 = 0; + gUnknown_0203CD64->phase = 0; gUnknown_0203CD64->playerName[0] = EOS; gUnknown_0203CD64->unk_002 = 0; gUnknown_0203CD64->unk_003= 0; @@ -161,17 +161,17 @@ void sub_818DBC4(void) { gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; gUnknown_0203CD64->id = LILYCOVE_LADY_FAVOUR; - gUnknown_0203CD64->unk_001 = 0; + gUnknown_0203CD64->phase = 0; } u8 sub_818DBE8(void) { gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; - if (gUnknown_0203CD64->unk_001 == 2) + if (gUnknown_0203CD64->phase == 2) { return 2; } - else if (gUnknown_0203CD64->unk_001 == 1) + else if (gUnknown_0203CD64->phase == 1) { return 1; } @@ -247,7 +247,7 @@ bool8 sub_818DD84(u16 itemId) gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; len = sub_818DB04(gUnknown_0860B2EC[gUnknown_0203CD64->unk_00c]); - gUnknown_0203CD64->unk_001 = 1; + gUnknown_0203CD64->phase = 1; sub_818DCAC(gStringVar2, itemId); gUnknown_0203CD64->itemId = itemId; sub_818DCF4(gSaveBlock2Ptr->playerName, gUnknown_0203CD64->playerName); @@ -297,14 +297,14 @@ u16 sub_818DEA0(void) gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; itemId = gUnknown_0860B304[gUnknown_0203CD64->unk_00c]; sub_818DE88(itemId); - gUnknown_0203CD64->unk_001 = 2; + gUnknown_0203CD64->phase = 2; return itemId; } void sub_818DEDC(void) { SetLilycoveFavourLady(); - gUnknown_0203CD64->unk_001 = 1; + gUnknown_0203CD64->phase = 1; } void sub_818DEF4(void) @@ -334,7 +334,7 @@ void SetLilycoveQuizLady(void) gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; gUnknown_0203CD68->id = LILYCOVE_LADY_QUIZ; - gUnknown_0203CD68->unk_001 = 0; + gUnknown_0203CD68->phase = 0; for (i = 0; i < 9; i ++) { gUnknown_0203CD68->unk_002[i] = -1; @@ -356,7 +356,7 @@ void sub_818E004(void) { gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; gUnknown_0203CD68->id = LILYCOVE_LADY_QUIZ; - gUnknown_0203CD68->unk_001 = 0; + gUnknown_0203CD68->phase = 0; gUnknown_0203CD68->unk_02a = 0; gUnknown_0203CD68->unk_016 = -1; } @@ -364,11 +364,11 @@ void sub_818E004(void) u8 sub_818E038(void) { gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; - if (gUnknown_0203CD68->unk_001 == 2) + if (gUnknown_0203CD68->phase == 2) { return 2; } - else if (gUnknown_0203CD68->unk_001 == 1) + else if (gUnknown_0203CD68->phase == 1) { return 1; } @@ -605,13 +605,13 @@ void sub_818E358(void) void sub_818E37C(void) { gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; - gUnknown_0203CD68->unk_001 = 1; + gUnknown_0203CD68->phase = 1; } void sub_818E39C(void) { gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; - gUnknown_0203CD68->unk_001 = 2; + gUnknown_0203CD68->phase = 2; } void sub_818E3BC(void) @@ -715,3 +715,21 @@ void sub_818E570(const struct LilycoveLadyQuiz *quiz) gUnknown_0203CD68->unk_02c = quiz->unk_02c; } } + +void sub_818E604(void) +{ + gUnknown_0203CD6C->playerName[0] = EOS; + gUnknown_0203CD6C->fave_pkblk = 0; + gUnknown_0203CD6C->other_pkblk = 0; + gUnknown_0203CD6C->max_sheen = 0; + gUnknown_0203CD6C->category = Random() % 5; +} + +void SetLilycoveContestLady(void) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + gUnknown_0203CD6C->id = LILYCOVE_LADY_CONTEST; + gUnknown_0203CD6C->phase = 0; + sub_818E604(); + gUnknown_0203CD6C->language = gGameLanguage; +} -- cgit v1.2.3 From 0c7555e237e44e0c0056946822e861ec022fcefe Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 20 Sep 2017 22:54:26 +0200 Subject: SetMoveEffect functionally equivalent and close --- src/battle_4.c | 715 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 703 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/battle_4.c b/src/battle_4.c index 5d867289b..a51da55bf 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -71,15 +71,17 @@ extern u8 gPlayerPartyCount; extern u16 gMoveToLearn; extern u16 gRandomMove; extern u8 gBankInMenu; -extern u8 gActionForBanks[4]; +extern u8 gActionForBanks[BATTLE_BANKS_COUNT]; extern u8 gCurrentMoveTurn; -extern u8 gBattleBufferB[4][0x200]; +extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200]; +extern u16 gLockedMoves[BATTLE_BANKS_COUNT]; extern const struct BattleMove gBattleMoves[]; +extern const struct BaseStats gBaseStats[]; +extern const u8 gTypeEffectiveness[]; extern const u16 gMissStringIds[]; +extern const u16 gTrappingMoves[]; extern const u8 gTrainerMoney[]; -extern const u8 gTypeEffectiveness[]; -extern const struct BaseStats gBaseStats[]; // functions @@ -106,6 +108,9 @@ extern const u8 BattleScript_ItemSteal[]; extern const u8 BattleScript_RapidSpinAway[]; extern const u8 BattleScript_TargetPRLZHeal[]; extern const u8 BattleScript_KnockedOff[]; +extern const u8 BattleScript_AllStatsUp[]; +extern const u8 BattleScript_AtkDefDown[]; +extern const u8 BattleScript_SAtkDown2[]; extern const u8 BattleScript_LevelUp[]; extern const u8 BattleScript_WrapFree[]; extern const u8 BattleScript_LeechSeedFree[]; @@ -139,6 +144,7 @@ bool8 IsTwoTurnsMove(u16 move); void DestinyBondFlagUpdate(void); u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. static void CheckWonderGuardAndLevitate(void); +u8 ChangeStatBuffs(s8, u8 statId, u8, const u8* BS_ptr); void atk00_attackcanceler(void); void atk01_accuracycheck(void); @@ -672,14 +678,14 @@ const u16 gCriticalHitChance[] = {16, 8, 4, 3, 2}; const u32 gStatusFlagsForMoveEffects[] = { 0x00000000, - 0x00000007, - 0x00000008, - 0x00000010, - 0x00000020, - 0x00000040, - 0x00000080, - 0x00000007, - 0x00000008, + STATUS_SLEEP, + STATUS_POISON, + STATUS_BURN, + STATUS_FREEZE, + STATUS_PARALYSIS, + STATUS_TOXIC_POISON, + STATUS2_CONFUSION, + STATUS2_FLINCHED, 0x00000000, 0x00000070, 0x00000000, @@ -733,6 +739,8 @@ const u32 gStatusFlagsForMoveEffects[] = 0x00000000 }; +extern const u8* gMoveEffectBS_Ptrs[]; + void atk00_attackcanceler(void) { s32 i; @@ -2023,3 +2031,686 @@ u8 BankGetTurnOrder(u8 bank) } return i; } + +#define INCREMENT_RESET_RETURN \ +{ \ + gBattlescriptCurrInstr++; \ + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; \ + return; \ +} + +#define RESET_RETURN \ +{ \ + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; \ + return; \ +} + +void SetMoveEffect(bool8 primary, u8 certain) +{ + bool32 statusChanged = FALSE; + u8 affectsUser = 0; // 0x40 otherwise + bool32 noSunCanFreeze = TRUE; + + if (gBattleCommunication[MOVE_EFFECT_BYTE] & MOVE_EFFECT_AFFECTS_USER) + { + gEffectBank = gBankAttacker; // bank that effects get applied on + gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(MOVE_EFFECT_AFFECTS_USER); + affectsUser = MOVE_EFFECT_AFFECTS_USER; + gBattleScripting.bank = gBankTarget; // theoretically the attacker + } + else + { + gEffectBank = gBankTarget; + gBattleScripting.bank = gBankAttacker; + } + + if (gBattleMons[gEffectBank].ability == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 9) + INCREMENT_RESET_RETURN + + if (gSideAffecting[GET_BANK_SIDE(gEffectBank)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 7) + INCREMENT_RESET_RETURN + + if (gBattleMons[gEffectBank].hp == 0 + && gBattleCommunication[MOVE_EFFECT_BYTE] != MOVE_EFFECT_PAYDAY + && gBattleCommunication[MOVE_EFFECT_BYTE] != MOVE_EFFECT_STEAL_ITEM) + INCREMENT_RESET_RETURN + + if (gBattleMons[gEffectBank].status2 & STATUS2_SUBSTITUTE && affectsUser != MOVE_EFFECT_AFFECTS_USER) + INCREMENT_RESET_RETURN + + if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) // status change + { + switch (gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + { + case STATUS_SLEEP: + // check active uproar + if (gBattleMons[gEffectBank].ability != ABILITY_SOUNDPROOF) + { + for (gActiveBank = 0; + gActiveBank < gNoOfAllBanks && !(gBattleMons[gActiveBank].status2 & STATUS2_UPROAR); + gActiveBank++) + {} + } + else + gActiveBank = gNoOfAllBanks; + + if (gBattleMons[gEffectBank].status1) + break; + if (gActiveBank != gNoOfAllBanks) + break; + if (gBattleMons[gEffectBank].ability == ABILITY_VITAL_SPIRIT) + break; + if (gBattleMons[gEffectBank].ability == ABILITY_INSOMNIA) + break; + + CancelMultiTurnMoves(gEffectBank); + statusChanged = TRUE; + break; + case STATUS_POISON: + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY + && (primary == TRUE || certain == 0x80)) + { + gLastUsedAbility = ABILITY_IMMUNITY; + RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + RESET_RETURN + } + if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON + || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) + && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && (primary == 1 || certain == 0x80)) + { + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + RESET_RETURN + } + if (gBattleMons[gEffectBank].type1 == TYPE_POISON) + break; + if (gBattleMons[gEffectBank].type2 == TYPE_POISON) + break; + if (gBattleMons[gEffectBank].type1 == TYPE_STEEL) + break; + if (gBattleMons[gEffectBank].type2 == TYPE_STEEL) + break; + if (gBattleMons[gEffectBank].status1) + break; + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) + break; + + statusChanged = TRUE; + break; + case STATUS_BURN: + if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL + && (primary == 1 || certain == 0x80)) + { + gLastUsedAbility = ABILITY_WATER_VEIL; + RecordAbilityBattle(gEffectBank, ABILITY_WATER_VEIL); + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_BRNPrevention; + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + RESET_RETURN + } + if ((gBattleMons[gEffectBank].type1 == TYPE_FIRE + || gBattleMons[gEffectBank].type2 == TYPE_FIRE) + && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && (primary == 1 || certain == 0x80)) + { + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_BRNPrevention; + + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + RESET_RETURN + } + if (gBattleMons[gEffectBank].type1 == TYPE_FIRE) + break; + if (gBattleMons[gEffectBank].type2 == TYPE_FIRE) + break; + if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL) + break; + if (gBattleMons[gEffectBank].status1) + break; + + statusChanged = TRUE; + break; + case STATUS_FREEZE: + if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY) + noSunCanFreeze = FALSE; + if (gBattleMons[gEffectBank].type1 == TYPE_ICE) + break; + if (gBattleMons[gEffectBank].type2 == TYPE_ICE) + break; + if (gBattleMons[gEffectBank].status1) + break; + if (noSunCanFreeze == 0) + break; + if (gBattleMons[gEffectBank].ability == ABILITY_MAGMA_ARMOR) + break; + + CancelMultiTurnMoves(gEffectBank); + statusChanged = TRUE; + break; + case STATUS_PARALYSIS: + if (gBattleMons[gEffectBank].ability == ABILITY_LIMBER) + { + if (primary == TRUE || certain == 0x80) + { + gLastUsedAbility = ABILITY_LIMBER; + RecordAbilityBattle(gEffectBank, ABILITY_LIMBER); + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PRLZPrevention; + + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + RESET_RETURN + } + else + break; + } + if (gBattleMons[gEffectBank].status1) + break; + + statusChanged = TRUE; + break; + case STATUS_TOXIC_POISON: + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY && (primary == 1 || certain == 0x80)) + { + gLastUsedAbility = ABILITY_IMMUNITY; + RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + RESET_RETURN + } + if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON + || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) + && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && (primary == TRUE || certain == 0x80)) + { + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + RESET_RETURN + } + if (gBattleMons[gEffectBank].status1) + break; + if (gBattleMons[gEffectBank].type1 != TYPE_POISON + && gBattleMons[gEffectBank].type2 != TYPE_POISON + && gBattleMons[gEffectBank].type1 != TYPE_STEEL + && gBattleMons[gEffectBank].type2 != TYPE_STEEL) + { + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) + break; + + // It's redundant, because at this point we know the status1 value is 0. + gBattleMons[gEffectBank].status1 &= ~(STATUS_TOXIC_POISON); + gBattleMons[gEffectBank].status1 &= ~(STATUS_POISON); + statusChanged = TRUE; + break; + } + else + { + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + } + break; + } + if (statusChanged == TRUE) + { + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + + if (gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS_SLEEP) + gBattleMons[gEffectBank].status1 |= ((Random() & 3) + 2); + else + gBattleMons[gEffectBank].status1 |= gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; + + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + + gActiveBank = gEffectBank; + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBank].status1); + MarkBufferBankForExecution(gActiveBank); + + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + + // for synchronize + + if (gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_POISON + || gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_TOXIC + || gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_PARALYSIS + || gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_BURN) + { + u8* synchronizeEffect = &gBattleStruct->synchronizeMoveEffect; + *synchronizeEffect = gBattleCommunication[MOVE_EFFECT_BYTE]; + gHitMarker |= HITMARKER_SYNCHRONISE_EFFECT; + } + return; + } + else if (statusChanged == FALSE) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattlescriptCurrInstr++; + return; + } + } + else + { + if (gBattleMons[gEffectBank].status2 & gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + { + gBattlescriptCurrInstr++; + } + else + { + u8 side; + u32 statusFlag = + switch (gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + { + case MOVE_EFFECT_CONFUSION: + if (gBattleMons[gEffectBank].ability == ABILITY_OWN_TEMPO + || gBattleMons[gEffectBank].status2 & STATUS2_CONFUSION) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleMons[gEffectBank].status2 |= (((Random()) % 0x4)) + 2; + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + } + break; + case MOVE_EFFECT_FLINCH: + if (gBattleMons[gEffectBank].ability == ABILITY_INNER_FOCUS) + { + if (primary == 1 || certain == 0x80) + { + gLastUsedAbility = ABILITY_INNER_FOCUS; + RecordAbilityBattle(gEffectBank, ABILITY_INNER_FOCUS); + gBattlescriptCurrInstr = BattleScript_FlinchPrevention; + RESET_RETURN + } + else + { + gBattlescriptCurrInstr++; + break; + } + } + else + { + if (BankGetTurnOrder(gEffectBank) > gCurrentMoveTurn) + gBattleMons[gEffectBank].status2 |= gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; + INCREMENT_RESET_RETURN + } + break; + case MOVE_EFFECT_UPROAR: + if (gBattleMons[gEffectBank].status2 & STATUS2_UPROAR) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBank] = gCurrentMove; + gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 4; + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + } + break; + case MOVE_EFFECT_PAYDAY: + if (GET_BANK_SIDE(gBankAttacker) == SIDE_PLAYER) + { + u16 PayDay = gPaydayMoney; + gPaydayMoney += (gBattleMons[gBankAttacker].level * 5); + if (PayDay > gPaydayMoney) + gPaydayMoney = 0xFFFF; + } + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case MOVE_EFFECT_TRI_ATTACK: + if (gBattleMons[gEffectBank].status1) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleCommunication[MOVE_EFFECT_BYTE] = Random() % 3 + 3; + SetMoveEffect(FALSE, 0); + } + break; + case MOVE_EFFECT_CHARGING: + gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBank] = gCurrentMove; + gProtectStructs[gEffectBank].chargingTurn = 1; + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_WRAP: + if (gBattleMons[gEffectBank].status2 & STATUS2_WRAPPED) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 0xD; + + *(gBattleStruct->wrappedMove + gEffectBank * 2 + 0) = gCurrentMove; + *(gBattleStruct->wrappedMove + gEffectBank * 2 + 1) = gCurrentMove >> 8; + *(gBattleStruct->wrappedBy + gEffectBank) = gBankAttacker; + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + + for (gBattleCommunication[MULTISTRING_CHOOSER] = 0; gBattleCommunication[MULTISTRING_CHOOSER] <= 4; gBattleCommunication[MULTISTRING_CHOOSER]++) + { + if (gCurrentMove == gTrappingMoves[gBattleCommunication[MULTISTRING_CHOOSER]]) + break; + } + } + break; + case MOVE_EFFECT_RECOIL_25: // 25% recoil + gBattleMoveDamage = (gHpDealt) / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case 15 ... 21: // stat + 1 + if (ChangeStatBuffs(0x10, gBattleCommunication[MOVE_EFFECT_BYTE] + 0xF2, affectsUser, 0)) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleScripting.animArg2 = 0; + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatUp; + } + break; + case 22 ... 28: // stat - 1 + if (ChangeStatBuffs(~(0x6f), gBattleCommunication[MOVE_EFFECT_BYTE] + 0xEB, affectsUser, 0)) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleScripting.animArg2 = 0; + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatDown; + } + break; + case 39 ... 45: // stat + 2 + if (ChangeStatBuffs(0x20, gBattleCommunication[MOVE_EFFECT_BYTE] + 0xDA, affectsUser, 0)) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleScripting.animArg2 = 0; + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatUp; + } + break; + case 46 ... 52: // stat - 2 + if (ChangeStatBuffs(~(0x5f), gBattleCommunication[MOVE_EFFECT_BYTE] + 0xD3, affectsUser, 0)) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleScripting.animArg2 = 0; + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatDown; + } + break; + case MOVE_EFFECT_RECHARGE: + gBattleMons[gEffectBank].status2 |= STATUS2_RECHARGE; + gDisableStructs[gEffectBank].rechargeCounter = 2; + gLockedMoves[gEffectBank] = gCurrentMove; + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_RAGE: + gBattleMons[gBankAttacker].status2 |= STATUS2_RAGE; + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_STEAL_ITEM: + { + if (gBattleTypeFlags & BATTLE_TYPE_x4000000) + { + gBattlescriptCurrInstr++; + break; + } + + side = GetBankSide(gBankAttacker); + if (GetBankSide(gBankAttacker) == SIDE_OPPONENT + && !(gBattleTypeFlags & + (BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_LINK + | BATTLE_TYPE_x2000000 + | BATTLE_TYPE_SECRET_BASE))) + { + gBattlescriptCurrInstr++; + break; + } + if (!(gBattleTypeFlags & + (BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_LINK + | BATTLE_TYPE_x2000000 + | BATTLE_TYPE_SECRET_BASE)) + && (gWishFutureKnock.knockedOffPokes[side] & gBitTable[gBattlePartyID[gBankAttacker]])) + { + gBattlescriptCurrInstr++; + break; + } + if (gBattleMons[gBankTarget].item + && gBattleMons[gBankTarget].ability == ABILITY_STICKY_HOLD) + { + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = BattleScript_NoItemSteal; + + gLastUsedAbility = gBattleMons[gBankTarget].ability; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + + break; + } + if (gBattleMons[gBankAttacker].item) + { + gBattlescriptCurrInstr++; + break; + } + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + gBattlescriptCurrInstr++; + break; + } + if (gBattleMons[gBankTarget].item > 0x78 + && gBattleMons[gBankTarget].item < (0x79 + 12)) + { + gBattlescriptCurrInstr++; + break; + } + if (gBattleMons[gBankTarget].item == 0) + { + gBattlescriptCurrInstr++; + break; + } + + *(u16*)((u8*)((gBattleStruct->field_D0) + gBankAttacker * 2)) = gLastUsedItem = gBattleMons[gBankTarget].item; + gBattleMons[gBankTarget].item = 0; + + gActiveBank = gBankAttacker; + EmitSetAttributes(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedItem); + MarkBufferBankForExecution(gBankAttacker); + + gActiveBank = gBankTarget; + EmitSetAttributes(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); + MarkBufferBankForExecution(gBankTarget); + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_ItemSteal; + + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 0) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 1) = 0; + } + break; + case MOVE_EFFECT_PREVENT_ESCAPE: + gBattleMons[gBankTarget].status2 |= STATUS2_ESCAPE_PREVENTION; + gDisableStructs[gBankTarget].bankPreventingEscape = gBankAttacker; + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_NIGHTMARE: + gBattleMons[gBankTarget].status2 |= STATUS2_NIGHTMARE; + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_ALL_STATS_UP: + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_AllStatsUp; + break; + case MOVE_EFFECT_RAPIDSPIN: + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_RapidSpinAway; + break; + case MOVE_EFFECT_REMOVE_PARALYSIS: // Smelling salts + if (!(gBattleMons[gBankTarget].status1 & STATUS_PARALYSIS)) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleMons[gBankTarget].status1 &= ~(STATUS_PARALYSIS); + + gActiveBank = gBankTarget; + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); + MarkBufferBankForExecution(gActiveBank); + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal; + } + break; + case MOVE_EFFECT_ATK_DEF_DOWN: // SuperPower + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_AtkDefDown; + break; + case MOVE_EFFECT_RECOIL_33_PARALYSIS: // Volt Tackle + gBattleMoveDamage = gHpDealt / 3; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case MOVE_EFFECT_THRASH: + if (gBattleMons[gEffectBank].status2 & STATUS2_LOCK_CONFUSE) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBank] = gCurrentMove; + gBattleMons[gEffectBank].status2 |= (((Random() & 1) + 2) << 0xA); + } + break; + case MOVE_EFFECT_KNOCK_OFF: + if (gBattleMons[gEffectBank].ability == ABILITY_STICKY_HOLD) + { + if (gBattleMons[gEffectBank].item == 0) + { + gBattlescriptCurrInstr++; + } + else + { + gLastUsedAbility = ABILITY_STICKY_HOLD; + gBattlescriptCurrInstr = BattleScript_NoItemSteal; + RecordAbilityBattle(gEffectBank, ABILITY_STICKY_HOLD); + } + break; + } + if (gBattleMons[gEffectBank].item == 0) + { + gBattlescriptCurrInstr++; + } + else + { + side = GetBankSide(gEffectBank); + + gLastUsedItem = gBattleMons[gEffectBank].item; + gBattleMons[gEffectBank].item = 0; + gWishFutureKnock.knockedOffPokes[side] |= gBitTable[gBattlePartyID[gEffectBank]]; + + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_KnockedOff; + + *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBank]) + 0) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBank]) + 1) = 0; + } + break; + default: + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_SP_ATK_TWO_DOWN: // Overheat + b_movescr_stack_push(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_SAtkDown2; + break; + } + } + } + + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; +} -- cgit v1.2.3 From cf26b0e125aef07052b333139c33a6bbe1088f96 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 20 Sep 2017 22:55:37 +0200 Subject: forgot save lol --- src/battle_4.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/battle_4.c b/src/battle_4.c index a51da55bf..6e71a6a57 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -2351,7 +2351,6 @@ void SetMoveEffect(bool8 primary, u8 certain) else { u8 side; - u32 statusFlag = switch (gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) { case MOVE_EFFECT_CONFUSION: -- cgit v1.2.3 From 9ed9f7de941d5b89a1c6d6241b3bbb5726aa99e8 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Wed, 20 Sep 2017 14:38:05 -0500 Subject: Finish renaming strings in strings.s --- src/item.c | 12 ++++++------ src/pokemon_size_record.c | 8 ++++---- src/start_menu.c | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/item.c b/src/item.c index c85e2fe1f..0114676b6 100644 --- a/src/item.c +++ b/src/item.c @@ -8,9 +8,9 @@ extern void ApplyNewEncyprtionKeyToHword(u16* hword, u32 newKey); extern bool8 InBattlePyramid(void); -extern const u8 gOtherText_PokeBalls[]; -extern const u8 gOtherText_Berries[]; -extern const u8 gOtherText_Berry[]; +extern const u8 gText_PokeBalls[]; +extern const u8 gText_Berries[]; +extern const u8 gText_Berry[]; extern const u8 gUnknown_085897E4[][28]; // not sure what this one is bool8 CheckPyramidBagHasItem(u16 itemId, u16 count); @@ -92,7 +92,7 @@ void CopyItemNameHandlePlural(u16 itemId, u8 *string, u32 quantity) if (quantity < 2) StringCopy(string, ItemId_GetItem(ITEM_POKE_BALL)->name); else - StringCopy(string, gOtherText_PokeBalls); + StringCopy(string, gText_PokeBalls); } else { @@ -109,9 +109,9 @@ void GetBerryCountString(u8* dst, const u8* berryName, u32 quantity) u8* txtPtr; if (quantity < 2) - berryString = gOtherText_Berry; + berryString = gText_Berry; else - berryString = gOtherText_Berries; + berryString = gText_Berries; txtPtr = StringCopy(dst, berryName); *txtPtr = CHAR_SPACE; StringCopy(txtPtr + 1, berryString); diff --git a/src/pokemon_size_record.c b/src/pokemon_size_record.c index 804dbda74..12d98bfd8 100644 --- a/src/pokemon_size_record.c +++ b/src/pokemon_size_record.c @@ -45,8 +45,8 @@ static const u8 sGiftRibbonsMonDataIds[] = MON_DATA_GIFT_RIBBON_7 }; -extern const u8 gOtherText_DecimalPoint[]; -extern const u8 gOtherText_Marco[]; +extern const u8 gText_DecimalPoint[]; +extern const u8 gText_Marco[]; extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1]; #define CM_PER_INCH 2.54 @@ -103,7 +103,7 @@ static void FormatMonSizeRecord(u8 *string, u32 size) #endif string = ConvertIntToDecimalStringN(string, size / 10, 0, 8); - string = StringAppend(string, gOtherText_DecimalPoint); + string = StringAppend(string, gText_DecimalPoint); ConvertIntToDecimalStringN(string, size % 10, 0, 1); } @@ -152,7 +152,7 @@ static void GetMonSizeRecordInfo(u16 species, u16 *sizeRecord) FormatMonSizeRecord(gStringVar3, size); StringCopy(gStringVar1, gSpeciesNames[species]); if (*sizeRecord == DEFAULT_MAX_SIZE) - StringCopy(gStringVar2, gOtherText_Marco); + StringCopy(gStringVar2, gText_Marco); else StringCopy(gStringVar2, gSaveBlock2Ptr->playerName); } diff --git a/src/start_menu.c b/src/start_menu.c index ffcab5220..ac393ce2e 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -151,7 +151,7 @@ static void BuildStartMenuActions_MultiBattleRoom(void) extern const struct WindowTemplate gSafariBallsWindowTemplate; extern const struct WindowTemplate gPyramidFloorWindowTemplate_1; extern const struct WindowTemplate gPyramidFloorWindowTemplate_2; -extern const u8 gOtherText_SafariStock[]; +extern const u8 gText_SafariBallStock[]; void DisplaySafariBallsWindow(void) { @@ -159,13 +159,13 @@ void DisplaySafariBallsWindow(void) PutWindowTilemap(sSafariBallsWindowId); sub_81973FC(sSafariBallsWindowId, 0); ConvertIntToDecimalStringN(gStringVar1, gNumSafariBalls, STR_CONV_MODE_RIGHT_ALIGN, 2); - StringExpandPlaceholders(gStringVar4, gOtherText_SafariStock); + StringExpandPlaceholders(gStringVar4, gText_SafariBallStock); PrintTextOnWindow(sSafariBallsWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL); CopyWindowToVram(sSafariBallsWindowId, 2); } extern const u8* const gUnknown_08510510[]; -extern const u8 gOtherText_BattlePyramid_X[]; +extern const u8 gText_BattlePyramidFloor[]; void DisplayPyramidFloorWindow(void) { @@ -177,7 +177,7 @@ void DisplayPyramidFloorWindow(void) PutWindowTilemap(sBattlePyramidFloorWindowId); sub_81973FC(sBattlePyramidFloorWindowId, 0); StringCopy(gStringVar1, gUnknown_08510510[*(u16*)(&gSaveBlock2Ptr->field_CAA[8])]); - StringExpandPlaceholders(gStringVar4, gOtherText_BattlePyramid_X); + StringExpandPlaceholders(gStringVar4, gText_BattlePyramidFloor); PrintTextOnWindow(sBattlePyramidFloorWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL); CopyWindowToVram(sBattlePyramidFloorWindowId, 2); } -- cgit v1.2.3 From bf4319f25e52be0d77038de9fda8cc3a83930902 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 20:08:05 -0400 Subject: sub_818E6B0 --- src/lilycove_lady.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index f6471828b..52f910598 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -733,3 +733,26 @@ void SetLilycoveContestLady(void) sub_818E604(); gUnknown_0203CD6C->language = gGameLanguage; } + +void sub_818E674(void) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + gUnknown_0203CD6C->id = LILYCOVE_LADY_CONTEST; + gUnknown_0203CD6C->phase = 0; + if (gUnknown_0203CD6C->fave_pkblk == 5 || gUnknown_0203CD6C->other_pkblk == 5) + { + sub_818E604(); + } +} + +void sub_818E6B0(u8 sheen) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + if (gUnknown_0203CD6C->max_sheen <= sheen) + { + gUnknown_0203CD6C->max_sheen = sheen; + memset(gUnknown_0203CD6C->playerName, EOS, sizeof(gUnknown_0203CD6C->playerName)); + memcpy(gUnknown_0203CD6C->playerName, gSaveBlock2Ptr->playerName, sizeof(gUnknown_0203CD6C->playerName)); + gUnknown_0203CD6C->language = gGameLanguage; + } +} \ No newline at end of file -- cgit v1.2.3 From 25ffdf734284db4bd418d6f2ff74a9d895cb4498 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 20:16:11 -0400 Subject: sub_818E704 --- src/lilycove_lady.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 52f910598..30b5d6b21 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -755,4 +755,62 @@ void sub_818E6B0(u8 sheen) memcpy(gUnknown_0203CD6C->playerName, gSaveBlock2Ptr->playerName, sizeof(gUnknown_0203CD6C->playerName)); gUnknown_0203CD6C->language = gGameLanguage; } -} \ No newline at end of file +} + +bool8 sub_818E704(struct Pokeblock *pokeblock) +{ + u8 sheen; + bool8 response; + + sheen = 0; + response = FALSE; + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + switch (gUnknown_0203CD6C->category) + { + case 0: + if (pokeblock->spicy != 0) + { + sheen = pokeblock->spicy; + response = TRUE; + } + break; + case 1: + if (pokeblock->dry != 0) + { + sheen = pokeblock->dry; + response = TRUE; + } + break; + case 2: + if (pokeblock->sweet != 0) + { + sheen = pokeblock->sweet; + response = TRUE; + } + break; + case 3: + if (pokeblock->bitter != 0) + { + sheen = pokeblock->bitter; + response = TRUE; + } + break; + case 4: + if (pokeblock->sour != 0) + { + sheen = pokeblock->sour; + response = TRUE; + } + break; + } + if (response == TRUE) + { + sub_818E6B0(sheen); + gUnknown_0203CD6C->fave_pkblk ++; + } + else + { + gUnknown_0203CD6C->other_pkblk ++; + } + return response; +} -- cgit v1.2.3 From c56b6fc9a46d92824b8eb6b61bc2dc1f525c0757 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 20:24:22 -0400 Subject: sub_818E794 --- src/lilycove_lady.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 30b5d6b21..efbc791e8 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -35,6 +35,8 @@ extern const u16 *const gUnknown_0860B1A4[16]; extern const u16 gUnknown_0860B1E4[16]; extern const u16 gUnknown_0860B204[16]; extern const u8 gUnknown_085EEB7E[8]; +extern const u8 *const gUnknown_0860B324[5]; +extern const u8 *const gUnknown_0860B310[5]; EWRAM_DATA struct LilycoveLadyFavour *gUnknown_0203CD64 = NULL; EWRAM_DATA struct LilycoveLadyQuiz *gUnknown_0203CD68 = NULL; @@ -814,3 +816,10 @@ bool8 sub_818E704(struct Pokeblock *pokeblock) } return response; } + +void sub_818E794(u8 *dest1, u8 *dest2) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + StringCopy(dest1, gUnknown_0860B324[gUnknown_0203CD6C->category]); + StringCopy10(dest2, gUnknown_0860B310[gUnknown_0203CD6C->category]); +} -- cgit v1.2.3 From faf844f332e95d39660db3f76f78ed480d4845bf Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 20:32:22 -0400 Subject: through sub_818E880 --- src/lilycove_lady.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index efbc791e8..d142323c4 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -26,17 +26,18 @@ u8 sub_818E13C(void); bool8 sub_818E1F4(void); u8 sub_818E258(const u8 *); +extern const u8 gUnknown_085EEB7E[8]; extern const u16 gUnknown_0860B074[5]; extern const u16 gUnknown_0860B07E[3]; -extern const u8 *const gUnknown_0860B224[]; -extern const u16 *const gUnknown_0860B2EC[6]; -extern const u16 gUnknown_0860B304[6]; extern const u16 *const gUnknown_0860B1A4[16]; extern const u16 gUnknown_0860B1E4[16]; extern const u16 gUnknown_0860B204[16]; -extern const u8 gUnknown_085EEB7E[8]; -extern const u8 *const gUnknown_0860B324[5]; +extern const u8 *const gUnknown_0860B224[]; +extern const u16 *const gUnknown_0860B2EC[6]; +extern const u16 gUnknown_0860B304[6]; extern const u8 *const gUnknown_0860B310[5]; +extern const u8 *const gUnknown_0860B324[5]; +extern const u8 *const gUnknown_0860B338[5]; EWRAM_DATA struct LilycoveLadyFavour *gUnknown_0203CD64 = NULL; EWRAM_DATA struct LilycoveLadyQuiz *gUnknown_0203CD68 = NULL; @@ -823,3 +824,44 @@ void sub_818E794(u8 *dest1, u8 *dest2) StringCopy(dest1, gUnknown_0860B324[gUnknown_0203CD6C->category]); StringCopy10(dest2, gUnknown_0860B310[gUnknown_0203CD6C->category]); } + +void sub_818E7E0(u8 *dest1, u8 *dest2) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + *dest1 = gUnknown_0203CD6C->category; + StringCopy(dest2, gUnknown_0860B310[gUnknown_0203CD6C->category]); +} + +void sub_818E81C(u8 *dest) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + StringCopy(dest, gUnknown_0203CD6C->playerName); +} + +void sub_818E848(u8 *dest) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + *dest = gUnknown_0203CD6C->language; +} + +void sub_818E868(u8 *dest, u8 category) +{ + StringCopy(dest, gUnknown_0860B338[category]); +} + +u8 sub_818E880(void) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + if (gUnknown_0203CD6C->fave_pkblk >= 5) + { + return 1; + } + else if (gUnknown_0203CD6C->fave_pkblk == 0) + { + return 2; + } + else + { + return 0; + } +} -- cgit v1.2.3 From d263750f1903a89fc61b2496453ff1c5b4b9a58b Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 20:48:32 -0400 Subject: remaining lilycove lady functions --- src/lilycove_lady.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index d142323c4..41112e40b 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -4,6 +4,8 @@ #include "global.h" #include "main.h" +#include "rom4.h" +#include "rom6.h" #include "event_data.h" #include "script.h" #include "rng.h" @@ -38,6 +40,7 @@ extern const u16 gUnknown_0860B304[6]; extern const u8 *const gUnknown_0860B310[5]; extern const u8 *const gUnknown_0860B324[5]; extern const u8 *const gUnknown_0860B338[5]; +extern const u16 gUnknown_0860B34C[5]; EWRAM_DATA struct LilycoveLadyFavour *gUnknown_0203CD64 = NULL; EWRAM_DATA struct LilycoveLadyQuiz *gUnknown_0203CD68 = NULL; @@ -865,3 +868,54 @@ u8 sub_818E880(void) return 0; } } + +bool8 sub_818E8B4(void) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + if (gUnknown_0203CD6C->phase == 1) + { + return TRUE; + } + return FALSE; +} + +bool8 sub_818E8E0(void) +{ + bool8 response; + + response = FALSE; + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + if (gUnknown_0203CD6C->fave_pkblk >= 5 || gUnknown_0203CD6C->other_pkblk >= 5) + { + response = TRUE; + } + return response; +} + +void sub_818E914(void) +{ + sub_818E794(gStringVar2, gStringVar1); +} + +void sub_818E92C(void) +{ + sub_81357FC(3, c2_exit_to_overworld_2_switch); +} + +void sub_818E940(void) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + gUnknown_0203CD6C->phase = 1; +} + +void sub_818E960(void) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + gSpecialVar_0x8005 = gUnknown_0860B34C[gUnknown_0203CD6C->category]; +} + +u8 sub_818E990(void) +{ + gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; + return gUnknown_0203CD6C->category; +} -- cgit v1.2.3 From 942fbe87d42ed1208217deac3cfa4f21908d446a Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 21:03:57 -0400 Subject: Populate header, label as static whatever won't break things --- src/lilycove_lady.c | 67 ++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 41112e40b..4839571ae 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -17,16 +17,15 @@ #include "easy_chat.h" #include "lilycove_lady.h" -void SetLilycoveQuizLady(void); -void SetLilycoveFavourLady(void); -void SetLilycoveContestLady(void); -void sub_818E004(void); -void sub_818DBC4(void); -void sub_818E674(void); -bool32 sub_811F8D8(u16); -u8 sub_818E13C(void); -bool8 sub_818E1F4(void); -u8 sub_818E258(const u8 *); +static void SetLilycoveQuizLady(void); +static void SetLilycoveFavourLady(void); +static void SetLilycoveContestLady(void); +static void sub_818E004(void); +static void sub_818DBC4(void); +static void sub_818E674(void); +static u8 sub_818E13C(void); +static bool8 sub_818E1F4(void); +static u8 sub_818E258(const u8 *); extern const u8 gUnknown_085EEB7E[8]; extern const u16 gUnknown_0860B074[5]; @@ -42,9 +41,9 @@ extern const u8 *const gUnknown_0860B324[5]; extern const u8 *const gUnknown_0860B338[5]; extern const u16 gUnknown_0860B34C[5]; -EWRAM_DATA struct LilycoveLadyFavour *gUnknown_0203CD64 = NULL; -EWRAM_DATA struct LilycoveLadyQuiz *gUnknown_0203CD68 = NULL; -EWRAM_DATA struct LilycoveLadyContest *gUnknown_0203CD6C = NULL; +static EWRAM_DATA struct LilycoveLadyFavour *gUnknown_0203CD64 = NULL; +static EWRAM_DATA struct LilycoveLadyQuiz *gUnknown_0203CD68 = NULL; +static EWRAM_DATA struct LilycoveLadyContest *gUnknown_0203CD6C = NULL; extern EWRAM_DATA u16 gScriptItemId; @@ -131,7 +130,7 @@ void sub_818DAEC(void) gScriptResult = GetLilycoveLadyId(); } -u8 sub_818DB04(const u16 *data) +static u8 sub_818DB04(const u16 *data) { u8 len; @@ -139,7 +138,7 @@ u8 sub_818DB04(const u16 *data) return len; } -void sub_818DB20(void) +static void sub_818DB20(void) { u8 size; u8 idx; @@ -150,7 +149,7 @@ void sub_818DB20(void) gUnknown_0203CD64->unk_010 = gUnknown_0860B2EC[gUnknown_0203CD64->unk_00c][idx]; } -void SetLilycoveFavourLady(void) +static void SetLilycoveFavourLady(void) { gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; gUnknown_0203CD64->id = LILYCOVE_LADY_FAVOUR; @@ -163,7 +162,7 @@ void SetLilycoveFavourLady(void) sub_818DB20(); } -void sub_818DBC4(void) +static void sub_818DBC4(void) { gUnknown_0203CD64 = &gSaveBlock1Ptr->lilycoveLady.favour; gUnknown_0203CD64->id = LILYCOVE_LADY_FAVOUR; @@ -187,7 +186,7 @@ u8 sub_818DBE8(void) } } -const u8 *sub_818DC1C(u8 idx) +static const u8 *sub_818DC1C(u8 idx) { return gUnknown_0860B224[idx]; } @@ -210,7 +209,7 @@ bool8 sub_818DC60(void) return FALSE; } -void sub_818DCAC(u8 *dest, u16 itemId) +static void sub_818DCAC(u8 *dest, u16 itemId) { StringCopy(dest, ItemId_GetItem(itemId)->name); } @@ -221,7 +220,7 @@ void sub_818DCC8(void) sub_818DCAC(gStringVar2, gUnknown_0203CD64->itemId); } -void sub_818DCF4(const u8 *src, u8 *dest) +static void sub_818DCF4(const u8 *src, u8 *dest) { memset(dest, 0xFF, 8); StringCopy7(dest, src); @@ -245,7 +244,7 @@ void sub_818DD78(void) sub_81AAC50(); } -bool8 sub_818DD84(u16 itemId) +static bool8 sub_818DD84(u16 itemId) { u8 len; u8 i; @@ -291,7 +290,7 @@ bool8 sub_818DE5C(void) return checkval < 5 ? FALSE : TRUE; } -void sub_818DE88(u16 itemId) +static void sub_818DE88(u16 itemId) { sub_818DCAC(gStringVar2, itemId); } @@ -318,7 +317,7 @@ void sub_818DEF4(void) EnableBothScriptContexts(); } -void sub_818DF00(void) +static void sub_818DF00(void) { u8 v0; u8 i; @@ -334,7 +333,7 @@ void sub_818DF00(void) gUnknown_0203CD68->playerName[0] = EOS; } -void SetLilycoveQuizLady(void) +static void SetLilycoveQuizLady(void) { u8 i; @@ -358,7 +357,7 @@ void SetLilycoveQuizLady(void) sub_818DF00(); } -void sub_818E004(void) +static void sub_818E004(void) { gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz; gUnknown_0203CD68->id = LILYCOVE_LADY_QUIZ; @@ -427,7 +426,7 @@ u8 sub_818E06C(void) } #ifdef NONMATCHING -u8 sub_818E13C(void) +static u8 sub_818E13C(void) { u8 retval; u8 len; @@ -461,7 +460,7 @@ u8 sub_818E13C(void) return retval; } #else -__attribute__((naked)) u8 sub_818E13C(void) +__attribute__((naked)) static u8 sub_818E13C(void) { asm_unified("\tpush {r4-r7,lr}\n" "\tmovs r7, 0x1\n" @@ -540,7 +539,7 @@ __attribute__((naked)) u8 sub_818E13C(void) } #endif -u8 sub_818E1F4(void) +static u8 sub_818E1F4(void) { bool8 response; u8 i; @@ -558,7 +557,7 @@ u8 sub_818E1F4(void) return response; } -u8 sub_818E258(const u8 *str) +static u8 sub_818E258(const u8 *str) { u8 len; const u8 *ptr; @@ -722,7 +721,7 @@ void sub_818E570(const struct LilycoveLadyQuiz *quiz) } } -void sub_818E604(void) +static void sub_818E604(void) { gUnknown_0203CD6C->playerName[0] = EOS; gUnknown_0203CD6C->fave_pkblk = 0; @@ -731,7 +730,7 @@ void sub_818E604(void) gUnknown_0203CD6C->category = Random() % 5; } -void SetLilycoveContestLady(void) +static void SetLilycoveContestLady(void) { gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; gUnknown_0203CD6C->id = LILYCOVE_LADY_CONTEST; @@ -740,7 +739,7 @@ void SetLilycoveContestLady(void) gUnknown_0203CD6C->language = gGameLanguage; } -void sub_818E674(void) +static void sub_818E674(void) { gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; gUnknown_0203CD6C->id = LILYCOVE_LADY_CONTEST; @@ -751,7 +750,7 @@ void sub_818E674(void) } } -void sub_818E6B0(u8 sheen) +static void sub_818E6B0(u8 sheen) { gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; if (gUnknown_0203CD6C->max_sheen <= sheen) @@ -821,7 +820,7 @@ bool8 sub_818E704(struct Pokeblock *pokeblock) return response; } -void sub_818E794(u8 *dest1, u8 *dest2) +static void sub_818E794(u8 *dest1, u8 *dest2) { gUnknown_0203CD6C = &gSaveBlock1Ptr->lilycoveLady.contest; StringCopy(dest1, gUnknown_0860B324[gUnknown_0203CD6C->category]); -- cgit v1.2.3 From 63a25a34a77a9e42901ccd13ae691b30130f9925 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 21:42:14 -0400 Subject: Disassemble lilycove lady data --- src/lilycove_lady.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 4839571ae..6a0e0c2b9 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -27,7 +27,8 @@ static u8 sub_818E13C(void); static bool8 sub_818E1F4(void); static u8 sub_818E258(const u8 *); -extern const u8 gUnknown_085EEB7E[8]; +extern const u8 gUnknown_085EEB7E[]; // Lady$ + extern const u16 gUnknown_0860B074[5]; extern const u16 gUnknown_0860B07E[3]; extern const u16 *const gUnknown_0860B1A4[16]; -- cgit v1.2.3 From 6f481cceb1b56c5d63ba045f7ca7f1ac7151332b Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Wed, 20 Sep 2017 22:01:28 -0400 Subject: Decompile lilycove lady data --- src/lilycove_lady.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 192 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 6a0e0c2b9..b476c6b2b 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -29,18 +29,198 @@ static u8 sub_818E258(const u8 *); extern const u8 gUnknown_085EEB7E[]; // Lady$ -extern const u16 gUnknown_0860B074[5]; -extern const u16 gUnknown_0860B07E[3]; -extern const u16 *const gUnknown_0860B1A4[16]; -extern const u16 gUnknown_0860B1E4[16]; -extern const u16 gUnknown_0860B204[16]; -extern const u8 *const gUnknown_0860B224[]; -extern const u16 *const gUnknown_0860B2EC[6]; -extern const u16 gUnknown_0860B304[6]; -extern const u8 *const gUnknown_0860B310[5]; -extern const u8 *const gUnknown_0860B324[5]; -extern const u8 *const gUnknown_0860B338[5]; -extern const u16 gUnknown_0860B34C[5]; +static const u16 gUnknown_0860B074[] = { + 0x62, 0xcb, 0xdc, 0xcc, 0xd1 +}; +static const u16 gUnknown_0860B07E[] = { + 0x1a, 0x14, 0x0a +}; + +static const u16 Unknown_0860B084[] = { + 0x101b, 0x1623, 0x1812, 0x102c, 0x020e, 0x0c03, 0x1a0b, 0x0210, 0x020d +}; + +static const u16 Unknown_0860B096[] = { + 0x101b, 0x1013, 0x1020, 0x1a0f, 0x020c, 0x0c03, 0x0211, 0x0203, 0x0400 +}; + +static const u16 Unknown_0860B0A8[] = { + 0x0e0f, 0x1018, 0x020e, 0x0204, 0x0c03, 0xffff, 0x0212, 0x0451, 0x0463 +}; + +static const u16 Unknown_0860B0BA[] = { + 0x101b, 0x100b, 0x0e0d, 0x141a, 0x181d, 0x0c03, 0x141e, 0x1a26, 0x1823 +}; + +static const u16 Unknown_0860B0CC[] = { + 0x101b, 0x181d, 0x1018, 0x0a02, 0x2014, 0x0c03, 0x0208, 0x1824, 0x181c +}; + +static const u16 Unknown_0860B0DE[] = { + 0x101b, 0x1000, 0x1c19, 0x265d, 0x0c03, 0xffff, 0x0447, 0x045d, 0x042c +}; + +static const u16 Unknown_0860B0F0[] = { + 0x101b, 0x1034, 0x1e11, 0x100b, 0x1a08, 0x0c03, 0x044b, 0x0446, 0x040a +}; + +static const u16 Unknown_0860B102[] = { + 0x101b, 0x1000, 0x274f, 0x0626, 0x0c03, 0xffff, 0x0442, 0x0411, 0x0450 +}; + +static const u16 Unknown_0860B114[] = { + 0x101b, 0x1000, 0x1c19, 0x043c, 0x0c03, 0xffff, 0x0421, 0x0464, 0x0435 +}; + +static const u16 Unknown_0860B126[] = { + 0x101b, 0x1203, 0x1030, 0x0207, 0x0c03, 0xffff, 0x0210, 0x020e, 0x020d +}; + +static const u16 Unknown_0860B138[] = { + 0x101b, 0x1623, 0x0a05, 0x020e, 0x0c03, 0xffff, 0x1a25, 0x181a, 0x181b +}; + +static const u16 Unknown_0860B14A[] = { + 0x101b, 0x1823, 0x1603, 0x0a02, 0x1812, 0x0c03, 0x1a15, 0x1a23, 0x181b +}; + +static const u16 Unknown_0860B15C[] = { + 0x1020, 0x020e, 0x1010, 0x1043, 0x1e0f, 0x0c03, 0x181c, 0x1a24, 0x1816 +}; + +static const u16 Unknown_0860B16E[] = { + 0x0446, 0x100b, 0x0620, 0x061c, 0x101b, 0x0c03, 0x0420, 0x0426, 0xffff +}; + +static const u16 Unknown_0860B180[] = { + 0x0400, 0x100b, 0x0639, 0x061c, 0x101b, 0x0c03, 0x040e, 0x0410, 0xffff +}; + +static const u16 Unknown_0860B192[] = { + 0x041f, 0x100b, 0x0639, 0x061c, 0x101b, 0x0c03, 0x0445, 0x0400, 0xffff +}; + +static const u16 *const gUnknown_0860B1A4[] = { + Unknown_0860B084, + Unknown_0860B096, + Unknown_0860B0A8, + Unknown_0860B0BA, + Unknown_0860B0CC, + Unknown_0860B0DE, + Unknown_0860B0F0, + Unknown_0860B102, + Unknown_0860B114, + Unknown_0860B126, + Unknown_0860B138, + Unknown_0860B14A, + Unknown_0860B15C, + Unknown_0860B16E, + Unknown_0860B180, + Unknown_0860B192 +}; + +static const u16 gUnknown_0860B1E4[] = { + 0x0210, 0x0400, 0x0212, 0x1a26, 0x0208, 0x045d, 0x040a, 0x0411, 0x0464, 0x020e, 0x1a25, 0x181b, 0x1a24, 0x0420, 0x0410, 0x0400 +}; + +static const u16 gUnknown_0860B204[] = { + 0x007b, 0x007f, 0x0081, 0x0023, 0x0023, 0x0023, 0x00a5, 0x00a7, 0x00a6, 0x000b, 0x012f, 0x006b, 0x006d, 0x0044, 0x0044, 0x000c +}; + +extern const u8 gUnknown_085EEB83[]; +extern const u8 gUnknown_085EEB8C[]; +extern const u8 gUnknown_085EEB95[]; +extern const u8 gUnknown_085EEB9E[]; +extern const u8 gUnknown_085EEBA4[]; +extern const u8 gUnknown_085EEBAB[]; + +static const u8 *const gUnknown_0860B224[] = { + gUnknown_085EEB83, + gUnknown_085EEB8C, + gUnknown_085EEB95, + gUnknown_085EEB9E, + gUnknown_085EEBA4, + gUnknown_085EEBAB +}; + +static const u16 Unknown_0860B23C[] = { + 0x0056, 0x0053, 0x0054, 0x000e, 0x0012, 0x000f, 0x00a7, 0x0011, 0x0010, 0x0018, 0x0019, 0x001e, 0x0000 +}; + +static const u16 Unknown_0860B256[] = { + 0x0051, 0x006a, 0x006b, 0x00cc, 0x00c2, 0x002f, 0x0067, 0x0068, 0x0087, 0x0089, 0x008b, 0x009d, 0x00a0, 0x00a5, 0x0004, 0x0002, 0x0000 +}; + +static const u16 Unknown_0860B278[] = { + 0x0021, 0x000d, 0x001a, 0x001b, 0x001c, 0x00cc, 0x00ca, 0x0026, 0x0086, 0x0096, 0x0097, 0x009a, 0x00a2, 0x00a6, 0x0000 +}; + +static const u16 Unknown_0860B296[] = { + 0x0020, 0x004d, 0x004b, 0x004c, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x006e, 0x005d, 0x006c, 0x006d, 0x006a, 0x006b, 0x00d6, 0x00bc, 0x00b3, 0x000b, 0x000c, 0x0000 +}; + +static const u16 Unknown_0860B2C0[] = { + 0x001f, 0x0013, 0x0014, 0x004a, 0x004e, 0x0049, 0x00a5, 0x00c8, 0x0067, 0x006f, 0x0000 +}; + +static const u16 Unknown_0860B2D6[] = { + 0x00b7, 0x00d3, 0x00d2, 0x00d8, 0x009e, 0x00a6, 0x00ab, 0x00aa, 0x006c, 0x006d, 0x0000 +}; + +static const u16 *const gUnknown_0860B2EC[] = { + Unknown_0860B23C, + Unknown_0860B256, + Unknown_0860B278, + Unknown_0860B296, + Unknown_0860B2C0, + Unknown_0860B2D6 +}; + +static const u16 gUnknown_0860B304[] = { + 0x0b, 0x6e, 0x40, 0x6f, 0x44, 0x47 +}; + +extern const u8 gUnknown_085EEB2B[]; +extern const u8 gUnknown_085EEB34[]; +extern const u8 gUnknown_085EEB3A[]; +extern const u8 gUnknown_085EEB41[]; +extern const u8 gUnknown_085EEB4A[]; +extern const u8 gUnknown_085EEB51[]; +extern const u8 gUnknown_085EEB5A[]; +extern const u8 gUnknown_085EEB61[]; +extern const u8 gUnknown_085EEB6A[]; +extern const u8 gUnknown_085EEB74[]; +extern const u8 gUnknown_085EADA4[]; +extern const u8 gUnknown_085EADB5[]; +extern const u8 gUnknown_085EADC4[]; +extern const u8 gUnknown_085EADD5[]; +extern const u8 gUnknown_085EADE7[]; + +static const u8 *const gUnknown_0860B310[] = { + gUnknown_085EEB2B, + gUnknown_085EEB34, + gUnknown_085EEB3A, + gUnknown_085EEB41, + gUnknown_085EEB4A +}; +static const u8 *const gUnknown_0860B324[] = { + gUnknown_085EEB51, + gUnknown_085EEB5A, + gUnknown_085EEB61, + gUnknown_085EEB6A, + gUnknown_085EEB74 +}; +static const u8 *const gUnknown_0860B338[] = { + gUnknown_085EADA4, + gUnknown_085EADB5, + gUnknown_085EADC4, + gUnknown_085EADD5, + gUnknown_085EADE7 +}; + +static const u16 gUnknown_0860B34C[] = { + 0x0120, 0x013b, 0x011e, 0x013d, 0x0019 +}; static EWRAM_DATA struct LilycoveLadyFavour *gUnknown_0203CD64 = NULL; static EWRAM_DATA struct LilycoveLadyQuiz *gUnknown_0203CD68 = NULL; -- cgit v1.2.3 From 15212c4f8d80b4e15b20d0594d890fe1e803bc0e Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Thu, 21 Sep 2017 23:43:13 -0400 Subject: Font6Func --- src/text.c | 12 +-- src/unk_text_util_2.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+), 8 deletions(-) create mode 100644 src/unk_text_util_2.c (limited to 'src') diff --git a/src/text.c b/src/text.c index aa4e201c0..fe1c5df24 100644 --- a/src/text.c +++ b/src/text.c @@ -32,11 +32,7 @@ u8 gUnknown_03002FB0[0x20]; u8 gUnknown_03002FD0[0x20]; u8 gUnknown_03002FF0[0x20]; u8 gGlyphDimensions[0x2]; -struct { - u8 flag_0:1; - u8 flag_1:1; - u8 flag_2:1; -} gTextFlags; +TextFlags gTextFlags; const u8 gFontHalfRowOffsets[] = { 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00, @@ -1973,7 +1969,7 @@ bool8 TextPrinterWaitAutoMode(struct TextPrinter *textPrinter) } } -bool8 TextPrinterWaitWithDownArrow(struct TextPrinter *textPrinter) +bool16 TextPrinterWaitWithDownArrow(struct TextPrinter *textPrinter) { bool8 result = FALSE; if (gTextFlags.flag_2 != 0) @@ -1992,9 +1988,9 @@ bool8 TextPrinterWaitWithDownArrow(struct TextPrinter *textPrinter) return result; } -bool8 TextPrinterWait(struct TextPrinter *textPrinter) +bool16 TextPrinterWait(struct TextPrinter *textPrinter) { - bool8 result = FALSE; + bool16 result = FALSE; if (gTextFlags.flag_2 != 0) { result = TextPrinterWaitAutoMode(textPrinter); diff --git a/src/unk_text_util_2.c b/src/unk_text_util_2.c new file mode 100644 index 000000000..23f3ca1b6 --- /dev/null +++ b/src/unk_text_util_2.c @@ -0,0 +1,200 @@ +#include "global.h" +#include "main.h" +#include "window.h" +#include "text.h" +#include "sound.h" + +extern const u8 gUnknown_08616124[]; + +void DecompressGlyphFont6(u16); + +u16 Font6Func(struct TextPrinter *textPrinter) +{ + u16 char_; + struct TextPrinterSubStruct *sub; + + sub = &textPrinter->sub_union.sub; + switch (textPrinter->state) + { + case 0: + if (gMain.heldKeys & (A_BUTTON | B_BUTTON) && sub->font_type_upper) + { + textPrinter->delayCounter = 0; + } + if (textPrinter->delayCounter && textPrinter->text_speed) + { + textPrinter->delayCounter --; + if (gTextFlags.flag_0 && gMain.newKeys & (A_BUTTON | B_BUTTON)) + { + sub->font_type_upper = TRUE; + textPrinter->delayCounter = 0; + } + return 3; + } + if (gTextFlags.flag_2) + { + textPrinter->delayCounter = 3; + } + else + { + textPrinter->delayCounter = textPrinter->text_speed; + } + char_ = *textPrinter->subPrinter.current_text_offset ++; + switch (char_) + { + case EOS: + return 1; + case CHAR_NEWLINE: + textPrinter->subPrinter.currentX = textPrinter->subPrinter.x; + textPrinter->subPrinter.currentY += gFonts[textPrinter->subPrinter.fontId].maxLetterHeight + textPrinter->subPrinter.lineSpacing; + return 2; + case PLACEHOLDER_BEGIN: + textPrinter->subPrinter.current_text_offset ++; + return 2; + case EXT_CTRL_CODE_BEGIN: + char_ = *textPrinter->subPrinter.current_text_offset ++; + switch (char_) + { + case 1: + textPrinter->subPrinter.fontColor_h = *textPrinter->subPrinter.current_text_offset ++; + GenerateFontHalfRowLookupTable(textPrinter->subPrinter.fontColor_h, textPrinter->subPrinter.bgColor, textPrinter->subPrinter.shadowColor); + return 2; + case 2: + textPrinter->subPrinter.bgColor = *textPrinter->subPrinter.current_text_offset ++; + GenerateFontHalfRowLookupTable(textPrinter->subPrinter.fontColor_h, textPrinter->subPrinter.bgColor, textPrinter->subPrinter.shadowColor); + return 2; + case 3: + textPrinter->subPrinter.shadowColor = *textPrinter->subPrinter.current_text_offset ++; + GenerateFontHalfRowLookupTable(textPrinter->subPrinter.fontColor_h, textPrinter->subPrinter.bgColor, textPrinter->subPrinter.shadowColor); + return 2; + case 4: + textPrinter->subPrinter.fontColor_h = *textPrinter->subPrinter.current_text_offset; + textPrinter->subPrinter.bgColor = *++ textPrinter->subPrinter.current_text_offset; + textPrinter->subPrinter.shadowColor = *++ textPrinter->subPrinter.current_text_offset; + textPrinter->subPrinter.current_text_offset ++; + + GenerateFontHalfRowLookupTable(textPrinter->subPrinter.fontColor_h, textPrinter->subPrinter.bgColor, textPrinter->subPrinter.shadowColor); + return 2; + case 5: + textPrinter->subPrinter.current_text_offset ++; + return 2; + case 6: + sub->font_type = *textPrinter->subPrinter.current_text_offset; + textPrinter->subPrinter.current_text_offset ++; + return 2; + case 7: + return 2; + case 8: + textPrinter->delayCounter = *textPrinter->subPrinter.current_text_offset ++; + textPrinter->state = 6; + return 2; + case 9: + textPrinter->state = 1; + if (gTextFlags.flag_2) + { + sub->frames_visible_counter = 0; + } + return 3; + case 10: + textPrinter->state = 5; + return 3; + case 11: + case 16: + textPrinter->subPrinter.current_text_offset += 2; + return 2; + case 12: + char_ = *++textPrinter->subPrinter.current_text_offset; + break; + case 13: + textPrinter->subPrinter.currentX = textPrinter->subPrinter.x + *textPrinter->subPrinter.current_text_offset ++; + return 2; + case 14: + textPrinter->subPrinter.currentY = textPrinter->subPrinter.y + *textPrinter->subPrinter.current_text_offset ++; + return 2; + case 15: + FillWindowPixelBuffer(textPrinter->subPrinter.windowId, textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4)); + return 2; + } + break; + case CHAR_PROMPT_CLEAR: + textPrinter->state = 2; + TextPrinterInitDownArrowCounters(textPrinter); + return 3; + case CHAR_PROMPT_SCROLL: + textPrinter->state = 3; + TextPrinterInitDownArrowCounters(textPrinter); + return 3; + case 0xF9: + char_ = *textPrinter->subPrinter.current_text_offset ++ | 0x100; + break; + case 0xF8: + textPrinter->subPrinter.current_text_offset ++; + return 0; + } + DecompressGlyphFont6(char_); + CopyGlyphToWindow(textPrinter); + textPrinter->subPrinter.currentX += gUnknown_03002F90[0x80] + textPrinter->subPrinter.letterSpacing; + return 0; + case 1: + if (TextPrinterWait(textPrinter)) + { + textPrinter->state = 0; + } + return 3; + case 2: + if (TextPrinterWaitWithDownArrow(textPrinter)) + { + FillWindowPixelBuffer(textPrinter->subPrinter.windowId, textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4)); + textPrinter->subPrinter.currentX = textPrinter->subPrinter.x; + textPrinter->subPrinter.currentY = textPrinter->subPrinter.y; + textPrinter->state = 0; + } + return 3; + case 3: + if (TextPrinterWaitWithDownArrow(textPrinter)) + { + TextPrinterClearDownArrow(textPrinter); + textPrinter->scrollDistance = gFonts[textPrinter->subPrinter.fontId].maxLetterHeight + textPrinter->subPrinter.lineSpacing; + textPrinter->subPrinter.currentX = textPrinter->subPrinter.x; + textPrinter->state = 4; + } + return 3; + case 4: + if (textPrinter->scrollDistance) + { + if (textPrinter->scrollDistance < gUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed]) + { + ScrollWindow(textPrinter->subPrinter.windowId, 0, textPrinter->scrollDistance, textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4)); + textPrinter->scrollDistance = 0; + } + else + { + ScrollWindow(textPrinter->subPrinter.windowId, 0, gUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed], textPrinter->subPrinter.bgColor | (textPrinter->subPrinter.bgColor << 4)); + textPrinter->scrollDistance -= gUnknown_08616124[gSaveBlock2Ptr->optionsTextSpeed]; + } + CopyWindowToVram(textPrinter->subPrinter.windowId, 2); + } + else + { + textPrinter->state = 0; + } + return 3; + case 5: + if (!IsSEPlaying()) + { + textPrinter->state = 0; + } + return 3; + case 6: + if (textPrinter->delayCounter) + { + textPrinter->delayCounter --; + } + else + { + textPrinter->state = 0; + } + return 3; + } + return 1; +} -- cgit v1.2.3 From aa64f61b84d6b52f4073cf9acef1a927cd9010e6 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 22 Sep 2017 00:01:07 -0400 Subject: Finish decomp of unk_text_util_2 --- src/unk_text_util_2.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/unk_text_util_2.c b/src/unk_text_util_2.c index 23f3ca1b6..d9bd9d98d 100644 --- a/src/unk_text_util_2.c +++ b/src/unk_text_util_2.c @@ -5,8 +5,9 @@ #include "sound.h" extern const u8 gUnknown_08616124[]; +extern const u16 gFont6BrailleGlyphs[]; -void DecompressGlyphFont6(u16); +static void DecompressGlyphFont6(u16); u16 Font6Func(struct TextPrinter *textPrinter) { @@ -198,3 +199,21 @@ u16 Font6Func(struct TextPrinter *textPrinter) } return 1; } + +static void DecompressGlyphFont6(u16 glyph) +{ + const u16 *glyphs; + + glyphs = gFont6BrailleGlyphs + 0x100 * (glyph / 8) + 0x10 * (glyph % 8); + DecompressGlyphTile(glyphs, (u16 *)gUnknown_03002F90); + DecompressGlyphTile(glyphs + 0x8, (u16 *)(gUnknown_03002F90 + 0x20)); + DecompressGlyphTile(glyphs + 0x80, (u16 *)(gUnknown_03002F90 + 0x40)); + DecompressGlyphTile(glyphs + 0x88, (u16 *)(gUnknown_03002F90 + 0x60)); + gUnknown_03002F90[0x80] = 0x10; + gUnknown_03002F90[0x81] = 0x10; +} + +u8 GetGlyphWidthFont6(void) +{ + return 0x10; +} -- cgit v1.2.3 From d5afb0c6e9566a62ca6d597aeabc173b2c3e7fa5 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Fri, 22 Sep 2017 21:33:49 +0200 Subject: up to x48 and troubles --- src/battle_3.c | 92 +-- src/battle_4.c | 1884 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 1810 insertions(+), 166 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index 4f0997aa0..1b62e3bb8 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -196,17 +196,17 @@ extern void sub_803E08C(void); extern void bc_move_exec_returning(void); extern s8 GetFlavourRelationByPersonality(u32 personality, u8 flavor); -void b_movescr_stack_push(const u8* bsPtr) +void BattleScriptPush(const u8* bsPtr) { BATTLESCRIPTS_STACK->ptr[BATTLESCRIPTS_STACK->size++] = bsPtr; } -void b_movescr_stack_push_cursor(void) +void BattleScriptPushCursor(void) { BATTLESCRIPTS_STACK->ptr[BATTLESCRIPTS_STACK->size++] = gBattlescriptCurrInstr; } -void b_movescr_stack_pop_cursor(void) +void BattleScriptPop(void) { gBattlescriptCurrInstr = BATTLESCRIPTS_STACK->ptr[--BATTLESCRIPTS_STACK->size]; } @@ -1206,7 +1206,7 @@ u8 AtkCanceller_UnableToUseMove(void) { gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = 1; gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; effect = 2; @@ -1234,7 +1234,7 @@ u8 AtkCanceller_UnableToUseMove(void) else { gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = 0; gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; effect = 2; @@ -1262,7 +1262,7 @@ u8 AtkCanceller_UnableToUseMove(void) else // unfreeze { gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; gBattleCommunication[MULTISTRING_CHOOSER] = 0; } @@ -1349,7 +1349,7 @@ u8 AtkCanceller_UnableToUseMove(void) if (Random() & 1) { gBattleCommunication[MULTISTRING_CHOOSER] = 0; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); } else // confusion dmg { @@ -1363,7 +1363,7 @@ u8 AtkCanceller_UnableToUseMove(void) } else // snapped out of confusion { - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore; } effect = 1; @@ -1387,10 +1387,10 @@ u8 AtkCanceller_UnableToUseMove(void) { gBattleScripting.bank = CountTrailingZeroBits((gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) >> 0x10); if (Random() & 1) - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); else { - b_movescr_stack_push(BattleScript_MoveUsedIsParalyzedCantAttack); + BattleScriptPush(BattleScript_MoveUsedIsParalyzedCantAttack); gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; gProtectStructs[gBankAttacker].loveImmobility = 1; CancelMultiTurnMoves(gBankAttacker); @@ -1432,7 +1432,7 @@ u8 AtkCanceller_UnableToUseMove(void) if (gBattleMoves[gCurrentMove].effect == EFFECT_THAW_HIT) { gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; gBattleCommunication[MULTISTRING_CHOOSER] = 1; } @@ -1969,7 +1969,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattleTextBuff1[1] = 3; gBattleTextBuff1[2] = moveType; gBattleTextBuff1[3] = 0xFF; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_ColorChangeActivates; effect++; } @@ -1985,7 +1985,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_RoughSkinActivates; effect++; } @@ -2006,7 +2006,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) if (gBattleCommunication[MOVE_EFFECT_BYTE] == 3) gBattleCommunication[MOVE_EFFECT_BYTE] += 2; gBattleCommunication[MOVE_EFFECT_BYTE] += 0x40; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; effect++; @@ -2021,7 +2021,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) && (Random() % 3) == 0) { gBattleCommunication[MOVE_EFFECT_BYTE] = 0x42; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; effect++; @@ -2036,7 +2036,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) && (Random() % 3) == 0) { gBattleCommunication[MOVE_EFFECT_BYTE] = 0x45; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; effect++; @@ -2051,7 +2051,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) && (Random() % 3) == 0) { gBattleCommunication[MOVE_EFFECT_BYTE] = 0x43; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; effect++; @@ -2073,7 +2073,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) && GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) != 0xFF) { gBattleMons[gBankAttacker].status2 |= (gBitTable[gBankTarget] << 0x10); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_CuteCharmActivates; effect++; } @@ -2155,7 +2155,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattleMons[i].status2 &= ~(STATUS2_INFATUATION); break; } - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = gUnknown_082DB68C; gBattleScripting.bank = i; gActiveBank = i; @@ -2197,7 +2197,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattleStruct->synchronizeMoveEffect = 2; gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleStruct->synchronizeMoveEffect + 0x40; gBattleScripting.bank = gBankTarget; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_SynchronizeActivates; gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; effect++; @@ -2212,7 +2212,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattleStruct->synchronizeMoveEffect = 2; gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleStruct->synchronizeMoveEffect; gBattleScripting.bank = gBankAttacker; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_SynchronizeActivates; gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; effect++; @@ -2303,7 +2303,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) { gLastUsedAbility = ABILITY_INTIMIDATE; gStatuses3[i] &= ~(STATUS3_INTIMIDATE_POKES); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = gUnknown_082DB4C1; gBattleStruct->intimidateBank = i; effect++; @@ -3592,7 +3592,7 @@ _0804330E:\n\ strb r3, [r1, 0x2]\n\ movs r0, 0xFF\n\ strb r0, [r1, 0x3]\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =BattleScript_ColorChangeActivates\n\ str r0, [r1]\n\ @@ -3668,7 +3668,7 @@ _080433CA:\n\ bne _080433D8\n\ str r2, [r1]\n\ _080433D8:\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =BattleScript_RoughSkinActivates\n\ str r0, [r1]\n\ @@ -3763,7 +3763,7 @@ _080434BC:\n\ ldrb r0, [r1, 0x3]\n\ adds r0, 0x40\n\ strb r0, [r1, 0x3]\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =BattleScript_ApplySecondaryEffect\n\ str r0, [r1]\n\ @@ -3849,7 +3849,7 @@ _08043598:\n\ ldr r1, =gBattleCommunication\n\ movs r0, 0x42\n\ strb r0, [r1, 0x3]\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =BattleScript_ApplySecondaryEffect\n\ str r0, [r1]\n\ @@ -3935,7 +3935,7 @@ _08043674:\n\ ldr r1, =gBattleCommunication\n\ movs r0, 0x45\n\ strb r0, [r1, 0x3]\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =BattleScript_ApplySecondaryEffect\n\ str r0, [r1]\n\ @@ -4021,7 +4021,7 @@ _08043750:\n\ ldr r1, =gBattleCommunication\n\ movs r0, 0x43\n\ strb r0, [r1, 0x3]\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =BattleScript_ApplySecondaryEffect\n\ str r0, [r1]\n\ @@ -4183,7 +4183,7 @@ _080438B6:\n\ ldr r0, [r2]\n\ orrs r0, r1\n\ str r0, [r2]\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =BattleScript_CuteCharmActivates\n\ str r0, [r1]\n\ @@ -4484,7 +4484,7 @@ _08043BF8:\n\ _08043BFA:\n\ str r0, [r2]\n\ _08043BFC:\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =gUnknown_082DB68C\n\ str r0, [r1]\n\ @@ -4607,7 +4607,7 @@ _08043CF8:\n\ ldr r0, =gBankTarget\n\ ldrb r0, [r0]\n\ strb r0, [r1, 0x17]\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =BattleScript_SynchronizeActivates\n\ str r0, [r1]\n\ @@ -4662,7 +4662,7 @@ _08043D7C:\n\ ldr r0, =gBankAttacker\n\ ldrb r0, [r0]\n\ strb r0, [r1, 0x17]\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =BattleScript_SynchronizeActivates\n\ str r0, [r1]\n\ @@ -5380,7 +5380,7 @@ _080443B4:\n\ ldr r1, =0xfff7ffff\n\ ands r0, r1\n\ str r0, [r2]\n\ - bl b_movescr_stack_push_cursor\n\ + bl BattleScriptPushCursor\n\ ldr r1, =gBattlescriptCurrInstr\n\ ldr r0, =gUnknown_082DB4C1\n\ str r0, [r1]\n\ @@ -5465,7 +5465,7 @@ void b_call_bc_move_exec(const u8* BS_ptr) void b_push_move_exec(const u8* BS_ptr) { - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BS_ptr; BATTLE_CALLBACKS_STACK->function[BATTLE_CALLBACKS_STACK->size++] = gBattleMainFunc; gBattleMainFunc = sub_803E08C; @@ -6029,7 +6029,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].status1 & STATUS_PARALYSIS) { gBattleMons[bank].status1 &= ~(STATUS_PARALYSIS); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureParRet; effect = ITEM_STATUS_CHANGE; } @@ -6038,7 +6038,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].status1 & STATUS_PSN_ANY) { gBattleMons[bank].status1 &= ~(STATUS_PSN_ANY | STATUS_TOXIC_COUNTER); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCurePsnRet; effect = ITEM_STATUS_CHANGE; } @@ -6047,7 +6047,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].status1 & STATUS_BURN) { gBattleMons[bank].status1 &= ~(STATUS_BURN); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureBrnRet; effect = ITEM_STATUS_CHANGE; } @@ -6056,7 +6056,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].status1 & STATUS_FREEZE) { gBattleMons[bank].status1 &= ~(STATUS_FREEZE); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureFrzRet; effect = ITEM_STATUS_CHANGE; } @@ -6066,7 +6066,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) { gBattleMons[bank].status1 &= ~(STATUS_SLEEP); gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet; effect = ITEM_STATUS_CHANGE; } @@ -6075,7 +6075,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].status2 & STATUS2_CONFUSION) { gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureConfusionRet; effect = ITEM_EFFECT_OTHER; } @@ -6085,7 +6085,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) { gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = 0; gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet; effect = ITEM_EFFECT_OTHER; @@ -6121,7 +6121,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) } gBattleMons[bank].status1 = 0; gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = 0; gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet; effect = ITEM_STATUS_CHANGE; @@ -6140,7 +6140,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) { gBattleScripting.bank = bank; gStringBank = bank; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_WhiteHerbRet; return effect; // unnecessary return } @@ -6170,9 +6170,9 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) && gBattleMons[gBankTarget].hp) { gBattleCommunication[MOVE_EFFECT_BYTE] = 8; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); SetMoveEffect(0, 0); - b_movescr_stack_pop_cursor(); + BattleScriptPop(); } break; case HOLD_EFFECT_SHELL_BELL: @@ -6190,7 +6190,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMoveDamage == 0) gBattleMoveDamage = -1; gSpecialStatuses[gBankTarget].moveturnLostHP = 0; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_ItemHealHP_Ret; effect++; } diff --git a/src/battle_4.c b/src/battle_4.c index 6e71a6a57..8e0be22c2 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -15,6 +15,8 @@ #include "battle_controllers.h" #include "species.h" #include "songs.h" +#include "text.h" +#include "sound.h" // variables @@ -75,6 +77,7 @@ extern u8 gActionForBanks[BATTLE_BANKS_COUNT]; extern u8 gCurrentMoveTurn; extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200]; extern u16 gLockedMoves[BATTLE_BANKS_COUNT]; +extern u16 gPartnerTrainerId; extern const struct BattleMove gBattleMoves[]; extern const struct BaseStats gBaseStats[]; @@ -84,7 +87,7 @@ extern const u16 gTrappingMoves[]; extern const u8 gTrainerMoney[]; // functions - +extern void sub_81A5718(u8 bank); // battle frontier 2 // BattleScripts extern const u8 BattleScript_MoveEnd[]; @@ -108,6 +111,7 @@ extern const u8 BattleScript_ItemSteal[]; extern const u8 BattleScript_RapidSpinAway[]; extern const u8 BattleScript_TargetPRLZHeal[]; extern const u8 BattleScript_KnockedOff[]; +extern const u8 BattleScript_StickyHoldOnKnockOff[]; extern const u8 BattleScript_AllStatsUp[]; extern const u8 BattleScript_AtkDefDown[]; extern const u8 BattleScript_SAtkDown2[]; @@ -124,6 +128,10 @@ extern const u8 BattleScript_TrainerBallBlock[]; extern const u8 BattleScript_WallyBallThrow[]; extern const u8 BattleScript_SuccessBallThrow[]; extern const u8 BattleScript_ShakeBallThrow[]; +extern const u8 BattleScript_FaintAttacker[]; +extern const u8 BattleScript_FaintTarget[]; +extern const u8 BattleScript_DestinyBondTakesLife[]; +extern const u8 BattleScript_GrudgeTakesPp[]; // read via orr #define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) @@ -144,7 +152,7 @@ bool8 IsTwoTurnsMove(u16 move); void DestinyBondFlagUpdate(void); u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. static void CheckWonderGuardAndLevitate(void); -u8 ChangeStatBuffs(s8, u8 statId, u8, const u8* BS_ptr); +u8 ChangeStatBuffs(s8 statValue, u8 statId, u8, const u8* BS_ptr); void atk00_attackcanceler(void); void atk01_accuracycheck(void); @@ -687,10 +695,10 @@ const u32 gStatusFlagsForMoveEffects[] = STATUS2_CONFUSION, STATUS2_FLINCHED, 0x00000000, - 0x00000070, + STATUS2_UPROAR, 0x00000000, - 0x00001000, - 0x0000E000, + STATUS2_MULTIPLETURNS, + STATUS2_WRAPPED, 0x00000000, 0x00000000, 0x00000000, @@ -706,10 +714,10 @@ const u32 gStatusFlagsForMoveEffects[] = 0x00000000, 0x00000000, 0x00000000, - 0x00400000, + STATUS2_RECHARGE, 0x00000000, 0x00000000, - 0x04000000, + STATUS2_ESCAPE_PREVENTION, 0x08000000, 0x00000000, 0x00000000, @@ -730,7 +738,7 @@ const u32 gStatusFlagsForMoveEffects[] = 0x00000000, 0x00000000, 0x00000000, - 0x00000C00, + STATUS2_LOCK_CONFUSE, 0x00000000, 0x00000000, 0x00000000, @@ -792,7 +800,7 @@ void atk00_attackcanceler(void) { PressurePPLose(gBankAttacker, gBankTarget, MOVE_MAGIC_COAT); gProtectStructs[gBankTarget].bounceMove = 0; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MagicCoatBounce; return; } @@ -804,7 +812,7 @@ void atk00_attackcanceler(void) PressurePPLose(gBankAttacker, gTurnOrder[i], MOVE_SNATCH); gProtectStructs[gTurnOrder[i]].stealMove = 0; gBattleScripting.bank = gTurnOrder[i]; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_SnatchedMove; return; } @@ -814,7 +822,7 @@ void atk00_attackcanceler(void) { gSpecialStatuses[gBankTarget].lightningRodRedirected = 0; gLastUsedAbility = ABILITY_LIGHTNING_ROD; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_TookAttack; RecordAbilityBattle(gBankTarget, gLastUsedAbility); } @@ -1584,7 +1592,7 @@ void atk09_attackanimation(void) if ((gHitMarker & HITMARKER_NO_ANIMATIONS) && (gCurrentMove != MOVE_TRANSFORM && gCurrentMove != MOVE_SUBSTITUTE)) { - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_Pausex20; gBattleScripting.animTurn++; gBattleScripting.animTargetsHit++; @@ -1625,7 +1633,7 @@ void atk09_attackanimation(void) } else { - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_Pausex20; } } @@ -1710,7 +1718,7 @@ void atk0C_datahpupdate(void) if (gDisableStructs[gActiveBank].substituteHP == 0) { gBattlescriptCurrInstr += 2; - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_SubstituteFade; return; } @@ -1898,7 +1906,7 @@ void atk0F_resultmessage(void) gLastUsedItem = gBattleMons[gBankTarget].item; gStringBank = gBankTarget; gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_HangedOnMsg; return; default: @@ -1911,14 +1919,14 @@ void atk0F_resultmessage(void) gBattleMoveFlags &= ~(MOVESTATUS_ONEHITKO); gBattleMoveFlags &= ~(MOVESTATUS_SUPEREFFECTIVE); gBattleMoveFlags &= ~(MOVESTATUS_NOTVERYEFFECTIVE); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_OneHitKOMsg; return; } else if (gBattleMoveFlags & MOVESTATUS_ENDURED) { gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_EnduredMsg; return; } @@ -1927,7 +1935,7 @@ void atk0F_resultmessage(void) gLastUsedItem = gBattleMons[gBankTarget].item; gStringBank = gBankTarget; gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_HangedOnMsg; return; } @@ -2110,12 +2118,12 @@ void SetMoveEffect(bool8 primary, u8 certain) break; case STATUS_POISON: if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY - && (primary == TRUE || certain == 0x80)) + && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { gLastUsedAbility = ABILITY_IMMUNITY; RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_PSNPrevention; if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) @@ -2132,9 +2140,9 @@ void SetMoveEffect(bool8 primary, u8 certain) if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - && (primary == 1 || certain == 0x80)) + && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_PSNPrevention; gBattleCommunication[MULTISTRING_CHOOSER] = 2; @@ -2157,12 +2165,12 @@ void SetMoveEffect(bool8 primary, u8 certain) break; case STATUS_BURN: if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL - && (primary == 1 || certain == 0x80)) + && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { gLastUsedAbility = ABILITY_WATER_VEIL; RecordAbilityBattle(gEffectBank, ABILITY_WATER_VEIL); - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_BRNPrevention; if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) { @@ -2178,9 +2186,9 @@ void SetMoveEffect(bool8 primary, u8 certain) if ((gBattleMons[gEffectBank].type1 == TYPE_FIRE || gBattleMons[gEffectBank].type2 == TYPE_FIRE) && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - && (primary == 1 || certain == 0x80)) + && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_BRNPrevention; gBattleCommunication[MULTISTRING_CHOOSER] = 2; @@ -2217,12 +2225,12 @@ void SetMoveEffect(bool8 primary, u8 certain) case STATUS_PARALYSIS: if (gBattleMons[gEffectBank].ability == ABILITY_LIMBER) { - if (primary == TRUE || certain == 0x80) + if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN) { gLastUsedAbility = ABILITY_LIMBER; RecordAbilityBattle(gEffectBank, ABILITY_LIMBER); - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_PRLZPrevention; if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) @@ -2245,12 +2253,12 @@ void SetMoveEffect(bool8 primary, u8 certain) statusChanged = TRUE; break; case STATUS_TOXIC_POISON: - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY && (primary == 1 || certain == 0x80)) + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { gLastUsedAbility = ABILITY_IMMUNITY; RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_PSNPrevention; if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) @@ -2267,9 +2275,9 @@ void SetMoveEffect(bool8 primary, u8 certain) if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - && (primary == TRUE || certain == 0x80)) + && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_PSNPrevention; gBattleCommunication[MULTISTRING_CHOOSER] = 2; @@ -2299,7 +2307,7 @@ void SetMoveEffect(bool8 primary, u8 certain) } if (statusChanged == TRUE) { - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); if (gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS_SLEEP) gBattleMons[gEffectBank].status1 |= ((Random() & 3) + 2); @@ -2341,6 +2349,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattlescriptCurrInstr++; return; } + return; } else { @@ -2351,7 +2360,7 @@ void SetMoveEffect(bool8 primary, u8 certain) else { u8 side; - switch (gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + switch (gBattleCommunication[MOVE_EFFECT_BYTE]) { case MOVE_EFFECT_CONFUSION: if (gBattleMons[gEffectBank].ability == ABILITY_OWN_TEMPO @@ -2363,47 +2372,46 @@ void SetMoveEffect(bool8 primary, u8 certain) { gBattleMons[gEffectBank].status2 |= (((Random()) % 0x4)) + 2; - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; } break; case MOVE_EFFECT_FLINCH: if (gBattleMons[gEffectBank].ability == ABILITY_INNER_FOCUS) { - if (primary == 1 || certain == 0x80) + if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN) { gLastUsedAbility = ABILITY_INNER_FOCUS; RecordAbilityBattle(gEffectBank, ABILITY_INNER_FOCUS); gBattlescriptCurrInstr = BattleScript_FlinchPrevention; - RESET_RETURN } else { gBattlescriptCurrInstr++; - break; } } else { if (BankGetTurnOrder(gEffectBank) > gCurrentMoveTurn) gBattleMons[gEffectBank].status2 |= gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; - INCREMENT_RESET_RETURN + gBattlescriptCurrInstr++; } break; case MOVE_EFFECT_UPROAR: - if (gBattleMons[gEffectBank].status2 & STATUS2_UPROAR) - { - gBattlescriptCurrInstr++; - } - else + if (!(gBattleMons[gEffectBank].status2 & STATUS2_UPROAR)) { + gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; gLockedMoves[gEffectBank] = gCurrentMove; gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 4; - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; } + else + { + gBattlescriptCurrInstr++; + } break; case MOVE_EFFECT_PAYDAY: if (GET_BANK_SIDE(gBankAttacker) == SIDE_PLAYER) @@ -2413,7 +2421,7 @@ void SetMoveEffect(bool8 primary, u8 certain) if (PayDay > gPaydayMoney) gPaydayMoney = 0xFFFF; } - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; break; case MOVE_EFFECT_TRI_ATTACK: @@ -2440,18 +2448,20 @@ void SetMoveEffect(bool8 primary, u8 certain) } else { - gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 0xD; + gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 3) << 0xD; *(gBattleStruct->wrappedMove + gEffectBank * 2 + 0) = gCurrentMove; *(gBattleStruct->wrappedMove + gEffectBank * 2 + 1) = gCurrentMove >> 8; *(gBattleStruct->wrappedBy + gEffectBank) = gBankAttacker; - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - for (gBattleCommunication[MULTISTRING_CHOOSER] = 0; gBattleCommunication[MULTISTRING_CHOOSER] <= 4; gBattleCommunication[MULTISTRING_CHOOSER]++) + for (gBattleCommunication[MULTISTRING_CHOOSER] = 0; ; gBattleCommunication[MULTISTRING_CHOOSER]++) { - if (gCurrentMove == gTrappingMoves[gBattleCommunication[MULTISTRING_CHOOSER]]) + if (gBattleCommunication[MULTISTRING_CHOOSER] > 4) + break; + if (gTrappingMoves[gBattleCommunication[MULTISTRING_CHOOSER]] == gCurrentMove) break; } } @@ -2461,58 +2471,90 @@ void SetMoveEffect(bool8 primary, u8 certain) if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; break; - case 15 ... 21: // stat + 1 - if (ChangeStatBuffs(0x10, gBattleCommunication[MOVE_EFFECT_BYTE] + 0xF2, affectsUser, 0)) + case MOVE_EFFECT_ATK_PLUS_1: + case MOVE_EFFECT_DEF_PLUS_1: + case MOVE_EFFECT_SPD_PLUS_1: + case MOVE_EFFECT_SP_ATK_PLUS_1: + case MOVE_EFFECT_SP_DEF_PLUS_1: + case MOVE_EFFECT_ACC_PLUS_1: + case MOVE_EFFECT_EVS_PLUS_1: + if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1), + gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_PLUS_1 + 1, + affectsUser, 0)) { gBattlescriptCurrInstr++; } else { - gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); gBattleScripting.animArg2 = 0; - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_StatUp; } break; - case 22 ... 28: // stat - 1 - if (ChangeStatBuffs(~(0x6f), gBattleCommunication[MOVE_EFFECT_BYTE] + 0xEB, affectsUser, 0)) + case MOVE_EFFECT_ATK_MINUS_1: + case MOVE_EFFECT_DEF_MINUS_1: + case MOVE_EFFECT_SPD_MINUS_1: + case MOVE_EFFECT_SP_ATK_MINUS_1: + case MOVE_EFFECT_SP_DEF_MINUS_1: + case MOVE_EFFECT_ACC_MINUS_1: + case MOVE_EFFECT_EVS_MINUS_1: + if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE, + gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_MINUS_1 + 1, + affectsUser, 0)) { gBattlescriptCurrInstr++; } else { - gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); gBattleScripting.animArg2 = 0; - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_StatDown; } break; - case 39 ... 45: // stat + 2 - if (ChangeStatBuffs(0x20, gBattleCommunication[MOVE_EFFECT_BYTE] + 0xDA, affectsUser, 0)) + case MOVE_EFFECT_ATK_PLUS_2: + case MOVE_EFFECT_DEF_PLUS_2: + case MOVE_EFFECT_SPD_PLUS_2: + case MOVE_EFFECT_SP_ATK_PLUS_2: + case MOVE_EFFECT_SP_DEF_PLUS_2: + case MOVE_EFFECT_ACC_PLUS_2: + case MOVE_EFFECT_EVS_PLUS_2: + if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2), + gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_PLUS_2 + 1, + affectsUser, 0)) { gBattlescriptCurrInstr++; } else { - gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); gBattleScripting.animArg2 = 0; - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_StatUp; } break; - case 46 ... 52: // stat - 2 - if (ChangeStatBuffs(~(0x5f), gBattleCommunication[MOVE_EFFECT_BYTE] + 0xD3, affectsUser, 0)) + case MOVE_EFFECT_ATK_MINUS_2: + case MOVE_EFFECT_DEF_MINUS_2: + case MOVE_EFFECT_SPD_MINUS_2: + case MOVE_EFFECT_SP_ATK_MINUS_2: + case MOVE_EFFECT_SP_DEF_MINUS_2: + case MOVE_EFFECT_ACC_MINUS_2: + case MOVE_EFFECT_EVS_MINUS_2: + if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE, + gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_MINUS_2 + 1, + affectsUser, 0)) { gBattlescriptCurrInstr++; } else { - gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); gBattleScripting.animArg2 = 0; - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_StatDown; } break; @@ -2544,9 +2586,8 @@ void SetMoveEffect(bool8 primary, u8 certain) | BATTLE_TYPE_SECRET_BASE))) { gBattlescriptCurrInstr++; - break; } - if (!(gBattleTypeFlags & + else if (!(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_LINK @@ -2555,57 +2596,51 @@ void SetMoveEffect(bool8 primary, u8 certain) && (gWishFutureKnock.knockedOffPokes[side] & gBitTable[gBattlePartyID[gBankAttacker]])) { gBattlescriptCurrInstr++; - break; } - if (gBattleMons[gBankTarget].item + else if (gBattleMons[gBankTarget].item && gBattleMons[gBankTarget].ability == ABILITY_STICKY_HOLD) { - b_movescr_stack_push_cursor(); + BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_NoItemSteal; gLastUsedAbility = gBattleMons[gBankTarget].ability; RecordAbilityBattle(gBankTarget, gLastUsedAbility); - - break; - } - if (gBattleMons[gBankAttacker].item) - { - gBattlescriptCurrInstr++; - break; - } - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - { - gBattlescriptCurrInstr++; - break; } - if (gBattleMons[gBankTarget].item > 0x78 - && gBattleMons[gBankTarget].item < (0x79 + 12)) + else if (gBattleMons[gBankAttacker].item + || gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY + || (gBattleMons[gBankTarget].item > 0x78 && gBattleMons[gBankTarget].item < 0x85) + || gBattleMons[gBankTarget].item == 0) { gBattlescriptCurrInstr++; - break; } - if (gBattleMons[gBankTarget].item == 0) + else { - gBattlescriptCurrInstr++; - break; - } + // This is a leftover from R/S direct use of ewram addresses + void** memes1 = (void**)(&gBattleStruct); + void* memes2 = (void*)((u32)(gBankAttacker * 2 + offsetof(struct BattleStruct, field_D0))); + u16* memes3 = (u16*)(((void*)(*memes1) + (u32)(memes2))); + gLastUsedItem = *memes3 = gBattleMons[gBankTarget].item; - *(u16*)((u8*)((gBattleStruct->field_D0) + gBankAttacker * 2)) = gLastUsedItem = gBattleMons[gBankTarget].item; - gBattleMons[gBankTarget].item = 0; + // A sane representation of this would simply be: + // gLastUsedItem = gBattleStruct->field_D0[gBankAttacker] = gBattleMons[gBankTarget].item; - gActiveBank = gBankAttacker; - EmitSetAttributes(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedItem); - MarkBufferBankForExecution(gBankAttacker); + gBattleMons[gBankTarget].item = 0; - gActiveBank = gBankTarget; - EmitSetAttributes(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); - MarkBufferBankForExecution(gBankTarget); + gActiveBank = gBankAttacker; + EmitSetAttributes(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedItem); + MarkBufferBankForExecution(gBankAttacker); - b_movescr_stack_push(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_ItemSteal; + gActiveBank = gBankTarget; + EmitSetAttributes(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); + MarkBufferBankForExecution(gBankTarget); + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_ItemSteal; + + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 0) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 1) = 0; + } - *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 0) = 0; - *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 1) = 0; } break; case MOVE_EFFECT_PREVENT_ESCAPE: @@ -2618,11 +2653,11 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattlescriptCurrInstr++; break; case MOVE_EFFECT_ALL_STATS_UP: - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_AllStatsUp; break; case MOVE_EFFECT_RAPIDSPIN: - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_RapidSpinAway; break; case MOVE_EFFECT_REMOVE_PARALYSIS: // Smelling salts @@ -2635,15 +2670,15 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleMons[gBankTarget].status1 &= ~(STATUS_PARALYSIS); gActiveBank = gBankTarget; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal; } break; case MOVE_EFFECT_ATK_DEF_DOWN: // SuperPower - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_AtkDefDown; break; case MOVE_EFFECT_RECOIL_33_PARALYSIS: // Volt Tackle @@ -2651,7 +2686,7 @@ void SetMoveEffect(bool8 primary, u8 certain) if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; break; case MOVE_EFFECT_THRASH: @@ -2676,16 +2711,12 @@ void SetMoveEffect(bool8 primary, u8 certain) else { gLastUsedAbility = ABILITY_STICKY_HOLD; - gBattlescriptCurrInstr = BattleScript_NoItemSteal; + gBattlescriptCurrInstr = BattleScript_StickyHoldOnKnockOff; RecordAbilityBattle(gEffectBank, ABILITY_STICKY_HOLD); } break; } - if (gBattleMons[gEffectBank].item == 0) - { - gBattlescriptCurrInstr++; - } - else + if (gBattleMons[gEffectBank].item) { side = GetBankSide(gEffectBank); @@ -2693,18 +2724,19 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleMons[gEffectBank].item = 0; gWishFutureKnock.knockedOffPokes[side] |= gBitTable[gBattlePartyID[gEffectBank]]; - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_KnockedOff; *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBank]) + 0) = 0; *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBank]) + 1) = 0; } - break; - default: - gBattlescriptCurrInstr++; + else + { + gBattlescriptCurrInstr++; + } break; case MOVE_EFFECT_SP_ATK_TWO_DOWN: // Overheat - b_movescr_stack_push(gBattlescriptCurrInstr + 1); + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_SAtkDown2; break; } @@ -2713,3 +2745,1615 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleCommunication[MOVE_EFFECT_BYTE] = 0; } + +void atk15_seteffectwithchancetarget(void) +{ + u32 percentChance; + + if (gBattleMons[gBankAttacker].ability == ABILITY_SERENE_GRACE) + percentChance = gBattleMoves[gCurrentMove].secondaryEffectChance * 2; + else + percentChance = gBattleMoves[gCurrentMove].secondaryEffectChance; + + if (gBattleCommunication[MOVE_EFFECT_BYTE] & MOVE_EFFECT_CERTAIN + && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(MOVE_EFFECT_CERTAIN); + SetMoveEffect(0, MOVE_EFFECT_CERTAIN); + } + else if (Random() % 100 < percentChance + && gBattleCommunication[MOVE_EFFECT_BYTE] + && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + if (percentChance >= 100) + SetMoveEffect(0, MOVE_EFFECT_CERTAIN); + else + SetMoveEffect(0, 0); + } + else + { + gBattlescriptCurrInstr++; + } + + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattleScripting.field_16 = 0; +} + +void atk16_seteffectprimary(void) +{ + SetMoveEffect(TRUE, 0); +} + +void atk17_seteffectsecondary(void) +{ + SetMoveEffect(FALSE, 0); +} + +void atk18_status_effect_clear(void) +{ + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + if (gBattleCommunication[MOVE_EFFECT_BYTE] <= MOVE_EFFECT_TOXIC) + gBattleMons[gActiveBank].status1 &= (~gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); + else + gBattleMons[gActiveBank].status2 &= (~gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); + + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattlescriptCurrInstr += 2; + gBattleScripting.field_16 = 0; +} + +void atk19_faint_pokemon(void) +{ + const u8 *BS_ptr; + + if (gBattlescriptCurrInstr[2] != 0) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + if (gHitMarker & HITMARKER_FAINTED(gActiveBank)) + { + BS_ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 3); + + BattleScriptPop(); + gBattlescriptCurrInstr = BS_ptr; + gSideAffecting[GetBankSide(gActiveBank)] &= ~(SIDE_STATUS_SPIKES_DAMAGED); + } + else + { + gBattlescriptCurrInstr += 7; + } + } + else + { + u8 bank; + + if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER) + { + gActiveBank = gBankAttacker; + bank = gBankTarget; + BS_ptr = BattleScript_FaintAttacker; + } + else + { + gActiveBank = gBankTarget; + bank = gBankAttacker; + BS_ptr = BattleScript_FaintTarget; + } + if (!(gAbsentBankFlags & gBitTable[gActiveBank]) + && gBattleMons[gActiveBank].hp == 0) + { + gHitMarker |= HITMARKER_FAINTED(gActiveBank); + BattleScriptPush(gBattlescriptCurrInstr + 7); + gBattlescriptCurrInstr = BS_ptr; + if (GetBankSide(gActiveBank) == SIDE_PLAYER) + { + gHitMarker |= HITMARKER_x400000; + if (gBattleResults.playerFaintCounter < 0xFF) + gBattleResults.playerFaintCounter++; + AdjustFriendshipOnBattleFaint(gActiveBank); + } + else + { + if (gBattleResults.opponentFaintCounter < 0xFF) + gBattleResults.opponentFaintCounter++; + gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES, NULL); + } + if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBankAttacker].hp != 0) + { + gHitMarker &= ~(HITMARKER_DESTINYBOND); + BattleScriptPush(gBattlescriptCurrInstr); + gBattleMoveDamage = gBattleMons[bank].hp; + gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife; + } + if ((gStatuses3[gBankTarget] & STATUS3_GRUDGE) + && !(gHitMarker & HITMARKER_GRUDGE) + && GetBankSide(gBankAttacker) != GetBankSide(gBankTarget) + && gBattleMons[gBankAttacker].hp != 0 + && gCurrentMove != MOVE_STRUGGLE) + { + u8 moveIndex = *(gBattleStruct->chosenMovesIds + gBankAttacker); + + gBattleMons[gBankAttacker].pp[moveIndex] = 0; + BattleScriptPush(gBattlescriptCurrInstr); + gBattlescriptCurrInstr = BattleScript_GrudgeTakesPp; + gActiveBank = gBankAttacker; + EmitSetAttributes(0, moveIndex + REQUEST_PPMOVE1_BATTLE, 0, 1, &gBattleMons[gActiveBank].pp[moveIndex]); + MarkBufferBankForExecution(gActiveBank); + + gBattleTextBuff1[0] = PLACEHOLDER_BEGIN; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = gBattleMons[gBankAttacker].moves[moveIndex]; + gBattleTextBuff1[3] = gBattleMons[gBankAttacker].moves[moveIndex] >> 8; + gBattleTextBuff1[4] = EOS; + } + } + else + { + gBattlescriptCurrInstr += 7; + } + } +} + +void atk1A_faint_animation(void) +{ + if (gBattleExecBuffer == 0) + { + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + EmitFaintAnimation(0); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 2; + } +} + +void atk1B_faint_effects_clear(void) +{ + if (gBattleExecBuffer == 0) + { + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + if (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || gBattleMons[gActiveBank].hp == 0) + { + gBattleMons[gActiveBank].status1 = 0; + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 0x4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + } + + UndoEffectsAfterFainting(); // Effects like attractions, trapping, etc. + gBattlescriptCurrInstr += 2; + } +} + +void atk1C_jumpifstatus(void) +{ + u8 bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); + + if (gBattleMons[bank].status1 & flags && gBattleMons[bank].hp) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 10; +} + +void atk1D_jumpifstatus2(void) +{ + u8 bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); + + if (gBattleMons[bank].status2 & flags && gBattleMons[bank].hp) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 10; +} + +void atk1E_jumpifability(void) +{ + u8 bank; + u8 ability = BSScriptRead8(gBattlescriptCurrInstr + 2); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); + + if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_ATTACKER_SIDE) + { + bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_BANK_SIDE, gBankAttacker, ability, 0, 0); + if (bank) + { + gLastUsedAbility = ability; + gBattlescriptCurrInstr = jumpPtr; + RecordAbilityBattle(bank - 1, gLastUsedAbility); + gBattleScripting.field_15 = bank - 1; + } + else + gBattlescriptCurrInstr += 7; + } + else if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_NOT_ATTACKER_SIDE) + { + bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gBankAttacker, ability, 0, 0); + if (bank) + { + gLastUsedAbility = ability; + gBattlescriptCurrInstr = jumpPtr; + RecordAbilityBattle(bank - 1, gLastUsedAbility); + gBattleScripting.field_15 = bank - 1; + } + else + gBattlescriptCurrInstr += 7; + } + else + { + bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + if (gBattleMons[bank].ability == ability) + { + gLastUsedAbility = ability; + gBattlescriptCurrInstr = jumpPtr; + RecordAbilityBattle(bank, gLastUsedAbility); + gBattleScripting.field_15 = bank; + } + else + gBattlescriptCurrInstr += 7; + } +} + +void atk1F_jumpifsideaffecting(void) +{ + u8 side; + u16 flags; + const u8* jumpPtr; + + if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_ATTACKER) + side = GET_BANK_SIDE(gBankAttacker); + else + side = GET_BANK_SIDE(gBankTarget); + + flags = BS2ScriptRead16(gBattlescriptCurrInstr + 2); + jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 4); + + if (gSideAffecting[side] & flags) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 8; +} + +void atk20_jumpifstat(void) +{ + u8 ret = 0; + u8 bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + u8 value = gBattleMons[bank].statStages[BSScriptRead8(gBattlescriptCurrInstr + 3)]; + + switch (BSScriptRead8(gBattlescriptCurrInstr + 2)) + { + case CMP_EQUAL: + if (value == BSScriptRead8(gBattlescriptCurrInstr + 4)) + ret++; + break; + case CMP_NOT_EQUAL: + if (value != BSScriptRead8(gBattlescriptCurrInstr + 4)) + ret++; + break; + case CMP_GREATER_THAN: + if (value > BSScriptRead8(gBattlescriptCurrInstr + 4)) + ret++; + break; + case CMP_LESS_THAN: + if (value < BSScriptRead8(gBattlescriptCurrInstr + 4)) + ret++; + break; + case CMP_COMMON_BITS: + if (value & BSScriptRead8(gBattlescriptCurrInstr + 4)) + ret++; + break; + case CMP_NO_COMMON_BITS: + if (!(value & BSScriptRead8(gBattlescriptCurrInstr + 4))) + ret++; + break; + } + + if (ret) + gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); + else + gBattlescriptCurrInstr += 9; +} + +void atk21_jumpifstatus3(void) +{ + u32 flags; + const u8* jumpPtr; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); + jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7); + + if (BSScriptRead8(gBattlescriptCurrInstr + 6)) + { + if ((gStatuses3[gActiveBank] & flags) != 0) + gBattlescriptCurrInstr += 11; + else + gBattlescriptCurrInstr = jumpPtr; + } + else + { + if ((gStatuses3[gActiveBank] & flags) != 0) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 11; + } +} + +void atk22_jumpiftype(void) +{ + u8 bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + u8 type = BSScriptRead8(gBattlescriptCurrInstr + 2); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); + + if (gBattleMons[bank].type1 == type || gBattleMons[bank].type2 == type) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 7; +} + +void atk23_getexp(void) +{ + u16 item; + s32 i; // also used as stringId + u8 holdEffect; + s32 sentIn; + + s32 viaExpShare = 0; + u16* exp = &gBattleStruct->expValue; + + gBank1 = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + sentIn = gSentPokesToOpponent[(gBank1 & 2) >> 1]; + + switch (gBattleScripting.atk23_state) + { + case 0: // check if should receive exp at all + if (GetBankSide(gBank1) != SIDE_OPPONENT || (gBattleTypeFlags & + (BATTLE_TYPE_LINK + | BATTLE_TYPE_x2000000 + | BATTLE_TYPE_x4000000 + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_SAFARI + | BATTLE_TYPE_BATTLE_TOWER + | BATTLE_TYPE_EREADER_TRAINER))) + { + gBattleScripting.atk23_state = 6; // goto last case + } + else + { + gBattleScripting.atk23_state++; + gBattleStruct->field_DF |= gBitTable[gBattlePartyID[gBank1]]; + } + break; + case 1: // calculate experience points to redistribute + { + u16 calculatedExp; + s32 viaSentIn; + + for (viaSentIn = 0, i = 0; i < 6; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == SPECIES_NONE || GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0) + continue; + if (gBitTable[i] & sentIn) + viaSentIn++; + + item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + if (holdEffect == HOLD_EFFECT_EXP_SHARE) + viaExpShare++; + } + + calculatedExp = gBaseStats[gBattleMons[gBank1].species].expYield * gBattleMons[gBank1].level / 7; + + if (viaExpShare) // at least one mon is getting exp via exp share + { + *exp = calculatedExp / 2 / viaSentIn; + if (*exp == 0) + *exp = 1; + + gExpShareExp = calculatedExp / 2 / viaExpShare; + if (gExpShareExp == 0) + gExpShareExp = 1; + } + else + { + *exp = calculatedExp / viaSentIn; + if (*exp == 0) + *exp = 1; + gExpShareExp = 0; + } + + gBattleScripting.atk23_state++; + gBattleStruct->expGetterId = 0; + gBattleStruct->sentInPokes = sentIn; + } + // fall through + case 2: // set exp value to the poke in expgetter_id and print message + if (gBattleExecBuffer == 0) + { + item = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HELD_ITEM); + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + if (holdEffect != HOLD_EFFECT_EXP_SHARE && !(gBattleStruct->sentInPokes & 1)) + { + *(&gBattleStruct->sentInPokes) >>= 1; + gBattleScripting.atk23_state = 5; + gBattleMoveDamage = 0; // used for exp + } + else if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL) == MAX_MON_LEVEL) + { + *(&gBattleStruct->sentInPokes) >>= 1; + gBattleScripting.atk23_state = 5; + gBattleMoveDamage = 0; // used for exp + } + else + { + // music change in wild battle after fainting a poke + if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) && gBattleMons[0].hp && !gBattleStruct->wildVictorySong) + { + BattleMusicStop(); + PlayBGM(0x161); + gBattleStruct->wildVictorySong++; + } + + if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP)) + { + if (gBattleStruct->sentInPokes & 1) + gBattleMoveDamage = *exp; + else + gBattleMoveDamage = 0; + + if (holdEffect == HOLD_EFFECT_EXP_SHARE) + gBattleMoveDamage += gExpShareExp; + if (holdEffect == HOLD_EFFECT_LUCKY_EGG) + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; + + if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterId])) + { + // check if the pokemon doesn't belong to the player + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gBattleStruct->expGetterId >= 3) + { + i = 0x149; + } + else + { + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; + i = 0x14A; + } + } + else + { + i = 0x149; + } + + // get exp getter bank + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + if (!(gBattlePartyID[2] != gBattleStruct->expGetterId) && !(gAbsentBankFlags & gBitTable[2])) + gBattleStruct->expGetterBank = 2; + else + { + if (!(gAbsentBankFlags & gBitTable[0])) + gBattleStruct->expGetterBank = 0; + else + gBattleStruct->expGetterBank = 2; + } + } + else + gBattleStruct->expGetterBank = 0; + + // buffer poke name + gBattleTextBuff1[0] = PLACEHOLDER_BEGIN; + gBattleTextBuff1[1] = 4; + gBattleTextBuff1[2] = gBattleStruct->expGetterBank; + gBattleTextBuff1[3] = gBattleStruct->expGetterId; + gBattleTextBuff1[4] = EOS; + + // buffer 'gained' or 'gained a boosted' + gBattleTextBuff2[0] = PLACEHOLDER_BEGIN; + gBattleTextBuff2[1] = 0; + gBattleTextBuff2[2] = i; + gBattleTextBuff2[3] = (i & 0xFF00) >> 8; + gBattleTextBuff2[4] = EOS; + + // buffer exp number + gBattleTextBuff3[0] = PLACEHOLDER_BEGIN; + gBattleTextBuff3[1] = 1; + gBattleTextBuff3[2] = 4; // word + gBattleTextBuff3[3] = 5; // max digits + gBattleTextBuff3[4] = gBattleMoveDamage; + gBattleTextBuff3[5] = (gBattleMoveDamage & 0x0000FF00) >> 8; + gBattleTextBuff3[6] = (gBattleMoveDamage & 0x00FF0000) >> 16; + gBattleTextBuff3[7] = (gBattleMoveDamage & 0xFF000000) >> 24; + gBattleTextBuff3[8] = EOS; + + PrepareStringBattle(0xD, gBattleStruct->expGetterBank); + MonGainEVs(&gPlayerParty[gBattleStruct->expGetterId], gBattleMons[gBank1].species); + } + gBattleStruct->sentInPokes >>= 1; + gBattleScripting.atk23_state++; + } + } + break; + case 3: // Set stats and give exp + if (gBattleExecBuffer == 0) + { + gBattleBufferB[gBattleStruct->expGetterBank][0] = 0; + if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP) && GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL) != MAX_MON_LEVEL) + { + BATTLE_LVLUP_STATS->hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); + BATTLE_LVLUP_STATS->atk = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); + BATTLE_LVLUP_STATS->def = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); + BATTLE_LVLUP_STATS->spd = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); + BATTLE_LVLUP_STATS->spAtk = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); + BATTLE_LVLUP_STATS->spDef = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPDEF); + + gActiveBank = gBattleStruct->expGetterBank; + EmitExpUpdate(0, gBattleStruct->expGetterId, gBattleMoveDamage); + MarkBufferBankForExecution(gActiveBank); + } + gBattleScripting.atk23_state++; + } + break; + case 4: // lvl up if necessary + if (gBattleExecBuffer == 0) + { + gActiveBank = gBattleStruct->expGetterBank; + if (gBattleBufferB[gActiveBank][0] == 0x21 && gBattleBufferB[gActiveBank][1] == 0xB) + { + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId) + sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + + // buff poke name + gBattleTextBuff1[0] = PLACEHOLDER_BEGIN; + gBattleTextBuff1[1] = 4; + gBattleTextBuff1[2] = gActiveBank; + gBattleTextBuff1[3] = gBattleStruct->expGetterId; + gBattleTextBuff1[4] = EOS; + + // buff level + gBattleTextBuff2[0] = PLACEHOLDER_BEGIN; + gBattleTextBuff2[1] = 1; + gBattleTextBuff2[2] = 1; + gBattleTextBuff2[3] = 3; + gBattleTextBuff2[4] = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); + gBattleTextBuff2[5] = EOS; + + BattleScriptPushCursor(); + gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterId]; + gBattlescriptCurrInstr = BattleScript_LevelUp; + gBattleMoveDamage = (gBattleBufferB[gActiveBank][2] | (gBattleBufferB[gActiveBank][3] << 8)); + AdjustFriendship(&gPlayerParty[gBattleStruct->expGetterId], 0); + + // update battle mon structure after level up + if (gBattlePartyID[0] == gBattleStruct->expGetterId && gBattleMons[0].hp) + { + gBattleMons[0].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); + gBattleMons[0].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP); + gBattleMons[0].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); + gBattleMons[0].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); + gBattleMons[0].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); + // Why is this duplicated? + gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); + gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); + + gBattleMons[0].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); + gBattleMons[0].spDefense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPDEF); + } + // What is else if? + if (gBattlePartyID[2] == gBattleStruct->expGetterId && gBattleMons[2].hp && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gBattleMons[2].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); + gBattleMons[2].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP); + gBattleMons[2].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); + gBattleMons[2].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); + gBattleMons[2].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); + // Duplicated again, but this time there's no Sp Defense + gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); + gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); + + gBattleMons[2].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); + } + gBattleScripting.atk23_state = 5; + } + else + { + gBattleMoveDamage = 0; + gBattleScripting.atk23_state = 5; + } + } + break; + case 5: // looper increment + if (gBattleMoveDamage) // there is exp to give, goto case 3 that gives exp + gBattleScripting.atk23_state = 3; + else + { + gBattleStruct->expGetterId++; + if (gBattleStruct->expGetterId <= 5) + gBattleScripting.atk23_state = 2; // loop again + else + gBattleScripting.atk23_state = 6; // we're done + } + break; + case 6: // increment instruction + if (gBattleExecBuffer == 0) + { + // not sure why gf clears the item and ability here + gBattleMons[gBank1].item = 0; + gBattleMons[gBank1].ability = 0; + gBattlescriptCurrInstr += 2; + } + break; + } +} + +#ifdef NONMATCHING +void atk24(void) +{ + u16 HP_count = 0; + s32 i; + + if (gBattleExecBuffer) + return; + + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId == STEVEN_PARTNER_ID) + { + for (i = 0; i < 3; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) + HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); + } + } + else + { + for (i = 0; i < 6; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) + && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->field_2A0 & gBitTable[i]))) + { + HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); + } + } + } + + if (HP_count == 0) + gBattleOutcome |= BATTLE_LOST; + + for (HP_count = 0, i = 0; i < 6; i++) + { + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES) && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG) + && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->field_2A1 & gBitTable[i]))) + { + HP_count += GetMonData(&gEnemyParty[i], MON_DATA_HP); + } + } + + if (HP_count == 0) + gBattleOutcome |= BATTLE_WON; + + if (gBattleOutcome == 0 && (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))) + { + s32 foundPlayer; + s32 foundOpponent; + + // Impossible to decompile loops. + for (foundPlayer = 0, i = 0; i < gNoOfAllBanks; i += 2) + { + if (HITMARKER_UNK(i) & gHitMarker && !gSpecialStatuses[i].flag40) + foundPlayer++; + } + + for (foundOpponent = 0, i = 1; i < gNoOfAllBanks; i += 2) + { + if (HITMARKER_UNK(i) & gHitMarker && !gSpecialStatuses[i].flag40) + foundOpponent++; + } + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (foundOpponent + foundPlayer > 1) + gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; + } + else + { + if (foundOpponent != 0 && foundPlayer != 0) + gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; + } + } + else + { + gBattlescriptCurrInstr += 5; + } +} +#else +__attribute__((naked)) +void atk24(void) +{ + asm("\n\ + .syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + movs r6, 0\n\ + ldr r0, =gBattleExecBuffer\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + beq _0804ACE2\n\ + b _0804AF22\n\ + _0804ACE2:\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 15\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804AD48\n\ + ldr r0, =gPartnerTrainerId\n\ + ldrh r1, [r0]\n\ + ldr r0, =0x00000c03\n\ + cmp r1, r0\n\ + bne _0804AD48\n\ + movs r5, 0\n\ + _0804ACFC:\n\ + movs r0, 0x64\n\ + adds r1, r5, 0\n\ + muls r1, r0\n\ + ldr r0, =gPlayerParty\n\ + adds r4, r1, r0\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _0804AD2C\n\ + adds r0, r4, 0\n\ + movs r1, 0x2D\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + bne _0804AD2C\n\ + adds r0, r4, 0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + adds r0, r6, r0\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ + _0804AD2C:\n\ + adds r5, 0x1\n\ + cmp r5, 0x2\n\ + ble _0804ACFC\n\ + b _0804ADA8\n\ + .pool\n\ + _0804AD48:\n\ + movs r5, 0\n\ + _0804AD4A:\n\ + movs r0, 0x64\n\ + adds r1, r5, 0\n\ + muls r1, r0\n\ + ldr r0, =gPlayerParty\n\ + adds r4, r1, r0\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _0804ADA2\n\ + adds r0, r4, 0\n\ + movs r1, 0x2D\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + bne _0804ADA2\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 11\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804AD94\n\ + ldr r0, =gBattleStruct\n\ + ldr r0, [r0]\n\ + movs r1, 0xA8\n\ + lsls r1, 2\n\ + adds r0, r1\n\ + ldrb r1, [r0]\n\ + ldr r2, =gBitTable\n\ + lsls r0, r5, 2\n\ + adds r0, r2\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _0804ADA2\n\ + _0804AD94:\n\ + adds r0, r4, 0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + adds r0, r6, r0\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ + _0804ADA2:\n\ + adds r5, 0x1\n\ + cmp r5, 0x5\n\ + ble _0804AD4A\n\ + _0804ADA8:\n\ + cmp r6, 0\n\ + bne _0804ADB6\n\ + ldr r0, =gBattleOutcome\n\ + ldrb r1, [r0]\n\ + movs r2, 0x2\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ + _0804ADB6:\n\ + movs r6, 0\n\ + movs r5, 0\n\ + _0804ADBA:\n\ + movs r0, 0x64\n\ + adds r1, r5, 0\n\ + muls r1, r0\n\ + ldr r0, =gEnemyParty\n\ + adds r4, r1, r0\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _0804AE10\n\ + adds r0, r4, 0\n\ + movs r1, 0x2D\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + bne _0804AE10\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 11\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804AE02\n\ + ldr r0, =gBattleStruct\n\ + ldr r0, [r0]\n\ + ldr r1, =0x000002a1\n\ + adds r0, r1\n\ + ldrb r1, [r0]\n\ + ldr r2, =gBitTable\n\ + lsls r0, r5, 2\n\ + adds r0, r2\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _0804AE10\n\ + _0804AE02:\n\ + adds r0, r4, 0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + adds r0, r6, r0\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ + _0804AE10:\n\ + adds r5, 0x1\n\ + cmp r5, 0x5\n\ + ble _0804ADBA\n\ + ldr r2, =gBattleOutcome\n\ + cmp r6, 0\n\ + bne _0804AE24\n\ + ldrb r0, [r2]\n\ + movs r1, 0x1\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + _0804AE24:\n\ + ldrb r0, [r2]\n\ + cmp r0, 0\n\ + bne _0804AF1A\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r1, [r0]\n\ + ldr r2, =0x02000002\n\ + ands r1, r2\n\ + mov r8, r0\n\ + cmp r1, 0\n\ + beq _0804AF1A\n\ + movs r3, 0\n\ + movs r5, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r1, [r0]\n\ + mov r12, r0\n\ + ldr r7, =gBattlescriptCurrInstr\n\ + cmp r3, r1\n\ + bge _0804AE70\n\ + ldr r0, =gHitMarker\n\ + movs r6, 0x80\n\ + lsls r6, 21\n\ + ldr r4, [r0]\n\ + adds r2, r1, 0\n\ + ldr r1, =gSpecialStatuses\n\ + _0804AE54:\n\ + adds r0, r6, 0\n\ + lsls r0, r5\n\ + ands r0, r4\n\ + cmp r0, 0\n\ + beq _0804AE68\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _0804AE68\n\ + adds r3, 0x1\n\ + _0804AE68:\n\ + adds r1, 0x28\n\ + adds r5, 0x2\n\ + cmp r5, r2\n\ + blt _0804AE54\n\ + _0804AE70:\n\ + movs r2, 0\n\ + movs r5, 0x1\n\ + mov r4, r12\n\ + ldrb r1, [r4]\n\ + cmp r5, r1\n\ + bge _0804AEAA\n\ + ldr r0, =gHitMarker\n\ + movs r4, 0x80\n\ + lsls r4, 21\n\ + mov r12, r4\n\ + ldr r6, [r0]\n\ + ldr r0, =gSpecialStatuses\n\ + adds r4, r1, 0\n\ + adds r1, r0, 0\n\ + adds r1, 0x14\n\ + _0804AE8E:\n\ + mov r0, r12\n\ + lsls r0, r5\n\ + ands r0, r6\n\ + cmp r0, 0\n\ + beq _0804AEA2\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _0804AEA2\n\ + adds r2, 0x1\n\ + _0804AEA2:\n\ + adds r1, 0x28\n\ + adds r5, 0x2\n\ + cmp r5, r4\n\ + blt _0804AE8E\n\ + _0804AEAA:\n\ + mov r1, r8\n\ + ldr r0, [r1]\n\ + movs r1, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804AEF0\n\ + adds r0, r2, r3\n\ + cmp r0, 0x1\n\ + bgt _0804AEF8\n\ + b _0804AF12\n\ + .pool\n\ + _0804AEF0:\n\ + cmp r2, 0\n\ + beq _0804AF12\n\ + cmp r3, 0\n\ + beq _0804AF12\n\ + _0804AEF8:\n\ + ldr r2, [r7]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + adds r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + adds r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + adds r1, r0\n\ + str r1, [r7]\n\ + b _0804AF22\n\ + _0804AF12:\n\ + ldr r0, [r7]\n\ + adds r0, 0x5\n\ + str r0, [r7]\n\ + b _0804AF22\n\ + _0804AF1A:\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x5\n\ + str r0, [r1]\n\ + _0804AF22:\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} + +#endif // NONMATCHING + +void MoveValuesCleanUp(void) +{ + gBattleMoveFlags = 0; + gBattleScripting.dmgMultiplier = 1; + gCritMultiplier = 1; + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattleCommunication[6] = 0; + gHitMarker &= ~(HITMARKER_DESTINYBOND); + gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); +} + +void atk25_move_values_cleanup(void) +{ + MoveValuesCleanUp(); + gBattlescriptCurrInstr += 1; +} + +void atk26_set_multihit(void) +{ + gMultiHitCounter = BSScriptRead8(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr += 2; +} + +void atk27_decrement_multihit(void) +{ + if (--gMultiHitCounter == 0) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); +} + +void atk28_goto(void) +{ + gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); +} + +void atk29_jumpifbyte(void) +{ + u8 caseID = BSScriptRead8(gBattlescriptCurrInstr + 1); + const u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); + u8 value = BSScriptRead8(gBattlescriptCurrInstr + 6); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7); + + gBattlescriptCurrInstr += 11; + + switch (caseID) + { + case CMP_EQUAL: + if (*memByte == value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NOT_EQUAL: + if (*memByte != value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_GREATER_THAN: + if (*memByte > value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_LESS_THAN: + if (*memByte < value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_COMMON_BITS: + if (*memByte & value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NO_COMMON_BITS: + if (!(*memByte & value)) + gBattlescriptCurrInstr = jumpPtr; + break; + } +} + +void atk2A_jumpifhalfword(void) +{ + u8 caseID = BSScriptRead8(gBattlescriptCurrInstr + 1); + const u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); + u16 value = BS2ScriptRead16(gBattlescriptCurrInstr + 6); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 8); + + gBattlescriptCurrInstr += 12; + + switch (caseID) + { + case CMP_EQUAL: + if (*memHword == value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NOT_EQUAL: + if (*memHword != value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_GREATER_THAN: + if (*memHword > value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_LESS_THAN: + if (*memHword < value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_COMMON_BITS: + if (*memHword & value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NO_COMMON_BITS: + if (!(*memHword & value)) + gBattlescriptCurrInstr = jumpPtr; + break; + } +} + +void atk2B_jumpifword(void) +{ + u8 caseID = BSScriptRead8(gBattlescriptCurrInstr + 1); + const u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); + u32 value = BSScriptRead32(gBattlescriptCurrInstr + 6); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); + + gBattlescriptCurrInstr += 14; + + switch (caseID) + { + case CMP_EQUAL: + if (*memWord == value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NOT_EQUAL: + if (*memWord != value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_GREATER_THAN: + if (*memWord > value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_LESS_THAN: + if (*memWord < value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_COMMON_BITS: + if (*memWord & value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NO_COMMON_BITS: + if (!(*memWord & value)) + gBattlescriptCurrInstr = jumpPtr; + break; + } +} + +void atk2C_jumpifarrayequal(void) +{ + const u8* mem1 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + const u8* mem2 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); + u32 size = BSScriptRead8(gBattlescriptCurrInstr + 9); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); + + u8 i; + for (i = 0; i < size; i++) + { + if (*mem1 != *mem2) + { + gBattlescriptCurrInstr += 14; + break; + } + mem1++, mem2++; + } + + if (i == size) + gBattlescriptCurrInstr = jumpPtr; +} + +void atk2D_jumpifarraynotequal(void) +{ + u8 equalBytes = 0; + const u8* mem1 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + const u8* mem2 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); + u32 size = BSScriptRead8(gBattlescriptCurrInstr + 9); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); + + u8 i; + for (i = 0; i < size; i++) + { + if (*mem1 == *mem2) + { + equalBytes++; + } + mem1++, mem2++; + } + + if (equalBytes != size) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 14; +} + +void atk2E_setbyte(void) +{ + u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + *memByte = BSScriptRead8(gBattlescriptCurrInstr + 5); + + gBattlescriptCurrInstr += 6; +} + +void atk2F_addbyte(void) +{ + u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + *memByte += BSScriptRead8(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr += 6; +} + +void atk30_subbyte(void) +{ + u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + *memByte -= BSScriptRead8(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr += 6; +} + +void atk31_copyarray(void) +{ + u8* dest = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + const u8* src = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); + s32 size = BSScriptRead8(gBattlescriptCurrInstr + 9); + + s32 i; + for (i = 0; i < size; i++) + { + dest[i] = src[i]; + } + + gBattlescriptCurrInstr += 10; +} + +void atk32_copyarray_withindex(void) +{ + u8* dest = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + const u8* src = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); + const u8* index = BS2ScriptReadPtr(gBattlescriptCurrInstr + 9); + s32 size = BSScriptRead8(gBattlescriptCurrInstr + 13); + + s32 i; + for (i = 0; i < size; i++) + { + dest[i] = src[i + *index]; + } + + gBattlescriptCurrInstr += 14; +} + +void atk33_orbyte(void) +{ + u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + *memByte |= BSScriptRead8(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr += 6; +} + +void atk34_orhalfword(void) +{ + u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + u16 val = BS2ScriptRead16(gBattlescriptCurrInstr + 5); + + *memHword |= val; + gBattlescriptCurrInstr += 7; +} + +void atk35_orword(void) +{ + u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + u32 val = BS2ScriptRead32(gBattlescriptCurrInstr + 5); + + *memWord |= val; + gBattlescriptCurrInstr += 9; +} + +void atk36_bicbyte(void) +{ + u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + *memByte &= ~(BSScriptRead8(gBattlescriptCurrInstr + 5)); + gBattlescriptCurrInstr += 6; +} + +void atk37_bichalfword(void) +{ + u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + u16 val = BS2ScriptRead16(gBattlescriptCurrInstr + 5); + + *memHword &= ~val; + gBattlescriptCurrInstr += 7; +} + +void atk38_bicword(void) +{ + u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + u32 val = BS2ScriptRead32(gBattlescriptCurrInstr + 5); + + *memWord &= ~val; + gBattlescriptCurrInstr += 9; +} + +void atk39_pause(void) +{ + if (gBattleExecBuffer == 0) + { + u16 value = BS2ScriptRead16(gBattlescriptCurrInstr + 1); + if (++gPauseCounterBattle >= value) + { + gPauseCounterBattle = 0; + gBattlescriptCurrInstr += 3; + } + } +} + +void atk3A_waitstate(void) +{ + if (gBattleExecBuffer == 0) + gBattlescriptCurrInstr++; +} + +void atk3B_healthbar_update(void) +{ + if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_TARGET) + gActiveBank = gBankTarget; + else + gActiveBank = gBankAttacker; + + EmitHealthBarUpdate(0, gBattleMoveDamage); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 2; +} + +void atk3C_return(void) +{ + BattleScriptPop(); +} + +void atk3D_end(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_ARENA) + sub_81A5718(gBankAttacker); + + gBattleMoveFlags = 0; + gActiveBank = 0; + gFightStateTracker = 0xB; +} + +void atk3E_end2(void) +{ + gActiveBank = 0; + gFightStateTracker = 0xB; +} + +void atk3F_end3(void) // pops the main function stack +{ + BattleScriptPop(); + if (BATTLE_CALLBACKS_STACK->size) + BATTLE_CALLBACKS_STACK->size--; + gBattleMainFunc = BATTLE_CALLBACKS_STACK->function[BATTLE_CALLBACKS_STACK->size]; +} + +void atk41_call(void) +{ + BattleScriptPush(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); +} + +void atk42_jumpiftype2(void) +{ + u8 bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + if (BSScriptRead8(gBattlescriptCurrInstr + 2) == gBattleMons[bank].type1 || BSScriptRead8(gBattlescriptCurrInstr + 2) == gBattleMons[bank].type2) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 3); + else + gBattlescriptCurrInstr += 7; +} + +void atk43_jumpifabilitypresent(void) +{ + if (AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, BSScriptRead8(gBattlescriptCurrInstr + 1), 0, 0)) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; +} + +void atk44(void) +{ + *(gBankAttacker + gBattleStruct->field_54) = 1; +} + +void atk45_playanimation(void) +{ + const u16* argumentPtr; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); + + if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE + || gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE + || gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE) + { + EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 7; + } + else if (gHitMarker & HITMARKER_NO_ANIMATIONS) + { + BattleScriptPush(gBattlescriptCurrInstr + 7); + gBattlescriptCurrInstr = BattleScript_Pausex20; + } + else if (gBattlescriptCurrInstr[2] == B_ANIM_RAIN_CONTINUES + || gBattlescriptCurrInstr[2] == B_ANIM_SUN_CONTINUES + || gBattlescriptCurrInstr[2] == B_ANIM_SANDSTORM_CONTINUES + || gBattlescriptCurrInstr[2] == B_ANIM_HAIL_CONTINUES) + { + EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 7; + } + else if (gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) + { + gBattlescriptCurrInstr += 7; + } + else + { + EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 7; + } +} + +void atk46_playanimation2(void) // animation Id is stored in the first pointer +{ + const u16* argumentPtr; + const u8* animationIdPtr; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + animationIdPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); + argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); + + if (*animationIdPtr == B_ANIM_STATS_CHANGE + || *animationIdPtr == B_ANIM_SNATCH_MOVE + || *animationIdPtr == B_ANIM_SUBSTITUTE_FADE) + { + EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 10; + } + else if (gHitMarker & HITMARKER_NO_ANIMATIONS) + { + gBattlescriptCurrInstr += 10; + } + else if (*animationIdPtr == B_ANIM_RAIN_CONTINUES + || *animationIdPtr == B_ANIM_SUN_CONTINUES + || *animationIdPtr == B_ANIM_SANDSTORM_CONTINUES + || *animationIdPtr == B_ANIM_HAIL_CONTINUES) + { + EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 10; + } + else if (gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) + { + gBattlescriptCurrInstr += 10; + } + else + { + EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 10; + } +} + +void atk47_setgraphicalstatchangevalues(void) +{ + u8 value = 0; + switch (gBattleScripting.statChanger & 0xF0) + { + case 0x10: // +1 + value = 0xF; + break; + case 0x20: // +2 + value = 0x27; + break; + case 0x90: // -1 + value = 0x16; + break; + case 0xA0: // -2 + value = 0x2E; + break; + } + gBattleScripting.animArg1 = (gBattleScripting.statChanger & 0xF) + value - 1; + gBattleScripting.animArg2 = 0; + gBattlescriptCurrInstr++; +} + +void atk48_playstatchangeanimation(void) +{ + s32 currStat = 0; + s16 statAnimId = 0; + s32 checkingStatAnimId = 0; + s32 changeableStats = 0; + u32 statsToCheck = 0; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + statsToCheck = BSScriptRead8(gBattlescriptCurrInstr + 2); + + if (gBattlescriptCurrInstr[3] & 1) // goes down + { + for (checkingStatAnimId = (gBattlescriptCurrInstr[3] & 0x2) ? 0x2D : 0x15; + statsToCheck != 0; + statsToCheck >>= 1, checkingStatAnimId += 1, currStat++) + { + if (!(statsToCheck & 1)) + continue; + if (!(gBattlescriptCurrInstr[3] & 8)) + { + if (gBattleMons[gActiveBank].statStages[currStat] > 0) + { + statAnimId = checkingStatAnimId; + changeableStats++; + } + } + else if (!gSideTimers[GET_BANK_SIDE(gActiveBank)].mistTimer + && gBattleMons[gActiveBank].ability != ABILITY_CLEAR_BODY + && gBattleMons[gActiveBank].ability != ABILITY_WHITE_SMOKE + && !(gBattleMons[gActiveBank].ability == ABILITY_KEEN_EYE && currStat == STAT_STAGE_ACC) + && !(gBattleMons[gActiveBank].ability == ABILITY_HYPER_CUTTER && currStat == STAT_STAGE_ATK)) + { + if (gBattleMons[gActiveBank].statStages[currStat] > 0) + { + statAnimId = checkingStatAnimId; + changeableStats++; + } + } + } + + if (changeableStats > 1) // more than one stat, so the color is gray + { + if (gBattlescriptCurrInstr[3] & 2) + statAnimId = 0x3A; + else + statAnimId = 0x39; + } + } + else // goes up + { + for (checkingStatAnimId = (gBattlescriptCurrInstr[3] & 0x2) ? 0x26 : 0xE; + statsToCheck != 0; + statsToCheck >>= 1, checkingStatAnimId += 1, currStat++) + { + if (statsToCheck & 1 && gBattleMons[gActiveBank].statStages[currStat] < 0xC) + { + statAnimId = checkingStatAnimId; + changeableStats++; + } + } + + if (changeableStats > 1) // more than one stat, so the color is gray + { + if (gBattlescriptCurrInstr[3] & 2) + statAnimId = 0x38; + else + statAnimId = 0x37; + } + } + + if (gBattlescriptCurrInstr[3] & 4 && changeableStats < 2) + { + gBattlescriptCurrInstr += 4; + } + else if (changeableStats != 0 && gBattleScripting.field_1B == 0) + { + EmitBattleAnimation(0, B_ANIM_STATS_CHANGE, statAnimId); + MarkBufferBankForExecution(gActiveBank); + if (gBattlescriptCurrInstr[3] & 4 && changeableStats > 1) + gBattleScripting.field_1B = 1; + gBattlescriptCurrInstr += 4; + } + else + { + gBattlescriptCurrInstr += 4; + } +} -- cgit v1.2.3 From fc57c6c817bcb8bed4469b5114ced17129bdca81 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sat, 23 Sep 2017 00:06:52 +0200 Subject: atk 48 is really troublesome --- src/battle_4.c | 63 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/battle_4.c b/src/battle_4.c index 8e0be22c2..ec84d1a5c 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -4271,48 +4271,49 @@ void atk47_setgraphicalstatchangevalues(void) void atk48_playstatchangeanimation(void) { - s32 currStat = 0; + u32 currStat = 0; s16 statAnimId = 0; - s32 checkingStatAnimId = 0; + s16 checkingStatAnimId = 0; s32 changeableStats = 0; u32 statsToCheck = 0; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); - statsToCheck = BSScriptRead8(gBattlescriptCurrInstr + 2); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + statsToCheck = gBattlescriptCurrInstr[2]; - if (gBattlescriptCurrInstr[3] & 1) // goes down + if (gBattlescriptCurrInstr[3] & ATK48_STAT_NEGATIVE) // goes down { - for (checkingStatAnimId = (gBattlescriptCurrInstr[3] & 0x2) ? 0x2D : 0x15; - statsToCheck != 0; - statsToCheck >>= 1, checkingStatAnimId += 1, currStat++) + checkingStatAnimId = (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) ? 0x2D : 0x15; + while (statsToCheck != 0) { - if (!(statsToCheck & 1)) - continue; - if (!(gBattlescriptCurrInstr[3] & 8)) + if (statsToCheck & 1) { - if (gBattleMons[gActiveBank].statStages[currStat] > 0) + if (!(gBattlescriptCurrInstr[3] & ATK48_LOWER_FAIL_CHECK)) { - statAnimId = checkingStatAnimId; - changeableStats++; + if (gBattleMons[gActiveBank].statStages[currStat] > 0) + { + statAnimId = checkingStatAnimId; + changeableStats++; + } } - } - else if (!gSideTimers[GET_BANK_SIDE(gActiveBank)].mistTimer - && gBattleMons[gActiveBank].ability != ABILITY_CLEAR_BODY - && gBattleMons[gActiveBank].ability != ABILITY_WHITE_SMOKE - && !(gBattleMons[gActiveBank].ability == ABILITY_KEEN_EYE && currStat == STAT_STAGE_ACC) - && !(gBattleMons[gActiveBank].ability == ABILITY_HYPER_CUTTER && currStat == STAT_STAGE_ATK)) - { - if (gBattleMons[gActiveBank].statStages[currStat] > 0) + else if (!gSideTimers[GET_BANK_SIDE(gActiveBank)].mistTimer + && gBattleMons[gActiveBank].ability != ABILITY_CLEAR_BODY + && gBattleMons[gActiveBank].ability != ABILITY_WHITE_SMOKE + && !(gBattleMons[gActiveBank].ability == ABILITY_KEEN_EYE && currStat == STAT_STAGE_ACC) + && !(gBattleMons[gActiveBank].ability == ABILITY_HYPER_CUTTER && currStat == STAT_STAGE_ATK)) { - statAnimId = checkingStatAnimId; - changeableStats++; + if (gBattleMons[gActiveBank].statStages[currStat] > 0) + { + statAnimId = checkingStatAnimId; + changeableStats++; + } } } + statsToCheck >>= 1, checkingStatAnimId++, currStat++; } if (changeableStats > 1) // more than one stat, so the color is gray { - if (gBattlescriptCurrInstr[3] & 2) + if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) statAnimId = 0x3A; else statAnimId = 0x39; @@ -4320,27 +4321,27 @@ void atk48_playstatchangeanimation(void) } else // goes up { - for (checkingStatAnimId = (gBattlescriptCurrInstr[3] & 0x2) ? 0x26 : 0xE; - statsToCheck != 0; - statsToCheck >>= 1, checkingStatAnimId += 1, currStat++) + checkingStatAnimId = (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) ? 0x26 : 0xE; + while (statsToCheck != 0) { if (statsToCheck & 1 && gBattleMons[gActiveBank].statStages[currStat] < 0xC) { statAnimId = checkingStatAnimId; changeableStats++; } + statsToCheck >>= 1, checkingStatAnimId += 1, currStat++; } if (changeableStats > 1) // more than one stat, so the color is gray { - if (gBattlescriptCurrInstr[3] & 2) + if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) statAnimId = 0x38; else statAnimId = 0x37; } } - if (gBattlescriptCurrInstr[3] & 4 && changeableStats < 2) + if (gBattlescriptCurrInstr[3] & ATK48_BIT_x4 && changeableStats < 2) { gBattlescriptCurrInstr += 4; } @@ -4348,7 +4349,7 @@ void atk48_playstatchangeanimation(void) { EmitBattleAnimation(0, B_ANIM_STATS_CHANGE, statAnimId); MarkBufferBankForExecution(gActiveBank); - if (gBattlescriptCurrInstr[3] & 4 && changeableStats > 1) + if (gBattlescriptCurrInstr[3] & ATK48_BIT_x4 && changeableStats > 1) gBattleScripting.field_1B = 1; gBattlescriptCurrInstr += 4; } -- cgit v1.2.3 From 561d60342f7ec39f03671ce37ab4f0ab8d0244c6 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 22 Sep 2017 21:18:53 -0400 Subject: Decompile data --- src/unk_text_util_2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/unk_text_util_2.c b/src/unk_text_util_2.c index d9bd9d98d..d88af611f 100644 --- a/src/unk_text_util_2.c +++ b/src/unk_text_util_2.c @@ -4,8 +4,8 @@ #include "text.h" #include "sound.h" -extern const u8 gUnknown_08616124[]; -extern const u16 gFont6BrailleGlyphs[]; +static const u8 gUnknown_08616124[] = {1, 2, 4}; +static const u16 gFont6BrailleGlyphs[] = INCBIN_U16("data/graphics/fonts/font6.fwjpnfont"); static void DecompressGlyphFont6(u16); -- cgit v1.2.3 From 4cf115000289d10de3408e752b37128446dd261c Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 22 Sep 2017 21:26:37 -0400 Subject: clion pls --- src/text.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/text.c b/src/text.c index fe1c5df24..90c069293 100644 --- a/src/text.c +++ b/src/text.c @@ -1,9 +1,9 @@ #include "global.h" -#include "text.h" #include "main.h" #include "palette.h" #include "string_util.h" #include "window.h" +#include "text.h" extern void FillBitmapRect4Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue); extern void FillWindowPixelRect(u8 windowId, u8 fillValue, u16 x, u16 y, u16 width, u16 height); -- cgit v1.2.3 From 244842618352ec090234bd63a0878f47459ea4a3 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Fri, 22 Sep 2017 22:45:47 -0400 Subject: decompile field_special_scene.c --- src/field_special_scene.c | 365 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100755 src/field_special_scene.c (limited to 'src') diff --git a/src/field_special_scene.c b/src/field_special_scene.c new file mode 100755 index 000000000..22a20161d --- /dev/null +++ b/src/field_special_scene.c @@ -0,0 +1,365 @@ +#include "global.h" +#include "task.h" +#include "field_map_obj.h" +#include "songs.h" +#include "sound.h" +#include "palette.h" +#include "script.h" +#include "vars.h" +#include "event_data.h" +#include "main.h" +#include "sprite.h" + +#define SECONDS(value) ((signed) (60.0 * value + 0.5)) + +// porthole states +enum +{ + INIT_PORTHOLE, + IDLE_CHECK, + EXECUTE_MOVEMENT, + EXIT_PORTHOLE, +}; + +extern void SetCameraPanning(s16 x, s16 y); +extern void SetCameraPanningCallback(void ( *callback)()); +extern void InstallCameraPanAheadCallback(); +extern void pal_fill_black(void); +extern void MapGridSetMetatileIdAt(s32 x, s32 y, u16 metatileId); +extern void DrawWholeMapView(); + +extern s8 gTruckCamera_HorizontalTable[]; + +extern u8 gUnknown_0858E8AB[]; +extern u8 gUnknown_0858E8AD[]; + +void Task_Truck3(u8); + +s32 GetTruckCameraBobbingY(int a1) +{ + if (!(a1 % 120)) + return -1; + else if ((a1 % 10) <= 4) + return 1; + + return 0; +} + +s32 GetTruckBoxMovement(int a1) // for the box movement? +{ + if (!((a1 + 120) % 180)) + return -1; + + return 0; +} + +// smh STILL BROKEN IN EMERALD +void Task_Truck1(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + s16 cameraYpan; + s16 box1 = 0; + s16 box2 = 0; + s16 box3 = 0; + u8 mapNum, mapGroup; + register s16 zero asm("r4"); + + box1 = GetTruckBoxMovement(data[0] + 30) * 4; // top box. + sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3, box1 + 3); + box2 = GetTruckBoxMovement(data[0]) * 2; // bottom left box. + sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 0, box2 - 3); + box3 = GetTruckBoxMovement(data[0]) * 4; // bottom right box. + mapNum = gSaveBlock1Ptr->location.mapNum; + mapGroup = gSaveBlock1Ptr->location.mapGroup; + zero = 0; + sub_808E82C(3, mapNum, mapGroup, -3, box3); + + if (++data[0] == SECONDS(500)) // this will never run + data[0] = zero; // reset the timer if it gets stuck. + + cameraYpan = GetTruckCameraBobbingY(data[0]); + SetCameraPanning(0, cameraYpan); +} + +void Task_Truck2(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + s16 cameraYpan; + s16 cameraXpan; + s16 box1; + s16 box2; + s16 box3; + + data[0]++; + data[2]++; + + if (data[0] > 5) + { + data[0] = 0; + data[1]++; + } + if ((u16)data[1] == 19) + { + DestroyTask(taskId); + } + else + { + if (gTruckCamera_HorizontalTable[data[1]] == 2) + gTasks[taskId].func = Task_Truck3; + + cameraXpan = gTruckCamera_HorizontalTable[data[1]]; + cameraYpan = GetTruckCameraBobbingY(data[2]); + SetCameraPanning(cameraXpan, cameraYpan); + box1 = GetTruckBoxMovement(data[2] + 30) * 4; + sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3 - cameraXpan, box1 + 3); + box2 = GetTruckBoxMovement(data[2]) * 2; + sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -cameraXpan, box2 - 3); + box3 = GetTruckBoxMovement(data[2]) * 4; + sub_808E82C(3, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -3 - cameraXpan, box3); + } +} + +void Task_Truck3(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + s16 cameraXpan; + s16 cameraYpan; + + data[0]++; + + if (data[0] > 5) + { + data[0] = 0; + data[1]++; + } + + if ((u16)data[1] == 19) + { + DestroyTask(taskId); + } + else + { + cameraXpan = gTruckCamera_HorizontalTable[data[1]]; + cameraYpan = 0; + SetCameraPanning(cameraXpan, 0); + sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3 - cameraXpan, cameraYpan + 3); + sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -cameraXpan, cameraYpan - 3); + sub_808E82C(3, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -3 - cameraXpan, cameraYpan); + } +} + +void Task_HandleTruckSequence(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + + switch (data[0]) + { + /* + Each case has a timer which is handled with data[1], incrementing + until it reaches the if function's condition, which sets the next task up. + */ + case 0: + data[1]++; + if (data[1] == SECONDS(1.5)) + { + SetCameraPanningCallback(NULL); + data[1] = 0; // reset the timer. + data[2] = CreateTask(Task_Truck1, 0xA); + data[0] = 1; // run the next case. + PlaySE(SE_TRACK_MOVE); + } + break; + case 1: + data[1]++; + if (data[1] == SECONDS(2.5)) + { + pal_fill_black(); + data[1] = 0; + data[0] = 2; + } + break; + case 2: + data[1]++; + if (!gPaletteFade.active && data[1] > SECONDS(5)) + { + data[1] = 0; + DestroyTask(data[2]); + data[3] = CreateTask(Task_Truck2, 0xA); + data[0] = 3; + PlaySE(SE_TRACK_STOP); + } + break; + case 3: + if (!gTasks[data[3]].isActive) // is Truck2 no longer active (is Truck3 active?) + { + InstallCameraPanAheadCallback(); + data[1] = 0; + data[0] = 4; + } + break; + case 4: + data[1]++; + if (data[1] == 90) + { + PlaySE(SE_TRACK_HAIK); + data[1] = 0; + data[0] = 5; + } + break; + case 5: + data[1]++; + if (data[1] == 120) + { + MapGridSetMetatileIdAt(11, 8, 520); + MapGridSetMetatileIdAt(11, 9, 528); + MapGridSetMetatileIdAt(11, 10, 536); + DrawWholeMapView(); + PlaySE(SE_TRACK_DOOR); + DestroyTask(taskId); + ScriptContext2_Disable(); + } + break; + } +} + +void ExecuteTruckSequence(void) +{ + MapGridSetMetatileIdAt(11, 8, 525); + MapGridSetMetatileIdAt(11, 9, 533); + MapGridSetMetatileIdAt(11, 10, 541); + DrawWholeMapView(); + ScriptContext2_Enable(); + CpuFastFill(0, gPlttBufferFaded, 0x400); + CreateTask(Task_HandleTruckSequence, 0xA); +} + +void EndTruckSequence(u8 taskId) +{ + if (!FuncIsActiveTask(Task_HandleTruckSequence)) + { + sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3, 3); + sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 0, -3); + sub_808E82C(3, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -3, 0); + } +} + +extern u8 GetSSTidalLocation(s8 *, s8 *, s16 *, s16 *); // should be in field_specials.h +extern void warp1_set(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y); + +bool8 sub_80FB59C(void) +{ + s8 mapGroup, mapNum; + s16 x, y; + + if (GetSSTidalLocation(&mapGroup, &mapNum, &x, &y)) + { + return FALSE; + } + else + { + warp1_set(mapGroup, mapNum, -1, x, y); + return TRUE; + } +} + +extern bool8 sub_80D3340(u8, u8, u8); +extern bool32 CountSSTidalStep(u16); +extern bool8 exec_movement(u8, u8, u8, u8 *); +extern void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused); +extern void sp13E_warp_to_last_warp(void); + +void Task_HandlePorthole(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + u16 *var = GetVarPointer(VAR_PORTHOLE); + struct WarpData *location = &gSaveBlock1Ptr->location; + + switch (data[0]) + { + case INIT_PORTHOLE: // finish fading before making porthole finish. + if (!gPaletteFade.active) + { + data[1] = 0; + data[0] = EXECUTE_MOVEMENT; // execute movement before checking if should be exited. strange? + } + break; + case IDLE_CHECK: // idle and move. + if (gMain.newKeys & A_BUTTON) + data[1] = 1; + if (!sub_80D3340(0xFF, location->mapNum, location->mapGroup)) + return; + if (CountSSTidalStep(1) == TRUE) + { + if (*var == 2) + *var = 9; + else + *var = 10; + data[0] = 3; + return; + } + data[0] = 2; + case EXECUTE_MOVEMENT: // execute movement. + if (data[1]) + { + data[0] = EXIT_PORTHOLE; // exit porthole. + return; + } + // run this once. + if (*var == 2) // which direction? + { + exec_movement(0xFF, location->mapNum, location->mapGroup, gUnknown_0858E8AB); + data[0] = IDLE_CHECK; // run case 1. + } + else + { + exec_movement(0xFF, location->mapNum, location->mapGroup, gUnknown_0858E8AD); + data[0] = IDLE_CHECK; // run case 1. + } + break; + case EXIT_PORTHOLE: // exit porthole. + FlagReset(0x4001); + FlagReset(0x4000); + copy_saved_warp2_bank_and_enter_x_to_warp1(0); + sp13E_warp_to_last_warp(); + DestroyTask(taskId); + break; + } +} + +void sub_80FB6EC(void) +{ + u8 spriteId = AddPseudoFieldObject(0x8C, SpriteCallbackDummy, 112, 80, 0); + + gSprites[spriteId].coordOffsetEnabled = FALSE; + + if (VarGet(0x40B4) == 2) + { + StartSpriteAnim(&gSprites[spriteId], FieldObjectDirectionToImageAnimId(4)); + } + else + { + StartSpriteAnim(&gSprites[spriteId], FieldObjectDirectionToImageAnimId(3)); + } +} + +void sub_80FB768(void) +{ + sub_80FB6EC(); + gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = TRUE; + pal_fill_black(); + CreateTask(Task_HandlePorthole, 80); + ScriptContext2_Enable(); +} + +extern void saved_warp2_set(int unused, s8 mapGroup, s8 mapNum, s8 warpId); +extern void sub_80AF8B8(void); + +void sub_80FB7A4(void) +{ + FlagSet(SYS_CRUISE_MODE); + FlagSet(0x4001); + FlagSet(0x4000); + saved_warp2_set(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1); + sub_80FB59C(); + sub_80AF8B8(); +} -- cgit v1.2.3 From 24751851d27ac288797457cdd44a261b98e47ed4 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Sat, 23 Sep 2017 12:06:23 -0400 Subject: correct field_map_obj.h order declaration. --- src/field_special_scene.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/field_special_scene.c b/src/field_special_scene.c index 22a20161d..2855b3f3a 100755 --- a/src/field_special_scene.c +++ b/src/field_special_scene.c @@ -1,5 +1,6 @@ #include "global.h" #include "task.h" +#include "sprite.h" #include "field_map_obj.h" #include "songs.h" #include "sound.h" @@ -8,7 +9,6 @@ #include "vars.h" #include "event_data.h" #include "main.h" -#include "sprite.h" #define SECONDS(value) ((signed) (60.0 * value + 0.5)) @@ -35,7 +35,7 @@ extern u8 gUnknown_0858E8AD[]; void Task_Truck3(u8); -s32 GetTruckCameraBobbingY(int a1) +s16 GetTruckCameraBobbingY(int a1) { if (!(a1 % 120)) return -1; @@ -45,7 +45,7 @@ s32 GetTruckCameraBobbingY(int a1) return 0; } -s32 GetTruckBoxMovement(int a1) // for the box movement? +s16 GetTruckBoxMovement(int a1) // for the box movement? { if (!((a1 + 120) % 180)) return -1; @@ -74,7 +74,7 @@ void Task_Truck1(u8 taskId) zero = 0; sub_808E82C(3, mapNum, mapGroup, -3, box3); - if (++data[0] == SECONDS(500)) // this will never run + if (SECONDS(500) == ++data[0]) // this will never run data[0] = zero; // reset the timer if it gets stuck. cameraYpan = GetTruckCameraBobbingY(data[0]); -- cgit v1.2.3 From 57543e164e0ed15c23e295ffa08e5804d4d32037 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Sat, 23 Sep 2017 12:42:06 -0400 Subject: revert pointless change --- src/field_special_scene.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/field_special_scene.c b/src/field_special_scene.c index 2855b3f3a..20331f37c 100755 --- a/src/field_special_scene.c +++ b/src/field_special_scene.c @@ -74,7 +74,7 @@ void Task_Truck1(u8 taskId) zero = 0; sub_808E82C(3, mapNum, mapGroup, -3, box3); - if (SECONDS(500) == ++data[0]) // this will never run + if (++data[0] == SECONDS(500)) // this will never run data[0] = zero; // reset the timer if it gets stuck. cameraYpan = GetTruckCameraBobbingY(data[0]); -- cgit v1.2.3 From 601fc9e85b383792819768c31728e4855e854f32 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sat, 23 Sep 2017 20:13:45 +0200 Subject: atk49 is matching baby WOHOHOHOHO --- src/battle_3.c | 5 +- src/battle_4.c | 570 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 564 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index 1b62e3bb8..4453545d3 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -186,7 +186,6 @@ extern void b_call_bc_move_exec(const u8 *); extern void BattleTurnPassed(void); extern void SetMoveEffect(bool8 primary, u8 certainArg); extern bool8 UproarWakeUpCheck(u8 bank); -extern u8 sub_803F90C(u8 bank); extern void sub_803F9EC(); extern bool8 sub_80423F4(u8 bank, u8, u8); extern u8 sub_806D864(u8); @@ -848,7 +847,7 @@ u8 TurnBasedEffects(void) { gBankAttacker = gActiveBank; gBattleMons[gActiveBank].status2 -= 0x10; // uproar timer goes down - if (sub_803F90C(gActiveBank)) + if (HasMoveFailed(gActiveBank)) { CancelMultiTurnMoves(gActiveBank); gBattleCommunication[MULTISTRING_CHOOSER] = 1; @@ -874,7 +873,7 @@ u8 TurnBasedEffects(void) if (gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE) { gBattleMons[gActiveBank].status2 -= 0x400; - if (sub_803F90C(gActiveBank)) + if (HasMoveFailed(gActiveBank)) CancelMultiTurnMoves(gActiveBank); else if (!(gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE) && (gBattleMons[gActiveBank].status2 & STATUS2_MULTIPLETURNS)) diff --git a/src/battle_4.c b/src/battle_4.c index ec84d1a5c..f896cd806 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -57,6 +57,8 @@ extern u8 gBattleMoveFlags; extern u8 gBattleCommunication[]; extern u16 gUnknown_02024250[4]; extern u16 gUnknown_02024258[4]; +extern u16 gUnknown_02024260[4]; +extern u8 gUnknown_02024270[4]; extern u8 gStringBank; extern u16 gDynamicBasePower; extern u16 gLastUsedItem; @@ -78,6 +80,9 @@ extern u8 gCurrentMoveTurn; extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200]; extern u16 gLockedMoves[BATTLE_BANKS_COUNT]; extern u16 gPartnerTrainerId; +extern u16 gLastUsedMove; +extern u16 gUnknownMovesUsedByBanks[BATTLE_BANKS_COUNT]; +extern u16 gLastUsedMovesByBanks[BATTLE_BANKS_COUNT]; extern const struct BattleMove gBattleMoves[]; extern const struct BaseStats gBaseStats[]; @@ -85,6 +90,7 @@ extern const u8 gTypeEffectiveness[]; extern const u16 gMissStringIds[]; extern const u16 gTrappingMoves[]; extern const u8 gTrainerMoney[]; +extern const u8* const gBattleScriptsForMoveEffects[]; // functions extern void sub_81A5718(u8 bank); // battle frontier 2 @@ -132,6 +138,9 @@ extern const u8 BattleScript_FaintAttacker[]; extern const u8 BattleScript_FaintTarget[]; extern const u8 BattleScript_DestinyBondTakesLife[]; extern const u8 BattleScript_GrudgeTakesPp[]; +extern const u8 BattleScript_RageIsBuilding[]; +extern const u8 BattleScript_DefrostedViaFireMove[]; +extern const u8 gUnknown_082DB87D[]; // read via orr #define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) @@ -145,7 +154,7 @@ extern const u8 BattleScript_GrudgeTakesPp[]; #define TARGET_PROTECT_AFFECTED ((gProtectStructs[gBankTarget].protected && gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED)) -#define TARGET_TURN_DAMAGED (((gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_physical.moveturnLostHP_special))) +#define TARGET_TURN_DAMAGED (((gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special))) // this file's functions bool8 IsTwoTurnsMove(u16 move); @@ -227,7 +236,7 @@ void atk45_playanimation(void); void atk46_playanimation2(void); void atk47_setgraphicalstatchangevalues(void); void atk48_playstatchangeanimation(void); -void atk49_moveendturn(void); +void atk49_moveend(void); void atk4A_typecalc2(void); void atk4B_return_atk_to_ball(void); void atk4C_copy_poke_data(void); @@ -479,7 +488,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = atk46_playanimation2, atk47_setgraphicalstatchangevalues, atk48_playstatchangeanimation, - atk49_moveendturn, + atk49_moveend, atk4A_typecalc2, atk4B_return_atk_to_ball, atk4C_copy_poke_data, @@ -2616,13 +2625,12 @@ void SetMoveEffect(bool8 primary, u8 certain) else { // This is a leftover from R/S direct use of ewram addresses - void** memes1 = (void**)(&gBattleStruct); - void* memes2 = (void*)((u32)(gBankAttacker * 2 + offsetof(struct BattleStruct, field_D0))); - u16* memes3 = (u16*)(((void*)(*memes1) + (u32)(memes2))); - gLastUsedItem = *memes3 = gBattleMons[gBankTarget].item; + u16* changedItem; + GET_CHANGED_ITEM_PTR_VIA_MEME_ACCESS(gBankAttacker, changedItem); + gLastUsedItem = *changedItem = gBattleMons[gBankTarget].item; // A sane representation of this would simply be: - // gLastUsedItem = gBattleStruct->field_D0[gBankAttacker] = gBattleMons[gBankTarget].item; + // gLastUsedItem = gBattleStruct->changedItems[gBankAttacker] = gBattleMons[gBankTarget].item; gBattleMons[gBankTarget].item = 0; @@ -4269,6 +4277,7 @@ void atk47_setgraphicalstatchangevalues(void) gBattlescriptCurrInstr++; } +#ifdef NONMATCHING void atk48_playstatchangeanimation(void) { u32 currStat = 0; @@ -4358,3 +4367,548 @@ void atk48_playstatchangeanimation(void) gBattlescriptCurrInstr += 4; } } +#else +__attribute__((naked)) +void atk48_playstatchangeanimation(void) +{ + asm("\n\ + .syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x4\n\ + movs r7, 0\n\ + movs r0, 0\n\ + mov r8, r0\n\ + movs r3, 0\n\ + ldr r5, =gBattlescriptCurrInstr\n\ + ldr r0, [r5]\n\ + ldrb r0, [r0, 0x1]\n\ + str r3, [sp]\n\ + bl GetBattleBank\n\ + ldr r2, =gActiveBank\n\ + strb r0, [r2]\n\ + ldr r0, [r5]\n\ + ldrb r4, [r0, 0x2]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + ldr r3, [sp]\n\ + cmp r0, 0\n\ + beq _0804BAEC\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0x15\n\ + cmp r0, 0\n\ + beq _0804BA18\n\ + movs r1, 0x2D\n\ +_0804BA18:\n\ + cmp r4, 0\n\ + beq _0804BAC0\n\ + movs r0, 0x1\n\ + mov r10, r0\n\ + ldr r0, =gBattleMons + 0x18\n\ + mov r9, r0\n\ + lsls r5, r1, 16\n\ +_0804BA26:\n\ + adds r0, r4, 0\n\ + mov r1, r10\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804BAB2\n\ + ldr r0, =gBattlescriptCurrInstr\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x8\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804BA58\n\ + ldr r0, =gActiveBank\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r7, r0\n\ + b _0804BAA0\n\ + .pool\n\ +_0804BA58:\n\ + ldr r6, =gActiveBank\n\ + ldrb r0, [r6]\n\ + str r3, [sp]\n\ + bl GetBankIdentity\n\ + mov r1, r10\n\ + ands r1, r0\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + ldr r1, =gSideTimers\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x4]\n\ + ldr r3, [sp]\n\ + cmp r0, 0\n\ + bne _0804BAB2\n\ + ldr r0, =gBattleMons\n\ + ldrb r2, [r6]\n\ + movs r1, 0x58\n\ + muls r2, r1\n\ + adds r0, r2, r0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x1D\n\ + beq _0804BAB2\n\ + cmp r0, 0x49\n\ + beq _0804BAB2\n\ + cmp r0, 0x33\n\ + bne _0804BA96\n\ + cmp r7, 0x6\n\ + beq _0804BAB2\n\ +_0804BA96:\n\ + cmp r0, 0x34\n\ + bne _0804BA9E\n\ + cmp r7, 0x1\n\ + beq _0804BAB2\n\ +_0804BA9E:\n\ + adds r0, r7, r2\n\ +_0804BAA0:\n\ + add r0, r9\n\ + ldrb r0, [r0]\n\ + lsls r0, 24\n\ + asrs r0, 24\n\ + cmp r0, 0\n\ + ble _0804BAB2\n\ + lsrs r0, r5, 16\n\ + mov r8, r0\n\ + adds r3, 0x1\n\ +_0804BAB2:\n\ + lsrs r4, 1\n\ + movs r1, 0x80\n\ + lsls r1, 9\n\ + adds r5, r1\n\ + adds r7, 0x1\n\ + cmp r4, 0\n\ + bne _0804BA26\n\ +_0804BAC0:\n\ + ldr r0, =gBattlescriptCurrInstr\n\ + mov r9, r0\n\ + cmp r3, 0x1\n\ + ble _0804BB4E\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0x39\n\ + mov r8, r1\n\ + cmp r0, 0\n\ + beq _0804BB4E\n\ + movs r0, 0x3A\n\ + b _0804BB4C\n\ + .pool\n\ +_0804BAEC:\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0xE\n\ + cmp r0, 0\n\ + beq _0804BAF8\n\ + movs r1, 0x26\n\ +_0804BAF8:\n\ + mov r9, r5\n\ + cmp r4, 0\n\ + beq _0804BB34\n\ + ldr r6, =gBattleMons + 0x18\n\ + adds r5, r2, 0\n\ + lsls r2, r1, 16\n\ +_0804BB04:\n\ + movs r0, 0x1\n\ + ands r0, r4\n\ + cmp r0, 0\n\ + beq _0804BB26\n\ + ldrb r1, [r5]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r7, r0\n\ + adds r0, r6\n\ + ldrb r0, [r0]\n\ + lsls r0, 24\n\ + asrs r0, 24\n\ + cmp r0, 0xB\n\ + bgt _0804BB26\n\ + lsrs r1, r2, 16\n\ + mov r8, r1\n\ + adds r3, 0x1\n\ +_0804BB26:\n\ + lsrs r4, 1\n\ + movs r0, 0x80\n\ + lsls r0, 9\n\ + adds r2, r0\n\ + adds r7, 0x1\n\ + cmp r4, 0\n\ + bne _0804BB04\n\ +_0804BB34:\n\ + cmp r3, 0x1\n\ + ble _0804BB4E\n\ + mov r1, r9\n\ + ldr r0, [r1]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0x37\n\ + mov r8, r1\n\ + cmp r0, 0\n\ + beq _0804BB4E\n\ + movs r0, 0x38\n\ +_0804BB4C:\n\ + mov r8, r0\n\ +_0804BB4E:\n\ + mov r1, r9\n\ + ldr r2, [r1]\n\ + ldrb r1, [r2, 0x3]\n\ + movs r0, 0x4\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804BB6C\n\ + cmp r3, 0x1\n\ + bgt _0804BB6C\n\ + adds r0, r2, 0x4\n\ + mov r1, r9\n\ + b _0804BBBA\n\ + .pool\n\ +_0804BB6C:\n\ + cmp r3, 0\n\ + beq _0804BBB4\n\ + ldr r4, =gBattleScripting\n\ + ldrb r0, [r4, 0x1B]\n\ + cmp r0, 0\n\ + bne _0804BBB4\n\ + movs r0, 0\n\ + movs r1, 0x1\n\ + mov r2, r8\n\ + str r3, [sp]\n\ + bl EmitBattleAnimation\n\ + ldr r0, =gActiveBank\n\ + ldrb r0, [r0]\n\ + bl MarkBufferBankForExecution\n\ + ldr r0, =gBattlescriptCurrInstr\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x4\n\ + ands r0, r1\n\ + ldr r3, [sp]\n\ + cmp r0, 0\n\ + beq _0804BBA4\n\ + cmp r3, 0x1\n\ + ble _0804BBA4\n\ + movs r0, 0x1\n\ + strb r0, [r4, 0x1B]\n\ +_0804BBA4:\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + b _0804BBB6\n\ + .pool\n\ +_0804BBB4:\n\ + mov r1, r9\n\ +_0804BBB6:\n\ + ldr r0, [r1]\n\ + adds r0, 0x4\n\ +_0804BBBA:\n\ + str r0, [r1]\n\ + add sp, 0x4\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided"); +} +#endif // NONMATCHING + +#define ATK49_LAST_CASE 17 + +void atk49_moveend(void) +{ + s32 i; + bool32 effect; + u8 moveType; + u8 holdEffectAtk; + u16 *choicedMoveAtk; + u8 arg1, arg2; + u16 lastMove; + + effect = FALSE; + + if (gLastUsedMove == 0xFFFF) + lastMove = 0; + else + lastMove = gLastUsedMove; + + arg1 = gBattlescriptCurrInstr[1]; + arg2 = gBattlescriptCurrInstr[2]; + + if (gBattleMons[gBankAttacker].item == ITEM_ENIGMA_BERRY) + holdEffectAtk = gEnigmaBerries[gBankAttacker].holdEffect; + else + holdEffectAtk = ItemId_GetHoldEffect(gBattleMons[gBankAttacker].item); + + choicedMoveAtk = &gBattleStruct->choicedMove[gBankAttacker]; + + GET_MOVE_TYPE(gCurrentMove, moveType); + + do + { + switch (gBattleScripting.atk49_state) + { + case 0: // rage check + if (gBattleMons[gBankTarget].status2 & STATUS2_RAGE + && gBattleMons[gBankTarget].hp != 0 && gBankAttacker != gBankTarget + && GetBankSide(gBankAttacker) != GetBankSide(gBankTarget) + && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT) && TARGET_TURN_DAMAGED + && gBattleMoves[gCurrentMove].power && gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] <= 0xB) + { + gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK]++; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_RageIsBuilding; + effect = TRUE; + } + gBattleScripting.atk49_state++; + break; + case 1: // defrosting check + if (gBattleMons[gBankTarget].status1 & STATUS_FREEZE + && gBattleMons[gBankTarget].hp != 0 && gBankAttacker != gBankTarget + && gSpecialStatuses[gBankTarget].moveturnLostHP_special + && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT) && moveType == TYPE_FIRE) + { + gBattleMons[gBankTarget].status1 &= ~(STATUS_FREEZE); + gActiveBank = gBankTarget; + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); + MarkBufferBankForExecution(gActiveBank); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove; + effect = TRUE; + } + gBattleScripting.atk49_state++; + break; + case 2: // target synchronize + if (AbilityBattleEffects(ABILITYEFFECT_SYNCHRONIZE, gBankTarget, 0, 0, 0)) + effect = TRUE; + gBattleScripting.atk49_state++; + break; + case 3: // contact abilities + if (AbilityBattleEffects(ABILITYEFFECT_CONTACT, gBankTarget, 0, 0, 0)) + effect = TRUE; + gBattleScripting.atk49_state++; + break; + case 4: // status immunities + if (AbilityBattleEffects(ABILITYEFFECT_IMMUNITY, 0, 0, 0, 0)) + effect = TRUE; // it loops through all banks, so we increment after its done with all banks + else + gBattleScripting.atk49_state++; + break; + case 5: // attacker synchronize + if (AbilityBattleEffects(ABILITYEFFECT_ATK_SYNCHRONIZE, gBankAttacker, 0, 0, 0)) + effect = TRUE; + gBattleScripting.atk49_state++; + break; + case 6: // update choice band move + if (!(gHitMarker & HITMARKER_OBEYS) || holdEffectAtk != HOLD_EFFECT_CHOICE_BAND + || gLastUsedMove == MOVE_STRUGGLE || (*choicedMoveAtk != 0 && *choicedMoveAtk != 0xFFFF)) + goto LOOP; + if (gLastUsedMove == MOVE_BATON_PASS && !(gBattleMoveFlags & MOVESTATUS_FAILED)) + { + gBattleScripting.atk49_state++; + break; + } + *choicedMoveAtk = gLastUsedMove; + LOOP: + { + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankAttacker].moves[i] == *choicedMoveAtk) + break; + } + if (i == 4) + *choicedMoveAtk = 0; + + gBattleScripting.atk49_state++; + } + break; + case 7: // changed held items + for (i = 0; i < gNoOfAllBanks; i++) + { + u16* changedItem; + GET_CHANGED_ITEM_PTR_VIA_MEME_ACCESS(i, changedItem); + if (*changedItem != 0) + { + gBattleMons[i].item = *changedItem; + *changedItem = 0; + } + } + gBattleScripting.atk49_state++; + break; + case 11: // item effects for all banks + if (ItemBattleEffects(3, 0, FALSE)) + effect = TRUE; + else + gBattleScripting.atk49_state++; + break; + case 12: // king's rock and shell bell + if (ItemBattleEffects(4, 0, FALSE)) + effect = TRUE; + gBattleScripting.atk49_state++; + break; + case 8: // make attacker sprite invisible + if (gStatuses3[gBankAttacker] & (STATUS3_SEMI_INVULNERABLE) + && gHitMarker & HITMARKER_NO_ANIMATIONS) + { + gActiveBank = gBankAttacker; + EmitSpriteInvisibility(0, TRUE); + MarkBufferBankForExecution(gActiveBank); + gBattleScripting.atk49_state++; + return; + } + gBattleScripting.atk49_state++; + break; + case 9: // make attacker sprite visible + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT + || !(gStatuses3[gBankAttacker] & (STATUS3_SEMI_INVULNERABLE)) + || HasMoveFailed(gBankAttacker)) + { + gActiveBank = gBankAttacker; + EmitSpriteInvisibility(0, FALSE); + MarkBufferBankForExecution(gActiveBank); + gStatuses3[gBankAttacker] &= ~(STATUS3_SEMI_INVULNERABLE); + gSpecialStatuses[gBankAttacker].restoredBankSprite = 1; + gBattleScripting.atk49_state++; + return; + } + gBattleScripting.atk49_state++; + break; + case 10: // make target sprite visible + if (!gSpecialStatuses[gBankTarget].restoredBankSprite && gBankTarget < gNoOfAllBanks + && !(gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE)) + { + gActiveBank = gBankTarget; + EmitSpriteInvisibility(0, FALSE); + MarkBufferBankForExecution(gActiveBank); + gStatuses3[gBankTarget] &= ~(STATUS3_SEMI_INVULNERABLE); + gBattleScripting.atk49_state++; + return; + } + gBattleScripting.atk49_state++; + break; + case 13: // update substitute + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gDisableStructs[i].substituteHP == 0) + gBattleMons[i].status2 &= ~(STATUS2_SUBSTITUTE); + } + gBattleScripting.atk49_state++; + break; + case 14: // This case looks interesting, although I am not certain what it does. Probably fine tunes edge cases. + if (gHitMarker & HITMARKER_PURSUIT_TRAP) + { + gActiveBank = gBankAttacker; + gBankAttacker = gBankTarget; + gBankTarget = gActiveBank; + gHitMarker &= ~(HITMARKER_PURSUIT_TRAP); + } + if (gHitMarker & HITMARKER_ATTACKSTRING_PRINTED) + { + gUnknownMovesUsedByBanks[gBankAttacker] = gLastUsedMove; + } + if (!(gAbsentBankFlags & gBitTable[gBankAttacker]) + && !(gBattleStruct->field_91 & gBitTable[gBankAttacker]) + && gBattleMoves[lastMove].effect != EFFECT_BATON_PASS) + { + if (gHitMarker & HITMARKER_OBEYS) + { + gLastUsedMovesByBanks[gBankAttacker] = gLastUsedMove; + gUnknown_02024260[gBankAttacker] = gCurrentMove; + } + else + { + gLastUsedMovesByBanks[gBankAttacker] = 0xFFFF; + gUnknown_02024260[gBankAttacker] = 0xFFFF; + } + + if (!(gHitMarker & HITMARKER_FAINTED(gBankTarget))) + gUnknown_02024270[gBankTarget] = gBankAttacker; + + if (gHitMarker & HITMARKER_OBEYS && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + if (gLastUsedMove == 0xFFFF) + { + gUnknown_02024250[gBankTarget] = gLastUsedMove; + } + else + { + gUnknown_02024250[gBankTarget] = gCurrentMove; + GET_MOVE_TYPE(gCurrentMove, gUnknown_02024258[gBankTarget]); + } + } + else + { + gUnknown_02024250[gBankTarget] = 0xFFFF; + } + } + gBattleScripting.atk49_state++; + break; + case 15: // mirror move + if (!(gAbsentBankFlags & gBitTable[gBankAttacker]) && !(gBattleStruct->field_91 & gBitTable[gBankAttacker]) + && gBattleMoves[lastMove].flags & FLAG_MIRROR_MOVE_AFFECTED && gHitMarker & HITMARKER_OBEYS + && gBankAttacker != gBankTarget && !(gHitMarker & HITMARKER_FAINTED(gBankTarget)) + && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + u8 target, attacker; + + *(gBattleStruct->mirrorMoves + gBankTarget * 2 + 0) = gLastUsedMove; + *(gBattleStruct->mirrorMoves + gBankTarget * 2 + 1) = gLastUsedMove >> 8; + + target = gBankTarget; + attacker = gBankAttacker; + *(attacker * 2 + target * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 0) = gLastUsedMove; + + target = gBankTarget; + attacker = gBankAttacker; + *(attacker * 2 + target * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 1) = gLastUsedMove >> 8; + } + gBattleScripting.atk49_state++; + break; + case 16: // + if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) && gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !gProtectStructs[gBankAttacker].chargingTurn && gBattleMoves[gCurrentMove].target == MOVE_TARGET_BOTH + && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) + { + u8 bank = GetBankByPlayerAI(GetBankIdentity(gBankTarget) ^ 2); + if (gBattleMons[bank].hp != 0) + { + gBankTarget = bank; + gHitMarker |= HITMARKER_NO_ATTACKSTRING; + gBattleScripting.atk49_state = 0; + MoveValuesCleanUp(); + BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); + gBattlescriptCurrInstr = gUnknown_082DB87D; + return; + } + else + { + gHitMarker |= HITMARKER_NO_ATTACKSTRING; + } + } + gBattleScripting.atk49_state++; + break; + case ATK49_LAST_CASE: + break; + } + + if (arg1 == 1 && effect == FALSE) + gBattleScripting.atk49_state = ATK49_LAST_CASE; + if (arg1 == 2 && arg2 == gBattleScripting.atk49_state) + gBattleScripting.atk49_state = ATK49_LAST_CASE; + + } while (gBattleScripting.atk49_state != ATK49_LAST_CASE && effect == FALSE); + + if (gBattleScripting.atk49_state == ATK49_LAST_CASE && effect == FALSE) + gBattlescriptCurrInstr += 3; +} + -- cgit v1.2.3 From 898d0b20ad524e2837079a50f33f6fae0e72b685 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sun, 24 Sep 2017 00:29:52 +0200 Subject: up to x50 --- src/battle_3.c | 2 - src/battle_4.c | 368 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pokemon_3.c | 4 +- 3 files changed, 370 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index 4453545d3..1b443118d 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -188,8 +188,6 @@ extern void SetMoveEffect(bool8 primary, u8 certainArg); extern bool8 UproarWakeUpCheck(u8 bank); extern void sub_803F9EC(); extern bool8 sub_80423F4(u8 bank, u8, u8); -extern u8 sub_806D864(u8); -extern u8 sub_806D82C(u8); extern u8 weather_get_current(void); extern void sub_803E08C(void); extern void bc_move_exec_returning(void); diff --git a/src/battle_4.c b/src/battle_4.c index f896cd806..db6d7fe53 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -17,6 +17,7 @@ #include "songs.h" #include "text.h" #include "sound.h" +#include "pokedex.h" // variables @@ -94,6 +95,7 @@ extern const u8* const gBattleScriptsForMoveEffects[]; // functions extern void sub_81A5718(u8 bank); // battle frontier 2 +extern void sub_81A56B4(void); // battle frontier 2 // BattleScripts extern const u8 BattleScript_MoveEnd[]; @@ -4912,3 +4914,369 @@ void atk49_moveend(void) gBattlescriptCurrInstr += 3; } +void atk4A_typecalc2(void) +{ + u8 flags = 0; + s32 i = 0; + u8 moveType = gBattleMoves[gCurrentMove].type; + + if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) + { + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gBattleMoveFlags |= (MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED); + gUnknown_02024250[gBankTarget] = 0; + gBattleCommunication[6] = moveType; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else + { + while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + { + break; + } + else + { + i += 3; + continue; + } + } + + if (gTypeEffectiveness[i] == moveType) + { + // check type1 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1) + { + if (gTypeEffectiveness[i + 2] == 0) + { + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + break; + } + if (gTypeEffectiveness[i + 2] == 5) + { + flags |= MOVESTATUS_NOTVERYEFFECTIVE; + } + if (gTypeEffectiveness[i + 2] == 20) + { + flags |= MOVESTATUS_SUPEREFFECTIVE; + } + } + // check type2 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2) + { + if (gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == 0) + { + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + break; + } + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == 5) + { + flags |= MOVESTATUS_NOTVERYEFFECTIVE; + } + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == 20) + { + flags |= MOVESTATUS_SUPEREFFECTIVE; + } + } + } + i += 3; + } + } + + if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD + && !(flags & MOVESTATUS_NOEFFECT) + && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2 + && (!(flags & MOVESTATUS_SUPEREFFECTIVE) || ((flags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) + && gBattleMoves[gCurrentMove].power) + { + gLastUsedAbility = ABILITY_WONDER_GUARD; + gBattleMoveFlags |= MOVESTATUS_MISSED; + gUnknown_02024250[gBankTarget] = 0; + gBattleCommunication[6] = 3; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) + gProtectStructs[gBankAttacker].notEffective = 1; + + gBattlescriptCurrInstr++; +} + +void atk4B_return_atk_to_ball(void) +{ + gActiveBank = gBankAttacker; + if (!(gHitMarker & HITMARKER_FAINTED(gActiveBank))) + { + EmitReturnPokeToBall(0, 0); + MarkBufferBankForExecution(gActiveBank); + } + gBattlescriptCurrInstr++; +} + +void atk4C_copy_poke_data(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + gBattlePartyID[gActiveBank] = *(gBattleStruct->field_5C + gActiveBank); + + EmitGetAttributes(0, 0, gBitTable[gBattlePartyID[gActiveBank]]); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +void atk4D_switch_data_update(void) +{ + struct BattlePokemon oldData; + s32 i; + u8 *monData; + + if (gBattleExecBuffer) + return; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + oldData = gBattleMons[gActiveBank]; + monData = (u8*)(&gBattleMons[gActiveBank]); + + for (i = 0; i < sizeof(struct BattlePokemon); i++) + { + monData[i] = gBattleBufferB[gActiveBank][4 + i]; + } + + gBattleMons[gActiveBank].type1 = gBaseStats[gBattleMons[gActiveBank].species].type1; + gBattleMons[gActiveBank].type2 = gBaseStats[gBattleMons[gActiveBank].species].type2; + gBattleMons[gActiveBank].ability = GetAbilityBySpecies(gBattleMons[gActiveBank].species, gBattleMons[gActiveBank].altAbility); + + // check knocked off item + i = GetBankSide(gActiveBank); + if (gWishFutureKnock.knockedOffPokes[i] & gBitTable[gBattlePartyID[gActiveBank]]) + { + gBattleMons[gActiveBank].item = 0; + } + + if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS) + { + for (i = 0; i < 8; i++) + { + gBattleMons[gActiveBank].statStages[i] = oldData.statStages[i]; + } + gBattleMons[gActiveBank].status2 = oldData.status2; + } + + SwitchInClearStructs(); + + if (gBattleTypeFlags & BATTLE_TYPE_PALACE && gBattleMons[gActiveBank].maxHP / 2 >= gBattleMons[gActiveBank].hp + && gBattleMons[gActiveBank].hp != 0 && !(gBattleMons[gActiveBank].status1 & STATUS_SLEEP)) + { + gBattleStruct->field_92 |= gBitTable[gActiveBank]; + } + + gBattleScripting.bank = gActiveBank; + gBattleTextBuff1[0] = PLACEHOLDER_BEGIN; + gBattleTextBuff1[1] = 7; + gBattleTextBuff1[2] = gActiveBank; + gBattleTextBuff1[3] = gBattlePartyID[gActiveBank]; + gBattleTextBuff1[4] = EOS; + + gBattlescriptCurrInstr += 2; +} + +void atk4E_switchin_anim(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + if (GetBankSide(gActiveBank) == SIDE_OPPONENT + && !(gBattleTypeFlags & (BATTLE_TYPE_LINK + | BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_x2000000 + | BATTLE_TYPE_x4000000 + | BATTLE_TYPE_FRONTIER))) + HandleSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBank].species), FLAG_SET_SEEN, gBattleMons[gActiveBank].personality); + + gAbsentBankFlags &= ~(gBitTable[gActiveBank]); + + EmitSwitchInAnim(0, gBattlePartyID[gActiveBank], gBattlescriptCurrInstr[2]); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 3; + + if (gBattleTypeFlags & BATTLE_TYPE_ARENA) + sub_81A56B4(); +} + +void atk4F_jump_if_cannot_switch(void) +{ + s32 val = 0; + s32 compareVar = 0; + struct Pokemon *party = NULL; + s32 r7 = 0; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1] & ~(ATK4F_DONT_CHECK_STATUSES)); + + if (!(gBattlescriptCurrInstr[1] & ATK4F_DONT_CHECK_STATUSES) + && ((gBattleMons[gActiveBank].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) + || (gStatuses3[gActiveBank] & STATUS3_ROOTED))) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + } + else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) + { + #ifndef NONMATCHING + asm("":::"r5"); + #endif // NONMATCHING + if (GetBankSide(gActiveBank) == SIDE_OPPONENT) + party = gEnemyParty; + else + party = gPlayerParty; + + val = 0; + if (2 & gActiveBank) + val = 3; + + for (compareVar = val + 3; val < compareVar; val++) + { + if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[val], MON_DATA_IS_EGG) + && GetMonData(&party[val], MON_DATA_HP) != 0 + && gBattlePartyID[gActiveBank] != val) + break; + } + + if (val == compareVar) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + } + else if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (gBattleTypeFlags & BATTLE_TYPE_x800000) + { + if (GetBankSide(gActiveBank) == SIDE_PLAYER) + { + party = gPlayerParty; + + val = 0; + if (sub_806D82C(sub_806D864(gActiveBank)) == TRUE) + val = 3; + } + else + { + party = gEnemyParty; + + if (gActiveBank == 1) + val = 0; + else + val = 3; + } + } + else + { + if (GetBankSide(gActiveBank) == SIDE_OPPONENT) + party = gEnemyParty; + else + party = gPlayerParty; + + + val = 0; + if (sub_806D82C(sub_806D864(gActiveBank)) == TRUE) + val = 3; + } + + for (compareVar = val + 3; val < compareVar; val++) + { + if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[val], MON_DATA_IS_EGG) + && GetMonData(&party[val], MON_DATA_HP) != 0 + && gBattlePartyID[gActiveBank] != val) + break; + } + + if (val == compareVar) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + } + else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && GetBankSide(gActiveBank) == SIDE_OPPONENT) + { + party = gEnemyParty; + + val = 0; + if (gActiveBank == 3) + val = 3; + + for (compareVar = val + 3; val < compareVar; val++) + { + if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[val], MON_DATA_IS_EGG) + && GetMonData(&party[val], MON_DATA_HP) != 0 + && gBattlePartyID[gActiveBank] != val) + break; + } + + if (val == compareVar) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + } + else + { + if (GetBankSide(gActiveBank) == SIDE_OPPONENT) + { + r7 = GetBankByPlayerAI(1); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + compareVar = GetBankByPlayerAI(3); + else + compareVar = r7; + + party = gEnemyParty; + } + else + { + r7 = GetBankByPlayerAI(0); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + compareVar = GetBankByPlayerAI(2); + else + compareVar = r7; + + party = gPlayerParty; + } + for (val = 0; val < 6; val++) + { + if (GetMonData(&party[val], MON_DATA_HP) != 0 + && GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[val], MON_DATA_IS_EGG) + && val != gBattlePartyID[r7] && val != gBattlePartyID[compareVar]) + break; + } + + if (val == 6) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + } +} + +void sub_804CF10(u8 arg0) +{ + *(gBattleStruct->field_58 + gActiveBank) = gBattlePartyID[gActiveBank]; + *(gBattleStruct->field_5C + gActiveBank) = 6; + gBattleStruct->field_93 &= ~(gBitTable[gActiveBank]); + + EmitChoosePokemon(0, 1, arg0, 0, gBattleStruct->field_60[gActiveBank]); + MarkBufferBankForExecution(gActiveBank); +} diff --git a/src/pokemon_3.c b/src/pokemon_3.c index 603732a34..2bc06c580 100644 --- a/src/pokemon_3.c +++ b/src/pokemon_3.c @@ -601,9 +601,9 @@ bool8 sub_806D7EC(void) return retVal; } -bool8 sub_806D82C(u8 id) +bool16 sub_806D82C(u8 id) { - bool8 retVal = FALSE; + bool16 retVal = FALSE; switch (gLinkPlayers[id].lp_field_18) { case 0: -- cgit v1.2.3 From 52a951276f8d4b79195a0d4889503e4a7f096024 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Mon, 25 Sep 2017 00:09:13 +0200 Subject: battle 4, up to x69 --- src/battle_4.c | 1143 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/pokemon_3.c | 2 +- 2 files changed, 1091 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/battle_4.c b/src/battle_4.c index db6d7fe53..77a4393c4 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -18,6 +18,12 @@ #include "text.h" #include "sound.h" #include "pokedex.h" +#include "recorded_battle.h" +#include "window.h" +#include "reshow_battle_screen.h" +#include "main.h" +#include "palette.h" +#include "money.h" // variables @@ -32,7 +38,7 @@ extern u32 gBattleExecBuffer; extern u8 gNoOfAllBanks; extern u16 gBattlePartyID[BATTLE_BANKS_COUNT]; extern u8 gTurnOrder[BATTLE_BANKS_COUNT]; -extern u8 gUnknown_02024A76[BATTLE_BANKS_COUNT]; +extern u8 gUnknown_0202407A[BATTLE_BANKS_COUNT]; extern u16 gCurrentMove; extern u8 gLastUsedAbility; extern u16 gBattleWeather; @@ -47,7 +53,6 @@ extern u16 gPaydayMoney; extern u16 gRandomTurnNumber; extern u8 gBattleOutcome; extern u8 gBattleTerrain; -extern u16 gTrainerBattleOpponent; extern u8 gBankAttacker; extern u8 gBankTarget; extern const u8* gBattlescriptCurrInstr; @@ -84,18 +89,29 @@ extern u16 gPartnerTrainerId; extern u16 gLastUsedMove; extern u16 gUnknownMovesUsedByBanks[BATTLE_BANKS_COUNT]; extern u16 gLastUsedMovesByBanks[BATTLE_BANKS_COUNT]; +extern u16 gTrainerBattleOpponent_A; +extern u16 gTrainerBattleOpponent_B; + +struct TrainerMoney +{ + u8 classId; + u8 value; +}; extern const struct BattleMove gBattleMoves[]; extern const struct BaseStats gBaseStats[]; extern const u8 gTypeEffectiveness[]; extern const u16 gMissStringIds[]; extern const u16 gTrappingMoves[]; -extern const u8 gTrainerMoney[]; +extern const struct TrainerMoney gTrainerMoneyTable[]; extern const u8* const gBattleScriptsForMoveEffects[]; // functions extern void sub_81A5718(u8 bank); // battle frontier 2 extern void sub_81A56B4(void); // battle frontier 2 +extern void sub_81BFA38(struct Pokemon* party, u8 monPartyId, u8 monCount, void (*callback)(void), u16 move); // pokemon summary screen +extern u8 sub_81C1B94(void); // pokemon summary screen +extern void IncrementGameStat(u8 statId); // rom_4 // BattleScripts extern const u8 BattleScript_MoveEnd[]; @@ -143,6 +159,12 @@ extern const u8 BattleScript_GrudgeTakesPp[]; extern const u8 BattleScript_RageIsBuilding[]; extern const u8 BattleScript_DefrostedViaFireMove[]; extern const u8 gUnknown_082DB87D[]; +extern const u8 gUnknown_082DAE90[]; +extern const u8 gUnknown_082DAE59[]; +extern const u8 gUnknown_082DAEC7[]; + +// strings +extern const u8 gText_BattleYesNoChoice[]; // read via orr #define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) @@ -164,6 +186,7 @@ void DestinyBondFlagUpdate(void); u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. static void CheckWonderGuardAndLevitate(void); u8 ChangeStatBuffs(s8 statValue, u8 statId, u8, const u8* BS_ptr); +void sub_8056A3C(u8 arg0, u8 arg1, u8 arg2, u8 arg3, u8 arg4); void atk00_attackcanceler(void); void atk01_accuracycheck(void); @@ -255,8 +278,8 @@ void atk56_fainting_cry(void); void atk57(void); void atk58_return_to_ball(void); void atk59_learnmove_inbattle(void); -void atk5A(void); -void atk5B_80256E0(void); +void atk5A_yesnoboxlearnmove(void); +void atk5B_yesnoboxstoplearningmove(void); void atk5C_hitanimation(void); void atk5D_getmoneyreward(void); void atk5E_8025A70(void); @@ -268,9 +291,9 @@ void atk63_jumptorandomattack(void); void atk64_statusanimation(void); void atk65_status2animation(void); void atk66_chosenstatusanimation(void); -void atk67_8025ECC(void); +void atk67_yesnobox(void); void atk68_80246A0(void); -void atk69_dmg_adjustment2(void); +void atk69_dmg_adjustment3(void); void atk6A_removeitem(void); void atk6B_atknameinbuff1(void); void atk6C_lvlbox_display(void); @@ -507,8 +530,8 @@ void (* const gBattleScriptingCommandsTable[])(void) = atk57, atk58_return_to_ball, atk59_learnmove_inbattle, - atk5A, - atk5B_80256E0, + atk5A_yesnoboxlearnmove, + atk5B_yesnoboxstoplearningmove, atk5C_hitanimation, atk5D_getmoneyreward, atk5E_8025A70, @@ -520,9 +543,9 @@ void (* const gBattleScriptingCommandsTable[])(void) = atk64_statusanimation, atk65_status2animation, atk66_chosenstatusanimation, - atk67_8025ECC, + atk67_yesnobox, atk68_80246A0, - atk69_dmg_adjustment2, + atk69_dmg_adjustment3, atk6A_removeitem, atk6B_atknameinbuff1, atk6C_lvlbox_display, @@ -758,7 +781,7 @@ const u32 gStatusFlagsForMoveEffects[] = 0x00000000 }; -extern const u8* gMoveEffectBS_Ptrs[]; +extern const u8* const gMoveEffectBS_Ptrs[]; void atk00_attackcanceler(void) { @@ -2890,11 +2913,7 @@ void atk19_faint_pokemon(void) EmitSetAttributes(0, moveIndex + REQUEST_PPMOVE1_BATTLE, 0, 1, &gBattleMons[gActiveBank].pp[moveIndex]); MarkBufferBankForExecution(gActiveBank); - gBattleTextBuff1[0] = PLACEHOLDER_BEGIN; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = gBattleMons[gBankAttacker].moves[moveIndex]; - gBattleTextBuff1[3] = gBattleMons[gBankAttacker].moves[moveIndex] >> 8; - gBattleTextBuff1[4] = EOS; + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBankAttacker].moves[moveIndex]) } } else @@ -3262,30 +3281,12 @@ void atk23_getexp(void) else gBattleStruct->expGetterBank = 0; - // buffer poke name - gBattleTextBuff1[0] = PLACEHOLDER_BEGIN; - gBattleTextBuff1[1] = 4; - gBattleTextBuff1[2] = gBattleStruct->expGetterBank; - gBattleTextBuff1[3] = gBattleStruct->expGetterId; - gBattleTextBuff1[4] = EOS; + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBank, gBattleStruct->expGetterId) // buffer 'gained' or 'gained a boosted' - gBattleTextBuff2[0] = PLACEHOLDER_BEGIN; - gBattleTextBuff2[1] = 0; - gBattleTextBuff2[2] = i; - gBattleTextBuff2[3] = (i & 0xFF00) >> 8; - gBattleTextBuff2[4] = EOS; - - // buffer exp number - gBattleTextBuff3[0] = PLACEHOLDER_BEGIN; - gBattleTextBuff3[1] = 1; - gBattleTextBuff3[2] = 4; // word - gBattleTextBuff3[3] = 5; // max digits - gBattleTextBuff3[4] = gBattleMoveDamage; - gBattleTextBuff3[5] = (gBattleMoveDamage & 0x0000FF00) >> 8; - gBattleTextBuff3[6] = (gBattleMoveDamage & 0x00FF0000) >> 16; - gBattleTextBuff3[7] = (gBattleMoveDamage & 0xFF000000) >> 24; - gBattleTextBuff3[8] = EOS; + PREPARE_STRING_BUFFER(gBattleTextBuff2, i) + + PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 5, gBattleMoveDamage) PrepareStringBattle(0xD, gBattleStruct->expGetterBank); MonGainEVs(&gPlayerParty[gBattleStruct->expGetterId], gBattleMons[gBank1].species); @@ -3324,20 +3325,9 @@ void atk23_getexp(void) if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId) sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); - // buff poke name - gBattleTextBuff1[0] = PLACEHOLDER_BEGIN; - gBattleTextBuff1[1] = 4; - gBattleTextBuff1[2] = gActiveBank; - gBattleTextBuff1[3] = gBattleStruct->expGetterId; - gBattleTextBuff1[4] = EOS; - - // buff level - gBattleTextBuff2[0] = PLACEHOLDER_BEGIN; - gBattleTextBuff2[1] = 1; - gBattleTextBuff2[2] = 1; - gBattleTextBuff2[3] = 3; - gBattleTextBuff2[4] = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); - gBattleTextBuff2[5] = EOS; + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBank, gBattleStruct->expGetterId) + + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 3, GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL)) BattleScriptPushCursor(); gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterId]; @@ -5280,3 +5270,1050 @@ void sub_804CF10(u8 arg0) EmitChoosePokemon(0, 1, arg0, 0, gBattleStruct->field_60[gActiveBank]); MarkBufferBankForExecution(gActiveBank); } + +void atk50_openpartyscreen(void) +{ + u32 flags; + u8 hitmarkerFaintBits; + u8 bank; + const u8 *jumpPtr; + + bank = 0; + flags = 0; + jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + + if (gBattlescriptCurrInstr[1] == 5) + { + if ((gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI)) != BATTLE_TYPE_DOUBLE) + { + for (gActiveBank = 0; gActiveBank < gNoOfAllBanks; gActiveBank++) + { + if (gHitMarker & HITMARKER_FAINTED(gActiveBank)) + { + if (sub_80423F4(gActiveBank, 6, 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(6); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + } + else + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + u8 flag40_0, flag40_1, flag40_2, flag40_3; + + hitmarkerFaintBits = gHitMarker >> 0x1C; + + if (gBitTable[0] & hitmarkerFaintBits) + { + gActiveBank = 0; + if (sub_80423F4(0, 6, 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[2]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + else + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + flags |= 1; + } + } + if (gBitTable[2] & hitmarkerFaintBits && !(gBitTable[0] & hitmarkerFaintBits)) + { + gActiveBank = 2; + if (sub_80423F4(2, 6, 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[0]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + else if (!(flags & 1)) + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + if (gBitTable[1] & hitmarkerFaintBits) + { + gActiveBank = 1; + if (sub_80423F4(1, 6, 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[3]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + else + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + flags |= 2; + } + } + if (gBitTable[3] & hitmarkerFaintBits && !(gBitTable[1] & hitmarkerFaintBits)) + { + gActiveBank = 3; + if (sub_80423F4(3, 6, 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[1]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + else if (!(flags & 2)) + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + + flag40_0 = gSpecialStatuses[0].flag40; + if (!flag40_0) + { + flag40_2 = gSpecialStatuses[2].flag40; + if (!flag40_2 && hitmarkerFaintBits != 0) + { + if (gAbsentBankFlags & gBitTable[0]) + gActiveBank = 2; + else + gActiveBank = 0; + + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + + } + flag40_1 = gSpecialStatuses[1].flag40; + if (!flag40_1) + { + flag40_3 = gSpecialStatuses[3].flag40; + if (!flag40_3 && hitmarkerFaintBits != 0) + { + if (gAbsentBankFlags & gBitTable[1]) + gActiveBank = 3; + else + gActiveBank = 1; + + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + } + gBattlescriptCurrInstr += 6; + } + else if (gBattlescriptCurrInstr[1] == 6) + { + if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + hitmarkerFaintBits = gHitMarker >> 0x1C; + if (gBitTable[2] & hitmarkerFaintBits && gBitTable[0] & hitmarkerFaintBits) + { + gActiveBank = 2; + if (sub_80423F4(2, gBattleBufferB[0][1], 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[0]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + } + if (gBitTable[3] & hitmarkerFaintBits && hitmarkerFaintBits & gBitTable[1]) + { + gActiveBank = 3; + if (sub_80423F4(3, gBattleBufferB[1][1], 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[1]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + } + gBattlescriptCurrInstr += 6; + } + else + { + gBattlescriptCurrInstr += 6; + } + } + else + { + gBattlescriptCurrInstr += 6; + } + + hitmarkerFaintBits = gHitMarker >> 0x1C; + + gBank1 = 0; + while (1) + { + if (gBitTable[gBank1] & hitmarkerFaintBits) + break; + if (gBank1 >= gNoOfAllBanks) + break; + gBank1++; + } + + if (gBank1 == gNoOfAllBanks) + gBattlescriptCurrInstr = jumpPtr; + } + else + { + if (gBattlescriptCurrInstr[1] & 0x80) + hitmarkerFaintBits = 0; // used here as the caseId for the EmitChoose function + else + hitmarkerFaintBits = 1; + + bank = GetBattleBank(gBattlescriptCurrInstr[1] & ~(0x80)); + if (gSpecialStatuses[bank].flag40) + { + gBattlescriptCurrInstr += 6; + } + else if (sub_80423F4(bank, 6, 6)) + { + gActiveBank = bank; + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + gBattlescriptCurrInstr = jumpPtr; + } + else + { + gActiveBank = bank; + *(gBattleStruct->field_58 + gActiveBank) = gBattlePartyID[gActiveBank]; + *(gBattleStruct->field_5C + gActiveBank) = 6; + gBattleStruct->field_93 &= ~(gBitTable[gActiveBank]); + + EmitChoosePokemon(0, hitmarkerFaintBits, *(gBattleStruct->field_5C + (gActiveBank ^ 2)), 0, gBattleStruct->field_60[gActiveBank]); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 6; + + if (GetBankIdentity(gActiveBank) == 0 && gBattleResults.playerSwitchesCounter < 0xFF) + gBattleResults.playerSwitchesCounter++; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + for (gActiveBank = 0; gActiveBank < gNoOfAllBanks; gActiveBank++) + { + if (gActiveBank != bank) + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + } + else + { + gActiveBank = GetBankByPlayerAI(GetBankIdentity(bank) ^ 1); + if (gAbsentBankFlags & gBitTable[gActiveBank]) + gActiveBank ^= 2; + + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + } +} + +void atk51_switch_handle_order(void) +{ + s32 i; + if (gBattleExecBuffer) + return; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + switch (BSScriptRead8(gBattlescriptCurrInstr + 2)) + { + case 0: + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleBufferB[i][0] == 0x22) + { + *(gBattleStruct->field_5C + i) = gBattleBufferB[i][1]; + if (!(gBattleStruct->field_93 & gBitTable[i])) + { + RecordedBattle_SetBankAction(i, gBattleBufferB[i][1]); + gBattleStruct->field_93 |= gBitTable[i]; + } + } + } + break; + case 1: + if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + sub_803BDA0(gActiveBank); + break; + case 2: + if (!(gBattleStruct->field_93 & gBitTable[gActiveBank])) + { + RecordedBattle_SetBankAction(gActiveBank, gBattleBufferB[gActiveBank][1]); + gBattleStruct->field_93 |= gBitTable[gActiveBank]; + } + // fall through + case 3: + gBattleCommunication[0] = gBattleBufferB[gActiveBank][1]; + *(gBattleStruct->field_5C + gActiveBank) = gBattleBufferB[gActiveBank][1]; + + if ((gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_LINK)) == (BATTLE_TYPE_MULTI | BATTLE_TYPE_LINK)) + { + *(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 0) &= 0xF; + *(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBank][2] & 0xF0); + *(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 1) = gBattleBufferB[gActiveBank][3]; + + *((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 0) &= (0xF0); + *((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBank][2] & 0xF0) >> 4; + *((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 2) = gBattleBufferB[gActiveBank][3]; + } + else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) + { + sub_80571DC(gActiveBank, *(gBattleStruct->field_5C + gActiveBank)); + } + else + { + sub_803BDA0(gActiveBank); + } + + PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBankAttacker].species) + PREPARE_MON_NICK_BUFFER(gBattleTextBuff2, gActiveBank, gBattleBufferB[gActiveBank][1]) + + break; + } + + gBattlescriptCurrInstr += 3; +} + +void atk52_switch_in_effects(void) +{ + s32 i; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + sub_803FA70(gActiveBank); + + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + gSpecialStatuses[gActiveBank].flag40 = 0; + + if (!(gSideAffecting[GetBankSide(gActiveBank)] & SIDE_STATUS_SPIKES_DAMAGED) + && (gSideAffecting[GetBankSide(gActiveBank)] & SIDE_STATUS_SPIKES) + && gBattleMons[gActiveBank].type1 != TYPE_FLYING + && gBattleMons[gActiveBank].type2 != TYPE_FLYING + && gBattleMons[gActiveBank].ability != ABILITY_LEVITATE) + { + u8 spikesDmg; + + gSideAffecting[GetBankSide(gActiveBank)] |= SIDE_STATUS_SPIKES_DAMAGED; + + gBattleMons[gActiveBank].status2 &= ~(STATUS2_DESTINY_BOND); + gHitMarker &= ~(HITMARKER_DESTINYBOND); + + spikesDmg = (5 - gSideTimers[GetBankSide(gActiveBank)].spikesAmount) * 2; + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / (spikesDmg); + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattleScripting.bank = gActiveBank; + BattleScriptPushCursor(); + + if (BSScriptRead8(gBattlescriptCurrInstr + 1) == 0) + gBattlescriptCurrInstr = gUnknown_082DAE90; + else if (BSScriptRead8(gBattlescriptCurrInstr + 1) == 1) + gBattlescriptCurrInstr = gUnknown_082DAE59; + else + gBattlescriptCurrInstr = gUnknown_082DAEC7; + } + else + { + if (gBattleMons[gActiveBank].ability == ABILITY_TRUANT && !gDisableStructs[gActiveBank].truantUnknownBit) + gDisableStructs[gActiveBank].truantCounter = 1; + + gDisableStructs[gActiveBank].truantUnknownBit = 0; + + if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBank, 0, 0, 0) == 0 && + ItemBattleEffects(0, gActiveBank, 0) == 0) + { + gSideAffecting[GetBankSide(gActiveBank)] &= ~(SIDE_STATUS_SPIKES_DAMAGED); + + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gTurnOrder[i] == gActiveBank) + gUnknown_0202407A[i] = 0xC; + } + + for (i = 0; i < gNoOfAllBanks; i++) + { + u16* hpOnSwitchout; + GET_HP_SWITCHOUT_PTR_VIA_MEME_ACCESS(GetBankSide(i), hpOnSwitchout) + *hpOnSwitchout = gBattleMons[i].hp; + } + + if (BSScriptRead8(gBattlescriptCurrInstr + 1) == 5) + { + u32 hitmarkerFaintBits = gHitMarker >> 0x1C; + + gBank1++; + while (1) + { + if (hitmarkerFaintBits & gBitTable[gBank1] && !(gAbsentBankFlags & gBitTable[gBank1])) + break; + if (gBank1 >= gNoOfAllBanks) + break; + gBank1++; + } + } + gBattlescriptCurrInstr += 2; + } + } +} + +void atk53_trainer_slide(void) +{ + gActiveBank = GetBankByPlayerAI(gBattlescriptCurrInstr[1]); + EmitTrainerSlide(0); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +void atk54_effectiveness_sound(void) +{ + gActiveBank = gBankAttacker; + EmitEffectivenessSound(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1)); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 3; +} + +void atk55_play_sound(void) +{ + gActiveBank = gBankAttacker; + EmitPlaySound(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1), 0); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 3; +} + +void atk56_fainting_cry(void) +{ + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + EmitFaintingCry(0); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +void atk57(void) +{ + gActiveBank = GetBankByPlayerAI(0); + Emit_x37(0, gBattleOutcome); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 1; +} + +void atk58_return_to_ball(void) +{ + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + EmitReturnPokeToBall(0, 1); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +void atk59_learnmove_inbattle(void) +{ + const u8* jumpPtr1 = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + const u8* jumpPtr2 = BSScriptReadPtr(gBattlescriptCurrInstr + 5); + + u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], BSScriptRead8(gBattlescriptCurrInstr + 9)); + while (ret == 0xFFFE) + ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], 0); + + if (ret == 0) + { + gBattlescriptCurrInstr = jumpPtr2; + } + else if (ret == 0xFFFF) + { + gBattlescriptCurrInstr += 10; + } + else + { + gActiveBank = GetBankByPlayerAI(0); + + if (gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId + && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) + { + GiveMoveToBattleMon(&gBattleMons[gActiveBank], ret); + } + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + gActiveBank = GetBankByPlayerAI(2); + if (gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId + && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) + { + GiveMoveToBattleMon(&gBattleMons[gActiveBank], ret); + } + } + + gBattlescriptCurrInstr = jumpPtr1; + } +} + +void atk5A_yesnoboxlearnmove(void) +{ + gActiveBank = 0; + + switch (gBattleScripting.learnMoveState) + { + case 0: + sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); + sub_814F9EC(gText_BattleYesNoChoice, 0xC); + gBattleScripting.learnMoveState++; + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 1; + BattleCreateCursorAt(1); + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (gBattleCommunication[1] == 0) + { + sub_8056A3C(0x18, 0x8, 0x1D, 0xD, 1); + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + gBattleScripting.learnMoveState++; + } + else + { + gBattleScripting.learnMoveState = 5; + } + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gBattleScripting.learnMoveState = 5; + } + break; + case 2: + if (!gPaletteFade.active) + { + FreeAllWindowBuffers(); + sub_81BFA38(gPlayerParty, gBattleStruct->expGetterId, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, gMoveToLearn); + gBattleScripting.learnMoveState++; + } + break; + case 3: + if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2) + { + gBattleScripting.learnMoveState++; + } + break; + case 4: + if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2) + { + u8 movePosition = sub_81C1B94(); + if (movePosition == 4) + { + gBattleScripting.learnMoveState = 5; + } + else + { + u16 moveId = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MOVE1 + movePosition); + if (IsHMMove2(moveId)) + { + PrepareStringBattle(0x13F, gActiveBank); + gBattleScripting.learnMoveState = 6; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + PREPARE_MOVE_BUFFER(gBattleTextBuff2, moveId) + + RemoveMonPPBonus(&gPlayerParty[gBattleStruct->expGetterId], movePosition); + SetMonMoveSlot(&gPlayerParty[gBattleStruct->expGetterId], gMoveToLearn, movePosition); + + if (gBattlePartyID[0] == gBattleStruct->expGetterId + && !(gBattleMons[0].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[0].unk18_b & gBitTable[movePosition])) + { + RemoveBattleMonPPBonus(&gBattleMons[0], movePosition); + SetBattleMonMoveSlot(&gBattleMons[0], gMoveToLearn, movePosition); + } + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && gBattlePartyID[2] == gBattleStruct->expGetterId + && !(gBattleMons[2].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[2].unk18_b & gBitTable[movePosition])) + { + RemoveBattleMonPPBonus(&gBattleMons[2], movePosition); + SetBattleMonMoveSlot(&gBattleMons[2], gMoveToLearn, movePosition); + } + } + } + } + break; + case 5: + sub_8056A3C(0x18, 8, 0x1D, 0xD, 1); + gBattlescriptCurrInstr += 5; + break; + case 6: + if (gBattleExecBuffer == 0) + { + gBattleScripting.learnMoveState = 2; + } + break; + } +} + +void atk5B_yesnoboxstoplearningmove(void) +{ + switch (gBattleScripting.learnMoveState) + { + case 0: + sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); + sub_814F9EC(gText_BattleYesNoChoice, 0xC); + gBattleScripting.learnMoveState++; + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 1; + BattleCreateCursorAt(1); + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + + if (gBattleCommunication[1] != 0) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; + + sub_8056A3C(0x18, 0x8, 0x1D, 0xD, 1); + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + sub_8056A3C(0x18, 0x8, 0x1D, 0xD, 1); + } + break; + } +} + +void atk5C_hitanimation(void) +{ + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) + { + gBattlescriptCurrInstr += 2; + } + else if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE) || !(gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE) || gDisableStructs[gActiveBank].substituteHP == 0) + { + EmitHitAnimation(0); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 2; + } + else + { + gBattlescriptCurrInstr += 2; + } +} + +static u32 GetTrainerMoneyToGive(u16 trainerId) +{ + u32 i = 0; + u32 lastMonLevel = 0; + u32 moneyReward = 0; + + if (trainerId == SECRET_BASE_OPPONENT) + { + moneyReward = 20 * gBattleResources->secretBase->partyLevels[0] * gBattleStruct->moneyMultiplier; + } + else + { + switch (gTrainers[trainerId].partyFlags) + { + case 0: + { + const struct TrainerMonNoItemDefaultMoves *party = gTrainers[trainerId].party.NoItemDefaultMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + case PARTY_FLAG_CUSTOM_MOVES: + { + const struct TrainerMonNoItemCustomMoves *party = gTrainers[trainerId].party.NoItemCustomMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + case PARTY_FLAG_HAS_ITEM: + { + const struct TrainerMonItemDefaultMoves *party = gTrainers[trainerId].party.ItemDefaultMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + case PARTY_FLAG_CUSTOM_MOVES | PARTY_FLAG_HAS_ITEM: + { + const struct TrainerMonItemCustomMoves *party = gTrainers[trainerId].party.ItemCustomMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + } + + for (; gTrainerMoneyTable[i].classId != 0xFF; i++) + { + if (gTrainerMoneyTable[i].classId == gTrainers[trainerId].trainerClass) + break; + } + + if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * gTrainerMoneyTable[i].value; + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * 2 * gTrainerMoneyTable[i].value; + else + moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * gTrainerMoneyTable[i].value; + } + + return moneyReward; +} + +void atk5D_getmoneyreward(void) +{ + u32 moneyReward = GetTrainerMoneyToGive(gTrainerBattleOpponent_A); + if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + moneyReward += GetTrainerMoneyToGive(gTrainerBattleOpponent_B); + + AddMoney(&gSaveBlock1Ptr->money, moneyReward); + + PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff1, 5, moneyReward) + + gBattlescriptCurrInstr++; +} + +void atk5E_8025A70(void) +{ + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + switch (gBattleCommunication[0]) + { + case 0: + EmitGetAttributes(0, REQUEST_ALL_BATTLE, 0); + MarkBufferBankForExecution(gActiveBank); + gBattleCommunication[0]++; + break; + case 1: + if (gBattleExecBuffer == 0) + { + s32 i; + struct BattlePokemon* bufferPoke = (struct BattlePokemon*) &gBattleBufferB[gActiveBank][4]; + for (i = 0; i < 4; i++) + { + gBattleMons[gActiveBank].moves[i] = bufferPoke->moves[i]; + gBattleMons[gActiveBank].pp[i] = bufferPoke->pp[i]; + } + gBattlescriptCurrInstr += 2; + } + break; + } +} + +void atk5F_8025B24(void) +{ + gActiveBank = gBankAttacker; + gBankAttacker = gBankTarget; + gBankTarget = gActiveBank; + + if (gHitMarker & HITMARKER_PURSUIT_TRAP) + gHitMarker &= ~(HITMARKER_PURSUIT_TRAP); + else + gHitMarker |= HITMARKER_PURSUIT_TRAP; + + gBattlescriptCurrInstr++; +} + +void atk60_increment_gamestat(void) +{ + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + IncrementGameStat(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + gBattlescriptCurrInstr += 2; +} + +void atk61_8025BA4(void) +{ + s32 i; + struct Pokemon* party; + struct HpAndStatus hpStatuses[6]; + + if (gBattleExecBuffer) + return; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + if (GetBankSide(gActiveBank) == SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + for (i = 0; i < 6; i++) + { + if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_NONE + || GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG) + { + hpStatuses[i].hp = 0xFFFF; + hpStatuses[i].status = 0; + } + else + { + hpStatuses[i].hp = GetMonData(&party[i], MON_DATA_HP); + hpStatuses[i].status = GetMonData(&party[i], MON_DATA_STATUS); + } + } + + EmitCmd48(0, hpStatuses, 1); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +void atk62_08025C6C(void) +{ + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + EmitCmd49(0); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +void atk63_jumptorandomattack(void) +{ + if (BSScriptRead8(gBattlescriptCurrInstr + 1) != 0) + gCurrentMove = gRandomMove; + else + gLastUsedMove = gCurrentMove = gRandomMove; + + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; +} + +void atk64_statusanimation(void) +{ + if (gBattleExecBuffer == 0) + { + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) + && gDisableStructs[gActiveBank].substituteHP == 0 + && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) + { + EmitStatusAnimation(0, FALSE, gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + } + gBattlescriptCurrInstr += 2; + } +} + +void atk65_status2animation(void) +{ + u32 wantedToAnimate; + + if (gBattleExecBuffer == 0) + { + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + wantedToAnimate = BSScriptRead32(gBattlescriptCurrInstr + 2); + if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) + && gDisableStructs[gActiveBank].substituteHP == 0 + && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) + { + EmitStatusAnimation(0, TRUE, gBattleMons[gActiveBank].status2 & wantedToAnimate); + MarkBufferBankForExecution(gActiveBank); + } + gBattlescriptCurrInstr += 6; + } +} + +void atk66_chosenstatusanimation(void) +{ + u32 wantedStatus; + + if (gBattleExecBuffer == 0) + { + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + wantedStatus = BSScriptRead32(gBattlescriptCurrInstr + 3); + if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) + && gDisableStructs[gActiveBank].substituteHP == 0 + && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) + { + EmitStatusAnimation(0, BSScriptRead8(gBattlescriptCurrInstr + 2), wantedStatus); + MarkBufferBankForExecution(gActiveBank); + } + gBattlescriptCurrInstr += 7; + } +} + +void atk67_yesnobox(void) +{ + switch (gBattleCommunication[0]) + { + case 0: + sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); + sub_814F9EC(gText_BattleYesNoChoice, 0xC); + gBattleCommunication[0]++; + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 1; + BattleCreateCursorAt(1); + } + if (gMain.newKeys & B_BUTTON) + { + gBattleCommunication[CURSOR_POSITION] = 1; + PlaySE(SE_SELECT); + sub_8056A3C(0x18, 8, 0x1D, 0xD, 1); + gBattlescriptCurrInstr++; + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + sub_8056A3C(0x18, 8, 0x1D, 0xD, 1); + gBattlescriptCurrInstr++; + } + break; + } +} + +void atk68_80246A0(void) +{ + s32 i; + + for (i = 0; i < gNoOfAllBanks; i++) + gUnknown_0202407A[i] = 0xC; + + gBattlescriptCurrInstr++; +} + +void atk69_dmg_adjustment3(void) // The same as 0x7, except there's no random damage multiplier. +{ + u8 holdEffect, quality; + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + { + RecordItemEffectBattle(gBankTarget, holdEffect); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + goto END; + if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE && !gProtectStructs[gBankTarget].endured + && !gSpecialStatuses[gBankTarget].focusBanded) + goto END; + + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + goto END; + + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + + if (gProtectStructs[gBankTarget].endured) + { + gBattleMoveFlags |= MOVESTATUS_ENDURED; + } + else if (gSpecialStatuses[gBankTarget].focusBanded) + { + gBattleMoveFlags |= MOVESTATUS_HUNGON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + + END: + gBattlescriptCurrInstr++; +} diff --git a/src/pokemon_3.c b/src/pokemon_3.c index 2bc06c580..aaa02c5d4 100644 --- a/src/pokemon_3.c +++ b/src/pokemon_3.c @@ -1374,7 +1374,7 @@ void sub_806E994(void) gBattleTextBuff2[2] = gBankInMenu; gBattleTextBuff2[3] = pokemon_order_func(gBattlePartyID[gBankInMenu]); gBattleTextBuff2[4] = EOS; - StrCpyDecodeBattle(gText_PkmnsXPreventsSwitching, gStringVar4); + BattleStringExpandPlaceholders(gText_PkmnsXPreventsSwitching, gStringVar4); } struct PokeItem -- cgit v1.2.3 From 55bae5e8adb9418552c7bd8b75523c2c8a67052b Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 25 Sep 2017 14:47:44 -0400 Subject: data/script_menu.s --- src/berry.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/berry.c b/src/berry.c index e9d6994f8..cf49d4dc4 100644 --- a/src/berry.c +++ b/src/berry.c @@ -17,7 +17,6 @@ extern bool8 sub_8092E9C(u8, u8, u8); extern u16 gScriptItemId; extern const u8 BerryTreeScript[]; -extern const struct BerryTree gBlankBerryTree; #define BERRY_NAME_LENGTH 6 @@ -804,6 +803,57 @@ const struct Berry gBerries[] = }, }; +const struct { + u8 unk0; + u16 unk1; +} gUnknown_0858AB24[] = { + { 50, 20}, + { 50, 20}, + { 50, 20}, + { 50, 20}, + { 50, 20}, + { 50, 30}, + { 50, 30}, + { 50, 30}, + { 50, 30}, + { 50, 30}, + { 60, 50}, + { 60, 50}, + { 60, 50}, + { 60, 50}, + { 60, 50}, + { 80, 70}, + { 80, 70}, + { 80, 70}, + { 80, 70}, + { 80, 70}, + {100, 100}, + {100, 100}, + {100, 100}, + {100, 100}, + {100, 100}, + {130, 150}, + {130, 150}, + {130, 150}, + {130, 150}, + {130, 150}, + {160, 250}, + {160, 250}, + {160, 250}, + {160, 250}, + {160, 250}, + {180, 500}, + {180, 500}, + {180, 500}, + {180, 500}, + {180, 500}, + {200, 750}, + {200, 750}, + {150, 200} +}; + +const struct BerryTree gBlankBerryTree = {}; + // unused void ClearEnigmaBerries(void) { -- cgit v1.2.3 From bf9e2b7210361695a3ffdb8305c054c41ad18609 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 25 Sep 2017 15:03:52 -0400 Subject: split data3_a1 --- src/berry.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/berry.c b/src/berry.c index cf49d4dc4..98cf7d932 100644 --- a/src/berry.c +++ b/src/berry.c @@ -803,10 +803,7 @@ const struct Berry gBerries[] = }, }; -const struct { - u8 unk0; - u16 unk1; -} gUnknown_0858AB24[] = { +const struct UnkStruct_0858AB24 gUnknown_0858AB24[] = { { 50, 20}, { 50, 20}, { 50, 20}, -- cgit v1.2.3 From a8a4a500abf23b8ab3ea206614b94e0f16d9af7d Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 25 Sep 2017 15:27:54 -0400 Subject: split data3_a0_A --- src/new_game.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/new_game.c b/src/new_game.c index 2bf774c69..5a482c593 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -18,6 +18,7 @@ #include "event_data.h" #include "money.h" #include "coins.h" +#include "text.h" extern u8 gPlayerPartyCount; extern u8 gDifferentSaveFile; @@ -104,7 +105,10 @@ void ClearPokedexFlags(void) memset(&gSaveBlock2Ptr->pokedex.seen, 0, sizeof(gSaveBlock2Ptr->pokedex.seen)); } -extern const struct ContestWinner gContestWinnerPicDummy; +const struct ContestWinner gContestWinnerPicDummy = { + .monName = _(""), + .trainerName = _("") +}; void ClearAllContestWinnerPics(void) { -- cgit v1.2.3 From d1efbcd282aa68634b275af25ca1bf187e85cb9e Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Mon, 25 Sep 2017 16:26:45 -0500 Subject: Extract scattered baseroms and cleanup --- src/berry_fix_program.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c index f04308ae8..eca20af9d 100644 --- a/src/berry_fix_program.c +++ b/src/berry_fix_program.c @@ -129,8 +129,7 @@ static const u8 *const gUnknown_08618178[][3] = { }, }; -extern const u8 gUnknown_089A6550[0xC0]; -extern const u8 gMultiBootProgram_BerryGlitchFix_Start[0x3b34]; +extern const u8 gMultiBootProgram_BerryGlitchFix_Start[0x3BF4]; extern const u8 gMultiBootProgram_BerryGlitchFix_End[]; // .text @@ -174,7 +173,7 @@ static void berry_fix_main(void) case 3: if (berry_fix_text_update(1) == 1) { - berry_fix_mb_manager->mb.masterp = gUnknown_089A6550; + berry_fix_mb_manager->mb.masterp = gMultiBootProgram_BerryGlitchFix_Start; berry_fix_mb_manager->mb.server_type = 0; MultiBootInit(&berry_fix_mb_manager->mb); berry_fix_mb_manager->unk2 = 0; @@ -189,7 +188,7 @@ static void berry_fix_main(void) } else if (++ berry_fix_mb_manager->unk2 > 180) { - MultiBootStartMaster(&berry_fix_mb_manager->mb, gMultiBootProgram_BerryGlitchFix_Start, (u32)(gMultiBootProgram_BerryGlitchFix_End - gMultiBootProgram_BerryGlitchFix_Start), 4, 1); + MultiBootStartMaster(&berry_fix_mb_manager->mb, gMultiBootProgram_BerryGlitchFix_Start + ROM_HEADER_SIZE, (u32)(gMultiBootProgram_BerryGlitchFix_End - (gMultiBootProgram_BerryGlitchFix_Start + ROM_HEADER_SIZE)), 4, 1); berry_fix_mb_manager->state = 5; } break; -- cgit v1.2.3 From d769ec137447c52062b48153851bd2824055b6df Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Tue, 26 Sep 2017 22:39:59 +0200 Subject: battle 4 up to a8 --- src/battle_3.c | 52 +- src/battle_4.c | 2739 ++++++++++++++++++++++++++++++++++++++++++- src/battle_ai.c | 2 +- src/calculate_base_damage.c | 1 - src/pokemon_2.c | 10 +- src/pokemon_3.c | 6 +- src/window.c | 2 +- 7 files changed, 2734 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index 1b443118d..1fd84a61b 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -831,7 +831,7 @@ u8 TurnBasedEffects(void) gBattleCommunication[MULTISTRING_CHOOSER] = 1; b_call_bc_move_exec(gUnknown_082DB234); gActiveBank = gBankAttacker; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); break; } @@ -956,7 +956,7 @@ u8 TurnBasedEffects(void) { CancelMultiTurnMoves(gActiveBank); gBattleMons[gActiveBank].status1 |= (Random() & 3) + 2; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); gEffectBank = gActiveBank; b_call_bc_move_exec(BattleScript_YawnMakesAsleep); @@ -1446,7 +1446,7 @@ u8 AtkCanceller_UnableToUseMove(void) if (effect == 2) { gActiveBank = gBankAttacker; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); } return effect; @@ -1539,14 +1539,14 @@ bool8 sub_80423F4(u8 bank, u8 r1, u8 r2) { if (GetBankSide(bank) == SIDE_OPPONENT) { - r7 = GetBankByPlayerAI(1); - r6 = GetBankByPlayerAI(3); + r7 = GetBankByIdentity(1); + r6 = GetBankByIdentity(3); party = gEnemyParty; } else { - r7 = GetBankByPlayerAI(0); - r6 = GetBankByPlayerAI(2); + r7 = GetBankByIdentity(0); + r6 = GetBankByIdentity(2); party = gPlayerParty; } if (r1 == 6) @@ -1835,7 +1835,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); // fix nighmare glitch gBattleScripting.bank = gActiveBank = bank; b_push_move_exec(BattleScript_ShedSkinActivates); - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); MarkBufferBankForExecution(gActiveBank); effect++; } @@ -2156,7 +2156,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattlescriptCurrInstr = gUnknown_082DB68C; gBattleScripting.bank = i; gActiveBank = i; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); return effect; } @@ -2235,14 +2235,14 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) if (gBattleMons[i].ability == ABILITY_TRACE && (gStatuses3[i] & STATUS3_TRACE)) { u8 opposite = (GetBankIdentity(i) ^ 1) & 1; - u8 target1 = GetBankByPlayerAI(opposite); - u8 target2 = GetBankByPlayerAI(opposite + 2); + u8 target1 = GetBankByIdentity(opposite); + u8 target2 = GetBankByIdentity(opposite + 2); if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) { if (gBattleMons[target1].ability != 0 && gBattleMons[target1].hp != 0 && gBattleMons[target2].ability != 0 && gBattleMons[target2].hp != 0) { - gActiveBank = GetBankByPlayerAI(((Random() & 1) * 2) | opposite); + gActiveBank = GetBankByIdentity(((Random() & 1) * 2) | opposite); gBattleMons[i].ability = gBattleMons[gActiveBank].ability; gLastUsedAbility = gBattleMons[gActiveBank].ability; effect++; @@ -3106,7 +3106,7 @@ _08042E24:\n\ movs r1, 0x28\n\ movs r2, 0\n\ movs r3, 0x4\n\ - bl EmitSetAttributes\n\ + bl EmitSetMonData\n\ ldrb r0, [r4]\n\ bl MarkBufferBankForExecution\n\ bl _080443D0\n\ @@ -4500,7 +4500,7 @@ _08043BFC:\n\ movs r1, 0x28\n\ movs r2, 0\n\ movs r3, 0x4\n\ - bl EmitSetAttributes\n\ + bl EmitSetMonData\n\ ldrb r0, [r4]\n\ bl MarkBufferBankForExecution\n\ bl _0804443A\n\ @@ -4744,11 +4744,11 @@ _08043E42:\n\ eors r5, r1\n\ ands r5, r1\n\ adds r0, r5, 0\n\ - bl GetBankByPlayerAI\n\ + bl GetBankByIdentity\n\ lsls r0, 24\n\ lsrs r6, r0, 24\n\ adds r0, r5, 0x2\n\ - bl GetBankByPlayerAI\n\ + bl GetBankByIdentity\n\ lsls r0, 24\n\ lsrs r7, r0, 24\n\ ldr r0, =gBattleTypeFlags\n\ @@ -4792,7 +4792,7 @@ _08043E74:\n\ lsls r1, 1\n\ orrs r5, r1\n\ adds r0, r5, 0\n\ - bl GetBankByPlayerAI\n\ + bl GetBankByIdentity\n\ mov r2, r8\n\ strb r0, [r2]\n\ ldrb r0, [r2]\n\ @@ -5609,7 +5609,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleTextBuff1[3] = move >> 8; gBattleTextBuff1[4] = 0xFF; b_call_bc_move_exec(BattleScript_BerryPPHealEnd2); - EmitSetAttributes(0, i + REQUEST_PPMOVE1_BATTLE, 0, 1, &changedPP); + EmitSetMonData(0, i + REQUEST_PPMOVE1_BATTLE, 0, 1, &changedPP); MarkBufferBankForExecution(gActiveBank); effect = ITEM_PP_CHANGE; } @@ -5993,7 +5993,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) switch (effect) { case ITEM_STATUS_CHANGE: - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); MarkBufferBankForExecution(gActiveBank); break; case ITEM_PP_CHANGE: @@ -6148,7 +6148,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleScripting.bank = bank; gStringBank = bank; gActiveBank = bank; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); break; } @@ -6251,7 +6251,7 @@ u8 GetMoveTarget(u16 move, u8 useMoveTarget) case MOVE_TARGET_BOTH: case MOVE_TARGET_FOES_AND_ALLY: case MOVE_TARGET_OPPONENTS_FIELD: - targetBank = GetBankByPlayerAI((GetBankIdentity(gBankAttacker) & 1) ^ 1); + targetBank = GetBankByIdentity((GetBankIdentity(gBankAttacker) & 1) ^ 1); if (gAbsentBankFlags & gBitTable[targetBank]) targetBank ^= 2; break; @@ -6264,22 +6264,22 @@ u8 GetMoveTarget(u16 move, u8 useMoveTarget) if (GetBankSide(gBankAttacker) == SIDE_PLAYER) { if (Random() & 1) - targetBank = GetBankByPlayerAI(1); + targetBank = GetBankByIdentity(1); else - targetBank = GetBankByPlayerAI(3); + targetBank = GetBankByIdentity(3); } else { if (Random() & 1) - targetBank = GetBankByPlayerAI(0); + targetBank = GetBankByIdentity(0); else - targetBank = GetBankByPlayerAI(2); + targetBank = GetBankByIdentity(2); } if (gAbsentBankFlags & gBitTable[targetBank]) targetBank ^= 2; } else - targetBank = GetBankByPlayerAI((GetBankIdentity(gBankAttacker) & 1) ^ 1); + targetBank = GetBankByIdentity((GetBankIdentity(gBankAttacker) & 1) ^ 1); break; case MOVE_TARGET_USER: case MOVE_TARGET_x10: diff --git a/src/battle_4.c b/src/battle_4.c index 77a4393c4..0f52ee0dd 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -24,6 +24,11 @@ #include "main.h" #include "palette.h" #include "money.h" +#include "bg.h" +#include "string_util.h" +#include "pokemon_icon.h" +#include "pokemon_item_effects.h" +#include "m4a.h" // variables @@ -91,6 +96,7 @@ extern u16 gUnknownMovesUsedByBanks[BATTLE_BANKS_COUNT]; extern u16 gLastUsedMovesByBanks[BATTLE_BANKS_COUNT]; extern u16 gTrainerBattleOpponent_A; extern u16 gTrainerBattleOpponent_B; +extern struct MusicPlayerInfo gMPlay_BGM; struct TrainerMoney { @@ -112,6 +118,15 @@ extern void sub_81A56B4(void); // battle frontier 2 extern void sub_81BFA38(struct Pokemon* party, u8 monPartyId, u8 monCount, void (*callback)(void), u16 move); // pokemon summary screen extern u8 sub_81C1B94(void); // pokemon summary screen extern void IncrementGameStat(u8 statId); // rom_4 +extern void sub_81D388C(struct Pokemon* mon, void* statStoreLocation); // pokenav.s +extern void sub_81D3640(u8 arg0, void* statStoreLocation1, void* statStoreLocation2, u8 arg3, u8 arg4, u8 arg5); // pokenav.s +extern void sub_81D3784(u8 arg0, void* statStoreLocation1, u8 arg2, u8 arg3, u8 arg4); // pokenav.s +extern u8* GetMonNickname(struct Pokemon* mon, u8* dst); // party_menu +extern u8 sub_81A5258(u8* arg0); // battle frontier 2 +extern void sub_81A5BF8(void); // battle frontier 2 +extern void sub_81A5D44(void); // battle frontier 2 +extern void sub_81B8E80(u8 bank, u8, u8); // party menu +extern bool8 sub_81B1250(void); // ? // BattleScripts extern const u8 BattleScript_MoveEnd[]; @@ -162,6 +177,26 @@ extern const u8 gUnknown_082DB87D[]; extern const u8 gUnknown_082DAE90[]; extern const u8 gUnknown_082DAE59[]; extern const u8 gUnknown_082DAEC7[]; +extern const u8 BattleScript_MoveEffectSleep[]; +extern const u8 BattleScript_MoveEffectPoison[]; +extern const u8 BattleScript_MoveEffectBurn[]; +extern const u8 BattleScript_MoveEffectFreeze[]; +extern const u8 BattleScript_MoveEffectParalysis[]; +extern const u8 BattleScript_MoveEffectToxic[]; +extern const u8 BattleScript_MoveEffectConfusion[]; +extern const u8 BattleScript_MoveEffectUproar[]; +extern const u8 BattleScript_MoveEffectPayDay[]; +extern const u8 BattleScript_MoveEffectWrap[]; +extern const u8 BattleScript_MoveEffectRecoil33[]; +extern const u8 BattleScript_DampStopsExplosion[]; +extern const u8 BattleScript_MistProtected[]; +extern const u8 BattleScript_AbilityNoStatLoss[]; +extern const u8 BattleScript_AbilityNoSpecificStatLoss[]; +extern const u8 BattleScript_ButItFailed[]; +extern const u8 gUnknown_082DADD8[]; +extern const u8 BattleScript_PrintPayDayMoneyString[]; +extern const u8 BattleScript_SturdyPreventsOHKO[]; +extern const u8 BattleScript_ObliviousPreventsAttraction[]; // strings extern const u8 gText_BattleYesNoChoice[]; @@ -187,6 +222,14 @@ u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging tur static void CheckWonderGuardAndLevitate(void); u8 ChangeStatBuffs(s8 statValue, u8 statId, u8, const u8* BS_ptr); void sub_8056A3C(u8 arg0, u8 arg1, u8 arg2, u8 arg3, u8 arg4); +bool32 IsMonGettingExpSentOut(void); +void sub_804F17C(void); +bool8 sub_804F1CC(void); +void sub_804F100(void); +void sub_804F144(void); +bool8 sub_804F344(void); +void PutMonIconOnLvlUpBox(void); +void PutLevelAndGenderOnLvlUpBox(void); void atk00_attackcanceler(void); void atk01_accuracycheck(void); @@ -296,23 +339,23 @@ void atk68_80246A0(void); void atk69_dmg_adjustment3(void); void atk6A_removeitem(void); void atk6B_atknameinbuff1(void); -void atk6C_lvlbox_display(void); -void atk6D_set_sentpokes_values(void); +void atk6C_draw_lvlupbox(void); +void atk6D_reset_sentpokes_value(void); void atk6E_set_atk_to_player0(void); void atk6F_set_visible(void); -void atk70_record_ability(void); +void atk70_record_last_used_ability(void); void atk71_buffer_move_to_learn(void); void atk72_jump_if_can_run_frombattle(void); void atk73_hp_thresholds(void); void atk74_hp_thresholds2(void); -void atk75_8026A58(void); +void atk75_item_effect_on_opponent(void); void atk76_various(void); -void atk77_setprotect(void); +void atk77_set_protect_like(void); void atk78_faintifabilitynotdamp(void); void atk79_setatkhptozero(void); void atk7A_jumpwhiletargetvalid(void); void atk7B_healhalfHP_if_possible(void); -void atk7C_8025508(void); +void atk7C_trymirrormove(void); void atk7D_set_rain(void); void atk7E_setreflect(void); void atk7F_setseeded(void); @@ -330,13 +373,13 @@ void atk8A_normalisebuffs(void); void atk8B_setbide(void); void atk8C_confuseifrepeatingattackends(void); void atk8D_setmultihit_counter(void); -void atk8E_prepare_multihit(void); +void atk8E_init_multihit_string(void); void atk8F_forcerandomswitch(void); void atk90_conversion_type_change(void); void atk91_givepaydaymoney(void); void atk92_setlightscreen(void); void atk93_ko_move(void); -void atk94_gethalfcurrentenemyhp(void); +void atk94_damagetohalftargethp(void); void atk95_setsandstorm(void); void atk96_weatherdamage(void); void atk97_try_infatuation(void); @@ -345,7 +388,7 @@ void atk99_setmist(void); void atk9A_set_focusenergy(void); void atk9B_transformdataexecution(void); void atk9C_set_substitute(void); -void atk9D_copyattack(void); +void atk9D_mimicattackcopy(void); void atk9E_metronome(void); void atk9F_dmgtolevel(void); void atkA0_psywavedamageeffect(void); @@ -548,23 +591,23 @@ void (* const gBattleScriptingCommandsTable[])(void) = atk69_dmg_adjustment3, atk6A_removeitem, atk6B_atknameinbuff1, - atk6C_lvlbox_display, - atk6D_set_sentpokes_values, + atk6C_draw_lvlupbox, + atk6D_reset_sentpokes_value, atk6E_set_atk_to_player0, atk6F_set_visible, - atk70_record_ability, + atk70_record_last_used_ability, atk71_buffer_move_to_learn, atk72_jump_if_can_run_frombattle, atk73_hp_thresholds, atk74_hp_thresholds2, - atk75_8026A58, + atk75_item_effect_on_opponent, atk76_various, - atk77_setprotect, + atk77_set_protect_like, atk78_faintifabilitynotdamp, atk79_setatkhptozero, atk7A_jumpwhiletargetvalid, atk7B_healhalfHP_if_possible, - atk7C_8025508, + atk7C_trymirrormove, atk7D_set_rain, atk7E_setreflect, atk7F_setseeded, @@ -582,13 +625,13 @@ void (* const gBattleScriptingCommandsTable[])(void) = atk8B_setbide, atk8C_confuseifrepeatingattackends, atk8D_setmultihit_counter, - atk8E_prepare_multihit, + atk8E_init_multihit_string, atk8F_forcerandomswitch, atk90_conversion_type_change, atk91_givepaydaymoney, atk92_setlightscreen, atk93_ko_move, - atk94_gethalfcurrentenemyhp, + atk94_damagetohalftargethp, atk95_setsandstorm, atk96_weatherdamage, atk97_try_infatuation, @@ -597,7 +640,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = atk9A_set_focusenergy, atk9B_transformdataexecution, atk9C_set_substitute, - atk9D_copyattack, + atk9D_mimicattackcopy, atk9E_metronome, atk9F_dmgtolevel, atkA0_psywavedamageeffect, @@ -781,7 +824,53 @@ const u32 gStatusFlagsForMoveEffects[] = 0x00000000 }; -extern const u8* const gMoveEffectBS_Ptrs[]; +const u8* const gMoveEffectBS_Ptrs[] = +{ + BattleScript_MoveEffectSleep, // 0 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SLEEP + BattleScript_MoveEffectPoison, // MOVE_EFFECT_POISON + BattleScript_MoveEffectBurn, // MOVE_EFFECT_BURN + BattleScript_MoveEffectFreeze, // MOVE_EFFECT_FREEZE + BattleScript_MoveEffectParalysis, // MOVE_EFFECT_PARALYSIS + BattleScript_MoveEffectToxic, // MOVE_EFFECT_TOXIC + BattleScript_MoveEffectConfusion, // MOVE_EFFECT_CONFUSION + BattleScript_MoveEffectSleep, // MOVE_EFFECT_FLINCH + BattleScript_MoveEffectSleep, // MOVE_EFFECT_TRI_ATTACK + BattleScript_MoveEffectUproar, // MOVE_EFFECT_UPROAR + BattleScript_MoveEffectPayDay, // MOVE_EFFECT_PAYDAY + BattleScript_MoveEffectSleep, // MOVE_EFFECT_CHARGING + BattleScript_MoveEffectWrap, // MOVE_EFFECT_WRAP + BattleScript_MoveEffectRecoil33, // MOVE_EFFECT_RECOIL_25 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_DEF_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SPD_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_ATK_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_DEF_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ACC_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_EVS_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_DEF_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SPD_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_ATK_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_DEF_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ACC_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_EVS_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_RECHARGE + BattleScript_MoveEffectSleep, // MOVE_EFFECT_RAGE + BattleScript_MoveEffectSleep, // MOVE_EFFECT_STEAL_ITEM + BattleScript_MoveEffectSleep, // MOVE_EFFECT_PREVENT_ESCAPE + BattleScript_MoveEffectSleep, // MOVE_EFFECT_NIGHTMARE + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ALL_STATS_UP + BattleScript_MoveEffectSleep, // MOVE_EFFECT_RAPIDSPIN + BattleScript_MoveEffectSleep, // MOVE_EFFECT_REMOVE_PARALYSIS + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_DEF_DOWN + BattleScript_MoveEffectRecoil33, // MOVE_EFFECT_RECOIL_33_PARALYSIS +}; + +static const struct WindowTemplate sUnusedWinTemplate = {0, 1, 3, 7, 0xF, 0x1F, 0x3F}; + +extern const struct SpriteTemplate SpriteTemplate_MonIconOnLvlUpBox; +extern const u16 sProtectSuccessRates[]; void atk00_attackcanceler(void) { @@ -1110,7 +1199,7 @@ void atk03_ppreduce(void) && !((gDisableStructs[gBankAttacker].unk18_b) & gBitTable[gCurrMovePos])) { gActiveBank = gBankAttacker; - EmitSetAttributes(0, REQUEST_PPMOVE1_BATTLE + gCurrMovePos, 0, 1, &gBattleMons[gBankAttacker].pp[gCurrMovePos]); + EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + gCurrMovePos, 0, 1, &gBattleMons[gBankAttacker].pp[gCurrMovePos]); MarkBufferBankForExecution(gBankAttacker); } } @@ -1828,7 +1917,7 @@ void atk0C_datahpupdate(void) } } gHitMarker &= ~(HITMARKER_x100000); - EmitSetAttributes(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBank].hp); + EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBank].hp); MarkBufferBankForExecution(gActiveBank); } } @@ -2351,7 +2440,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; gActiveBank = gEffectBank; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBank].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBank].status1); MarkBufferBankForExecution(gActiveBank); if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) @@ -2660,11 +2749,11 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleMons[gBankTarget].item = 0; gActiveBank = gBankAttacker; - EmitSetAttributes(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedItem); + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedItem); MarkBufferBankForExecution(gBankAttacker); gActiveBank = gBankTarget; - EmitSetAttributes(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); MarkBufferBankForExecution(gBankTarget); BattleScriptPush(gBattlescriptCurrInstr + 1); @@ -2703,7 +2792,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleMons[gBankTarget].status1 &= ~(STATUS_PARALYSIS); gActiveBank = gBankTarget; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); BattleScriptPush(gBattlescriptCurrInstr + 1); @@ -2910,7 +2999,7 @@ void atk19_faint_pokemon(void) BattleScriptPush(gBattlescriptCurrInstr); gBattlescriptCurrInstr = BattleScript_GrudgeTakesPp; gActiveBank = gBankAttacker; - EmitSetAttributes(0, moveIndex + REQUEST_PPMOVE1_BATTLE, 0, 1, &gBattleMons[gActiveBank].pp[moveIndex]); + EmitSetMonData(0, moveIndex + REQUEST_PPMOVE1_BATTLE, 0, 1, &gBattleMons[gActiveBank].pp[moveIndex]); MarkBufferBankForExecution(gActiveBank); PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBankAttacker].moves[moveIndex]) @@ -2943,7 +3032,7 @@ void atk1B_faint_effects_clear(void) if (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || gBattleMons[gActiveBank].hp == 0) { gBattleMons[gActiveBank].status1 = 0; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 0x4, &gBattleMons[gActiveBank].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 0x4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); } @@ -4672,7 +4761,7 @@ void atk49_moveend(void) { gBattleMons[gBankTarget].status1 &= ~(STATUS_FREEZE); gActiveBank = gBankTarget; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); MarkBufferBankForExecution(gActiveBank); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove; @@ -4871,7 +4960,7 @@ void atk49_moveend(void) && !gProtectStructs[gBankAttacker].chargingTurn && gBattleMoves[gCurrentMove].target == MOVE_TARGET_BOTH && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) { - u8 bank = GetBankByPlayerAI(GetBankIdentity(gBankTarget) ^ 2); + u8 bank = GetBankByIdentity(GetBankIdentity(gBankTarget) ^ BIT_MON); if (gBattleMons[bank].hp != 0) { gBankTarget = bank; @@ -5019,7 +5108,7 @@ void atk4C_copy_poke_data(void) gBattlePartyID[gActiveBank] = *(gBattleStruct->field_5C + gActiveBank); - EmitGetAttributes(0, 0, gBitTable[gBattlePartyID[gActiveBank]]); + EmitGetMonData(0, 0, gBitTable[gBattlePartyID[gActiveBank]]); MarkBufferBankForExecution(gActiveBank); gBattlescriptCurrInstr += 2; @@ -5225,10 +5314,10 @@ void atk4F_jump_if_cannot_switch(void) { if (GetBankSide(gActiveBank) == SIDE_OPPONENT) { - r7 = GetBankByPlayerAI(1); + r7 = GetBankByIdentity(1); if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - compareVar = GetBankByPlayerAI(3); + compareVar = GetBankByIdentity(3); else compareVar = r7; @@ -5236,10 +5325,10 @@ void atk4F_jump_if_cannot_switch(void) } else { - r7 = GetBankByPlayerAI(0); + r7 = GetBankByIdentity(0); if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - compareVar = GetBankByPlayerAI(2); + compareVar = GetBankByIdentity(2); else compareVar = r7; @@ -5550,9 +5639,9 @@ void atk50_openpartyscreen(void) } else { - gActiveBank = GetBankByPlayerAI(GetBankIdentity(bank) ^ 1); + gActiveBank = GetBankByIdentity(GetBankIdentity(bank) ^ BIT_SIDE); if (gAbsentBankFlags & gBitTable[gActiveBank]) - gActiveBank ^= 2; + gActiveBank ^= BIT_MON; EmitLinkStandbyMsg(0, 2, 0); MarkBufferBankForExecution(gActiveBank); @@ -5712,7 +5801,7 @@ void atk52_switch_in_effects(void) void atk53_trainer_slide(void) { - gActiveBank = GetBankByPlayerAI(gBattlescriptCurrInstr[1]); + gActiveBank = GetBankByIdentity(gBattlescriptCurrInstr[1]); EmitTrainerSlide(0); MarkBufferBankForExecution(gActiveBank); @@ -5748,7 +5837,7 @@ void atk56_fainting_cry(void) void atk57(void) { - gActiveBank = GetBankByPlayerAI(0); + gActiveBank = GetBankByIdentity(0); Emit_x37(0, gBattleOutcome); MarkBufferBankForExecution(gActiveBank); @@ -5783,7 +5872,7 @@ void atk59_learnmove_inbattle(void) } else { - gActiveBank = GetBankByPlayerAI(0); + gActiveBank = GetBankByIdentity(0); if (gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) @@ -5792,7 +5881,7 @@ void atk59_learnmove_inbattle(void) } if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) { - gActiveBank = GetBankByPlayerAI(2); + gActiveBank = GetBankByIdentity(2); if (gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) { @@ -6067,7 +6156,7 @@ void atk5E_8025A70(void) switch (gBattleCommunication[0]) { case 0: - EmitGetAttributes(0, REQUEST_ALL_BATTLE, 0); + EmitGetMonData(0, REQUEST_ALL_BATTLE, 0); MarkBufferBankForExecution(gActiveBank); gBattleCommunication[0]++; break; @@ -6317,3 +6406,2571 @@ void atk69_dmg_adjustment3(void) // The same as 0x7, except there's no random da END: gBattlescriptCurrInstr++; } + +void atk6A_removeitem(void) +{ + u16* usedHeldItem; + + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + GET_USED_ITEM_PTR_VIA_MEME_ACCESS(gActiveBank, usedHeldItem) + *usedHeldItem = gBattleMons[gActiveBank].item; + gBattleMons[gActiveBank].item = 0; + + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBank].item); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +void atk6B_atknameinbuff1(void) +{ + PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBankAttacker, gBattlePartyID[gBankAttacker]) + + gBattlescriptCurrInstr++; +} + +extern u16 gBattle_BG1_X; +extern u16 gBattle_BG1_Y; +extern u16 gBattle_BG2_X; +extern u16 gBattle_BG2_Y; + +void atk6C_draw_lvlupbox(void) +{ + if (gBattleScripting.atk6C_state == 0) + { + if (IsMonGettingExpSentOut()) + gBattleScripting.atk6C_state = 3; + else + gBattleScripting.atk6C_state = 1; + } + + switch (gBattleScripting.atk6C_state) + { + case 1: + gBattle_BG2_Y = 0x60; + SetBgAttribute(2, BG_CTRL_ATTR_MOSAIC, 0); + ShowBg(2); + sub_804F17C(); + gBattleScripting.atk6C_state = 2; + break; + case 2: + if (!sub_804F1CC()) + gBattleScripting.atk6C_state = 3; + break; + case 3: + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0x100; + SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 1); + SetBgAttribute(1, BG_CTRL_ATTR_MOSAIC, 0); + ShowBg(0); + ShowBg(1); + sub_8056A3C(0x12, 7, 0x1D, 0x13, 0x80); + gBattleScripting.atk6C_state = 4; + break; + case 4: + sub_804F100(); + PutWindowTilemap(13); + CopyWindowToVram(13, 3); + gBattleScripting.atk6C_state++; + break; + case 5: + case 7: + if (!IsDma3ManagerBusyWithBgCopy()) + { + gBattle_BG1_Y = 0; + gBattleScripting.atk6C_state++; + } + break; + case 6: + if (gMain.newKeys != 0) + { + PlaySE(SE_SELECT); + sub_804F144(); + CopyWindowToVram(13, 2); + gBattleScripting.atk6C_state++; + } + break; + case 8: + if (gMain.newKeys != 0) + { + PlaySE(SE_SELECT); + sub_8056A3C(0x12, 7, 0x1D, 0x13, 0x81); + gBattleScripting.atk6C_state++; + } + break; + case 9: + if (!sub_804F344()) + { + ClearWindowTilemap(14); + CopyWindowToVram(14, 1); + + ClearWindowTilemap(13); + CopyWindowToVram(13, 1); + + SetBgAttribute(2, BG_CTRL_ATTR_MOSAIC, 2); + ShowBg(2); + + gBattleScripting.atk6C_state = 10; + } + break; + case 10: + if (!IsDma3ManagerBusyWithBgCopy()) + { + SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 0); + SetBgAttribute(1, BG_CTRL_ATTR_MOSAIC, 1); + ShowBg(0); + ShowBg(1); + gBattlescriptCurrInstr++; + } + break; + } +} + +void sub_804F100(void) +{ + struct StatsArray currentStats; + + sub_81D388C(&gPlayerParty[gBattleStruct->expGetterId], ¤tStats); + sub_81D3640(0xD, gBattleResources->statsBeforeLvlUp, ¤tStats, 0xE, 0xD, 0xF); +} + +void sub_804F144(void) +{ + struct StatsArray currentStats; + + sub_81D388C(&gPlayerParty[gBattleStruct->expGetterId], ¤tStats); + sub_81D3784(0xD, ¤tStats, 0xE, 0xD, 0xF); +} + +extern const u16 gUnknown_0831C2C8[]; +extern const u8 gUnknown_0831C2E8[]; + +void sub_804F17C(void) +{ + gBattle_BG2_Y = 0; + gBattle_BG2_X = 0x1A0; + + LoadPalette(gUnknown_0831C2C8, 0x60, 0x20); + CopyToWindowPixelBuffer(14, gUnknown_0831C2E8, 0, 0); + PutWindowTilemap(14); + CopyWindowToVram(14, 3); + + PutMonIconOnLvlUpBox(); +} + +bool8 sub_804F1CC(void) +{ + if (IsDma3ManagerBusyWithBgCopy()) + return TRUE; + + if (gBattle_BG2_X == 0x200) + return FALSE; + + if (gBattle_BG2_X == 0x1A0) + PutLevelAndGenderOnLvlUpBox(); + + gBattle_BG2_X += 8; + if (gBattle_BG2_X >= 0x200) + gBattle_BG2_X = 0x200; + + return (gBattle_BG2_X != 0x200); +} + +void PutLevelAndGenderOnLvlUpBox(void) +{ + u16 monLevel; + u8 monGender; + struct TextSubPrinter subPrinter; + u8 *txtPtr; + u32 var; + + monLevel = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); + monGender = GetMonGender(&gPlayerParty[gBattleStruct->expGetterId]); + GetMonNickname(&gPlayerParty[gBattleStruct->expGetterId], gStringVar4); + + subPrinter.current_text_offset = gStringVar4; + subPrinter.windowId = 14; + subPrinter.fontId = 0; + subPrinter.x = 32; + subPrinter.y = 0; + subPrinter.currentX = 32; + subPrinter.currentY = 0; + subPrinter.letterSpacing = 0; + subPrinter.lineSpacing = 0; + subPrinter.fontColor_l = TEXT_COLOR_TRANSPARENT; + subPrinter.fontColor_h = TEXT_COLOR_WHITE; + subPrinter.bgColor = TEXT_COLOR_TRANSPARENT; + subPrinter.shadowColor = TEXT_COLOR_DARK_GREY; + + AddTextPrinter(&subPrinter, 0xFF, NULL); + + txtPtr = gStringVar4; + gStringVar4[0] = CHAR_SPECIAL_F9; + txtPtr++; + txtPtr[0] = 5; + txtPtr++; + + var = (u32)(txtPtr); + txtPtr = ConvertIntToDecimalStringN(txtPtr, monLevel, STR_CONV_MODE_LEFT_ALIGN, 3); + var = (u32)(txtPtr) - var; + txtPtr = StringFill(txtPtr, 0x77, 4 - var); + + if (monGender != MON_GENDERLESS) + { + if (monGender == MON_MALE) + { + txtPtr = WriteColorChangeControlCode(txtPtr, 0, 0xC); + txtPtr = WriteColorChangeControlCode(txtPtr, 1, 0xD); + *(txtPtr++) = CHAR_MALE; + } + else + { + txtPtr = WriteColorChangeControlCode(txtPtr, 0, 0xE); + txtPtr = WriteColorChangeControlCode(txtPtr, 1, 0xF); + *(txtPtr++) = CHAR_FEMALE; + } + *(txtPtr++) = EOS; + } + + subPrinter.y = 10; + subPrinter.currentY = 10; + AddTextPrinter(&subPrinter, 0xFF, NULL); + + CopyWindowToVram(14, 2); +} + +bool8 sub_804F344(void) +{ + if (gBattle_BG2_X == 0x1A0) + return FALSE; + + if (gBattle_BG2_X - 16 < 0x1A0) + gBattle_BG2_X = 0x1A0; + else + gBattle_BG2_X -= 16; + + return (gBattle_BG2_X != 0x1A0); +} + +#define MON_ICON_LVLUP_BOX_TAG 0xD75A + +#define sDestroy data0 +#define sSavedLvlUpBoxXPosition data1 + +void PutMonIconOnLvlUpBox(void) +{ + u8 spriteId; + const u16* iconPal; + struct SpriteSheet iconSheet; + struct SpritePalette iconPalSheet; + + u16 species = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPECIES); + u32 personality = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_PERSONALITY); + + const u8* iconPtr = GetMonIconPtr(species, personality, 1); + iconSheet.data = iconPtr; + iconSheet.size = 0x200; + iconSheet.tag = MON_ICON_LVLUP_BOX_TAG; + + iconPal = GetValidMonIconPalettePtr(species); + iconPalSheet.data = iconPal; + iconPalSheet.tag = MON_ICON_LVLUP_BOX_TAG; + + LoadSpriteSheet(&iconSheet); + LoadSpritePalette(&iconPalSheet); + + spriteId = CreateSprite(&SpriteTemplate_MonIconOnLvlUpBox, 256, 10, 0); + gSprites[spriteId].sDestroy = FALSE; + gSprites[spriteId].sSavedLvlUpBoxXPosition = gBattle_BG2_X; +} + +void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite) +{ + sprite->pos2.x = sprite->sSavedLvlUpBoxXPosition - gBattle_BG2_X; + + if (sprite->pos2.x != 0) + { + sprite->sDestroy = TRUE; + } + else if (sprite->sDestroy) + { + DestroySprite(sprite); + FreeSpriteTilesByTag(MON_ICON_LVLUP_BOX_TAG); + FreeSpritePaletteByTag(MON_ICON_LVLUP_BOX_TAG); + } +} + +#undef sDestroy +#undef sSavedLvlUpBoxXPosition + +bool32 IsMonGettingExpSentOut(void) +{ + if (gBattlePartyID[0] == gBattleStruct->expGetterId) + return TRUE; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlePartyID[2] == gBattleStruct->expGetterId) + return TRUE; + + return FALSE; +} + +void atk6D_reset_sentpokes_value(void) +{ + ResetSentPokesToOpponentValue(); + gBattlescriptCurrInstr++; +} + +void atk6E_set_atk_to_player0(void) +{ + gBankAttacker = GetBankByIdentity(0); + gBattlescriptCurrInstr++; +} + +void atk6F_set_visible(void) +{ + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + EmitSpriteInvisibility(0, FALSE); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +void atk70_record_last_used_ability(void) +{ + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + RecordAbilityBattle(gActiveBank, gLastUsedAbility); + gBattlescriptCurrInstr += 1; // UB: Should be + 2, one byte for command and one byte for bank argument. +} + +void BufferMoveToLearnIntoBattleTextBuff2(void) +{ + PREPARE_MOVE_BUFFER(gBattleTextBuff2, gMoveToLearn); +} + +void atk71_buffer_move_to_learn(void) +{ + BufferMoveToLearnIntoBattleTextBuff2(); + gBattlescriptCurrInstr++; +} + +void atk72_jump_if_can_run_frombattle(void) +{ + if (CanRunFromBattle(gBank1)) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; +} + +void atk73_hp_thresholds(void) +{ + u8 opposingBank; + s32 result; + + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + opposingBank = gActiveBank ^ BIT_SIDE; + + result = gBattleMons[opposingBank].hp * 100 / gBattleMons[opposingBank].maxHP; + if (result == 0) + result = 1; + + if (result > 69 || !gBattleMons[opposingBank].hp) + gBattleStruct->hpScale = 0; + else if (result > 39) + gBattleStruct->hpScale = 1; + else if (result > 9) + gBattleStruct->hpScale = 2; + else + gBattleStruct->hpScale = 3; + } + + gBattlescriptCurrInstr += 2; +} + +void atk74_hp_thresholds2(void) +{ + u8 opposingBank; + s32 result; + u8 hpSwitchout; + + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + opposingBank = gActiveBank ^ BIT_SIDE; + hpSwitchout = *(gBattleStruct->hpOnSwitchout + GetBankSide(opposingBank)); + result = (hpSwitchout - gBattleMons[opposingBank].hp) * 100 / hpSwitchout; + + if (gBattleMons[opposingBank].hp >= hpSwitchout) + gBattleStruct->hpScale = 0; + else if (result <= 29) + gBattleStruct->hpScale = 1; + else if (result <= 69) + gBattleStruct->hpScale = 2; + else + gBattleStruct->hpScale = 3; + } + + gBattlescriptCurrInstr += 2; +} + +void atk75_item_effect_on_opponent(void) +{ + gBankInMenu = gBankAttacker; + ExecuteTableBasedItemEffect(&gEnemyParty[gBattlePartyID[gBankAttacker]], gLastUsedItem, gBattlePartyID[gBankAttacker], 0, 1); + + gBattlescriptCurrInstr += 1; +} + +extern const u8 gUnknown_0831C4F8[]; +extern const u8* const gRefereeStringsTable[]; + +void atk76_various(void) +{ + u8 side; + s32 i; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + switch (gBattlescriptCurrInstr[2]) + { + case VARIOUS_CANCEL_MULTI_TURN_MOVES: + CancelMultiTurnMoves(gActiveBank); + break; + case VARIOUS_SET_MAGIC_COAT_TARGET: + gBankAttacker = gBankTarget; + side = GetBankSide(gBankAttacker) ^ 1; + if (gSideTimers[side].followmeTimer != 0 && gBattleMons[gSideTimers[side].followmeTarget].hp != 0) + gBankTarget = gSideTimers[side].followmeTarget; + else + gBankTarget = gActiveBank; + break; + case 2: + gBattleCommunication[0] = IsRunningFromBattleImpossible(); + break; + case VARIOUS_GET_MOVE_TARGET: + gBankTarget = GetMoveTarget(gCurrentMove, 0); + break; + case 4: + if (gHitMarker & HITMARKER_FAINTED(gActiveBank)) + gBattleCommunication[0] = 1; + else + gBattleCommunication[0] = 0; + break; + case VARIOUS_RESET_INTIMIDATE_TRACE_BITS: + gSpecialStatuses[gActiveBank].intimidatedPoke = 0; + gSpecialStatuses[gActiveBank].traced = 0; + break; + case VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP: + if (gBattlePartyID[0] == gBattleStruct->expGetterId || gBattlePartyID[2] == gBattleStruct->expGetterId) + { + u16 *choicedMove; + + if (gBattlePartyID[0] == gBattleStruct->expGetterId) + gActiveBank = 0; + else + gActiveBank = 2; + + choicedMove = &gBattleStruct->choicedMove[gActiveBank]; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[gActiveBank].moves[i] == *choicedMove) + break; + } + if (i == 4) + *choicedMove = 0; + } + break; + case 7: + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE)) + && gBattleTypeFlags & BATTLE_TYPE_TRAINER + && gBattleMons[0].hp != 0 + && gBattleMons[1].hp != 0) + { + gHitMarker &= ~(HITMARKER_x400000); + } + break; + case 8: + gBattleCommunication[0] = 0; + gBattleScripting.bank = gActiveBank = gBattleCommunication[1]; + if (!(gBattleStruct->field_92 & gBitTable[gActiveBank]) + && gBattleMons[gActiveBank].maxHP / 2 >= gBattleMons[gActiveBank].hp + && gBattleMons[gActiveBank].hp != 0 + && !(gBattleMons[gActiveBank].status1 & STATUS_SLEEP)) + { + gBattleStruct->field_92 |= gBitTable[gActiveBank]; + gBattleCommunication[0] = 1; + gBattleCommunication[MULTISTRING_CHOOSER] = gUnknown_0831C4F8[GetNatureFromPersonality(gBattleMons[gActiveBank].personality)]; + } + break; + case 9: + i = sub_81A5258(gBattleCommunication); + if (i == 0) + return; + + gBattleCommunication[1] = i; + break; + case 10: + gBattleMons[1].hp = 0; + gHitMarker |= HITMARKER_FAINTED(1); + gBattleStruct->field_2A1 |= gBitTable[gBattlePartyID[1]]; + gDisableStructs[1].truantUnknownBit = 1; + break; + case 11: + gBattleMons[0].hp = 0; + gHitMarker |= HITMARKER_FAINTED(0); + gHitMarker |= HITMARKER_x400000; + gBattleStruct->field_2A0 |= gBitTable[gBattlePartyID[0]]; + gDisableStructs[0].truantUnknownBit = 1; + break; + case 12: + gBattleMons[0].hp = 0; + gBattleMons[1].hp = 0; + gHitMarker |= HITMARKER_FAINTED(0); + gHitMarker |= HITMARKER_FAINTED(1); + gHitMarker |= HITMARKER_x400000; + gBattleStruct->field_2A0 |= gBitTable[gBattlePartyID[0]]; + gBattleStruct->field_2A1 |= gBitTable[gBattlePartyID[1]]; + gDisableStructs[0].truantUnknownBit = 1; + gDisableStructs[1].truantUnknownBit = 1; + break; + case 13: + EmitCmd13(0); + MarkBufferBankForExecution(gActiveBank); + break; + case 14: + sub_81A5BF8(); + break; + case 15: + sub_81A5D44(); + break; + case 16: + BattleStringExpandPlaceholdersToDisplayedString(gRefereeStringsTable[gBattlescriptCurrInstr[1]]); + sub_814F9EC(gDisplayedStringBattle, 0x16); + break; + case 17: + if (IsTextPrinterActive(0x16)) + return; + break; + case VARIOUS_WAIT_CRY: + if (!IsCryFinished()) + return; + break; + case VARIOUS_RETURN_OPPONENT_MON1: + gActiveBank = 1; + if (gBattleMons[gActiveBank].hp != 0) + { + EmitReturnPokeToBall(0, 0); + MarkBufferBankForExecution(gActiveBank); + } + break; + case VARIOUS_RETURN_OPPONENT_MON2: + if (gNoOfAllBanks > 3) + { + gActiveBank = 3; + if (gBattleMons[gActiveBank].hp != 0) + { + EmitReturnPokeToBall(0, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + break; + case 21: + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x55); + break; + case 22: + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + break; + case 23: + gBattleStruct->field_2A2 |= gBitTable[gActiveBank]; + break; + case 24: + if (sub_805725C(gActiveBank)) + return; + break; + case VARIOUS_SET_TELEPORT_OUTCOME: + if (GetBankSide(gActiveBank) == SIDE_PLAYER) + gBattleOutcome = BATTLE_PLAYER_TELEPORTED; + else + gBattleOutcome = BATTLE_OPPONENT_TELEPORTED; + break; + case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC: + EmitPlaySound(0, 0x19C, 1); + MarkBufferBankForExecution(gActiveBank); + break; + } + + gBattlescriptCurrInstr += 3; +} + +void atk77_set_protect_like(void) // protect and endure +{ + bool8 notLastTurn = TRUE; + u16 lastMove = gUnknown_02024260[gBankAttacker]; + + if (lastMove != MOVE_PROTECT && lastMove != MOVE_DETECT && lastMove != MOVE_ENDURE) + gDisableStructs[gBankAttacker].protectUses = 0; + + if (gCurrentMoveTurn == (gNoOfAllBanks - 1)) + notLastTurn = FALSE; + + if (sProtectSuccessRates[gDisableStructs[gBankAttacker].protectUses] >= Random() && notLastTurn) + { + if (gBattleMoves[gCurrentMove].effect == EFFECT_PROTECT) + { + gProtectStructs[gBankAttacker].protected = 1; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + if (gBattleMoves[gCurrentMove].effect == EFFECT_ENDURE) + { + gProtectStructs[gBankAttacker].endured = 1; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + gDisableStructs[gBankAttacker].protectUses++; + } + else + { + gDisableStructs[gBankAttacker].protectUses = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + gBattleMoveFlags |= MOVESTATUS_MISSED; + } + + gBattlescriptCurrInstr++; +} + +void atk78_faintifabilitynotdamp(void) +{ + if (gBattleExecBuffer) + return; + + for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) + { + if (gBattleMons[gBankTarget].ability == ABILITY_DAMP) + break; + } + + if (gBankTarget == gNoOfAllBanks) + { + gActiveBank = gBankAttacker; + gBattleMoveDamage = gBattleMons[gActiveBank].hp; + EmitHealthBarUpdate(0, 0x7FFF); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr++; + + for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBankFlags & gBitTable[gBankTarget])) + break; + } + } + else + { + gLastUsedAbility = ABILITY_DAMP; + RecordAbilityBattle(gBankTarget, gBattleMons[gBankTarget].ability); + gBattlescriptCurrInstr = BattleScript_DampStopsExplosion; + } +} + +void atk79_setatkhptozero(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBank = gBankAttacker; + gBattleMons[gActiveBank].hp = 0; + EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBank].hp); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr++; +} + +void atk7A_jumpwhiletargetvalid(void) // Used by intimidate to loop through all targets. +{ + const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + for (gBankTarget++; ; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBankFlags & gBitTable[gBankTarget])) + break; + } + + if (gBankTarget >= gNoOfAllBanks) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = jumpPtr; + } + else + gBattlescriptCurrInstr += 5; +} + +void atk7B_healhalfHP_if_possible(void) +{ + const u8* failPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + if (BSScriptRead8(gBattlescriptCurrInstr + 5) == BS_GET_ATTACKER) + gBankTarget = gBankAttacker; + + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + + if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) + gBattlescriptCurrInstr = failPtr; + else + gBattlescriptCurrInstr += 6; +} + +void atk7C_trymirrormove(void) +{ + s32 validMovesCount; + s32 i; + u16 move; + u16 movesArray[4]; + + for (i = 0; i < 3; i++) + movesArray[i] = 0; + + for (validMovesCount = 0, i = 0; i < gNoOfAllBanks; i++) + { + if (i != gBankAttacker) + { + move = *(i * 2 + gBankAttacker * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 0) + | (*(i * 2 + gBankAttacker * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 1) << 8); + + if (move != 0 && move != 0xFFFF) + { + movesArray[validMovesCount] = move; + validMovesCount++; + } + } + } + + move = *(gBattleStruct->mirrorMoves + gBankAttacker * 2 + 0) + | (*(gBattleStruct->mirrorMoves + gBankAttacker * 2 + 1) << 8); + + if (move != 0 && move != 0xFFFF) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gCurrentMove = move; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + } + else if (validMovesCount) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + i = Random() % validMovesCount; + gCurrentMove = movesArray[i]; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + } + else + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr++; + } +} + +void atk7D_set_rain(void) +{ + if (gBattleWeather & WEATHER_RAIN_ANY) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_RAIN_TEMPORARY; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gWishFutureKnock.weatherDuration = 5; + } + gBattlescriptCurrInstr++; +} + +void atk7E_setreflect(void) +{ + if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_REFLECT) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_REFLECT; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].reflectTimer = 5; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].reflectBank = gBankAttacker; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_ATK_SIDE) == 2) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + gBattlescriptCurrInstr++; +} + +void atk7F_setseeded(void) +{ + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT || gStatuses3[gBankTarget] & STATUS3_LEECHSEED) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else if (gBattleMons[gBankTarget].type1 == TYPE_GRASS || gBattleMons[gBankTarget].type2 == TYPE_GRASS) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gStatuses3[gBankTarget] |= gBankAttacker; + gStatuses3[gBankTarget] |= STATUS3_LEECHSEED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + + gBattlescriptCurrInstr++; +} + +void atk80_manipulatedamage(void) +{ + switch (BSScriptRead8(gBattlescriptCurrInstr + 1)) + { + case ATK80_DMG_CHANGE_SIGN: + gBattleMoveDamage *= -1; + break; + case ATK80_DMG_HALF_BY_TWO_NOT_MORE_THAN_HALF_MAX_HP: + gBattleMoveDamage /= 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if ((gBattleMons[gBankTarget].maxHP / 2) < gBattleMoveDamage) + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; + break; + case ATK80_DMG_DOUBLED: + gBattleMoveDamage *= 2; + break; + } + + gBattlescriptCurrInstr += 2; +} + +void atk81_setrest(void) +{ + const u8* failJump = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + gActiveBank = gBankTarget = gBankAttacker; + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP * (-1); + + if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) + { + gBattlescriptCurrInstr = failJump; + } + else + { + if (gBattleMons[gBankTarget].status1 & ((u8)(~STATUS_SLEEP))) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + + gBattleMons[gBankTarget].status1 = 3; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 5; + } +} + +void atk82_jumpifnotfirstturn(void) +{ + const u8* failJump = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + if (gDisableStructs[gBankAttacker].isFirstTurn) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = failJump; +} + +void atk83_nop(void) +{ + gBattlescriptCurrInstr++; +} + +bool8 UproarWakeUpCheck(u8 bank) +{ + s32 i; + + for (i = 0; i < gNoOfAllBanks; i++) + { + if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || gBattleMons[bank].ability == ABILITY_SOUNDPROOF) + continue; + + gBattleScripting.bank = i; + + if (gBankTarget == 0xFF) + gBankTarget = i; + else if (gBankTarget == i) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + + break; + } + + if (i == gNoOfAllBanks) + return FALSE; + else + return TRUE; +} + +void atk84_jump_if_cant_sleep(void) +{ + const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + if (UproarWakeUpCheck(gBankTarget)) + { + gBattlescriptCurrInstr = jumpPtr; + } + else if (gBattleMons[gBankTarget].ability == ABILITY_INSOMNIA + || gBattleMons[gBankTarget].ability == ABILITY_VITAL_SPIRIT) + { + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + gBattlescriptCurrInstr = jumpPtr; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else + { + gBattlescriptCurrInstr += 5; + } +} + +void atk85_stockpile(void) +{ + if (gDisableStructs[gBankAttacker].stockpileCounter == 3) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gDisableStructs[gBankAttacker].stockpileCounter++; + + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 1, gDisableStructs[gBankAttacker].stockpileCounter) + + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + gBattlescriptCurrInstr++; +} + +void atk86_stockpiletobasedamage(void) +{ + const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + if (gDisableStructs[gBankAttacker].stockpileCounter == 0) + { + gBattlescriptCurrInstr = jumpPtr; + } + else + { + if (gBattleCommunication[6] != 1) + { + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, + gSideAffecting[GET_BANK_SIDE(gBankTarget)], 0, + 0, gBankAttacker, gBankTarget) + * gDisableStructs[gBankAttacker].stockpileCounter; + gBattleScripting.animTurn = gDisableStructs[gBankAttacker].stockpileCounter; + + if (gProtectStructs[gBankAttacker].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; + } + + gDisableStructs[gBankAttacker].stockpileCounter = 0; + gBattlescriptCurrInstr += 5; + } +} + +void atk87_stockpiletohpheal(void) +{ + const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + if (gDisableStructs[gBankAttacker].stockpileCounter == 0) + { + gBattlescriptCurrInstr = jumpPtr; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else if (gBattleMons[gBankAttacker].maxHP == gBattleMons[gBankAttacker].hp) + { + gDisableStructs[gBankAttacker].stockpileCounter = 0; + gBattlescriptCurrInstr = jumpPtr; + gBankTarget = gBankAttacker; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / (1 << (3 - gDisableStructs[gBankAttacker].stockpileCounter)); + + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + + gBattleScripting.animTurn = gDisableStructs[gBankAttacker].stockpileCounter; + gDisableStructs[gBankAttacker].stockpileCounter = 0; + gBattlescriptCurrInstr += 5; + gBankTarget = gBankAttacker; + } +} + +void atk88_negativedamage(void) +{ + gBattleMoveDamage = -(gHpDealt / 2); + if (gBattleMoveDamage == 0) + gBattleMoveDamage = -1; + + gBattlescriptCurrInstr++; +} + +u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8* BS_ptr) +{ + bool8 certain = 0; + bool8 notProtectAffected = FALSE; + u32 index; + + if (flags & MOVE_EFFECT_AFFECTS_USER) + gActiveBank = gBankAttacker; + else + gActiveBank = gBankTarget; + + flags &= ~(MOVE_EFFECT_AFFECTS_USER); + + if (flags & MOVE_EFFECT_CERTAIN) + certain++; + flags &= ~(MOVE_EFFECT_CERTAIN); + + if (flags & STAT_CHANGE_NOT_PROTECT_AFFECTED) + notProtectAffected++; + flags &= ~(STAT_CHANGE_NOT_PROTECT_AFFECTED); + + PREPARE_STAT_BUFFER(gBattleTextBuff1, statId) + + if ((statValue << 0x18) < 0) // stat decrease + { + if (gSideTimers[GET_BANK_SIDE(gActiveBank)].mistTimer + && !certain && gCurrentMove != MOVE_CURSE) + { + if (flags == STAT_CHANGE_BS_PTR) + { + if (gSpecialStatuses[gActiveBank].statLowered) + { + gBattlescriptCurrInstr = BS_ptr; + } + else + { + BattleScriptPush(BS_ptr); + gBattleScripting.bank = gActiveBank; + gBattlescriptCurrInstr = BattleScript_MistProtected; + gSpecialStatuses[gActiveBank].statLowered = 1; + } + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gCurrentMove != MOVE_CURSE + && notProtectAffected != TRUE && JumpIfMoveAffectedByProtect(0)) + { + gBattlescriptCurrInstr = BattleScript_ButItFailed; + return STAT_CHANGE_DIDNT_WORK; + } + else if ((gBattleMons[gActiveBank].ability == ABILITY_CLEAR_BODY + || gBattleMons[gActiveBank].ability == ABILITY_WHITE_SMOKE) + && !certain && gCurrentMove != MOVE_CURSE) + { + if (flags == STAT_CHANGE_BS_PTR) + { + if (gSpecialStatuses[gActiveBank].statLowered) + { + gBattlescriptCurrInstr = BS_ptr; + } + else + { + BattleScriptPush(BS_ptr); + gBattleScripting.bank = gActiveBank; + gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss; + gLastUsedAbility = gBattleMons[gActiveBank].ability; + RecordAbilityBattle(gActiveBank, gLastUsedAbility); + gSpecialStatuses[gActiveBank].statLowered = 1; + } + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gBattleMons[gActiveBank].ability == ABILITY_KEEN_EYE + && !certain && statId == STAT_STAGE_ACC) + { + if (flags == STAT_CHANGE_BS_PTR) + { + BattleScriptPush(BS_ptr); + gBattleScripting.bank = gActiveBank; + gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; + gLastUsedAbility = gBattleMons[gActiveBank].ability; + RecordAbilityBattle(gActiveBank, gLastUsedAbility); + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gBattleMons[gActiveBank].ability == ABILITY_HYPER_CUTTER + && !certain && statId == STAT_STAGE_ATK) + { + if (flags == STAT_CHANGE_BS_PTR) + { + BattleScriptPush(BS_ptr); + gBattleScripting.bank = gActiveBank; + gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; + gLastUsedAbility = gBattleMons[gActiveBank].ability; + RecordAbilityBattle(gActiveBank, gLastUsedAbility); + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gBattleMons[gActiveBank].ability == ABILITY_SHIELD_DUST && flags == 0) + { + return STAT_CHANGE_DIDNT_WORK; + } + else // try to decrease + { + statValue = -GET_STAT_BUFF_VALUE(statValue); + gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; + index = 1; + if (statValue == -2) + { + gBattleTextBuff2[1] = B_BUFF_STRING; + gBattleTextBuff2[2] = 0xD3; // harshly + gBattleTextBuff2[3] = 0xD3 >> 8; + index = 4; + } + gBattleTextBuff2[index] = B_BUFF_STRING; + index++; + gBattleTextBuff2[index] = 0xD4; // fell + index++; + gBattleTextBuff2[index] = 0xD4 >> 8; + index++; + gBattleTextBuff2[index] = B_BUFF_EOS; + + if (gBattleMons[gActiveBank].statStages[statId] == 0) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = (gBankTarget == gActiveBank); + + } + } + else // stat increase + { + statValue = GET_STAT_BUFF_VALUE(statValue); + gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; + index = 1; + if (statValue == 2) + { + gBattleTextBuff2[1] = B_BUFF_STRING; + gBattleTextBuff2[2] = 0xD1; // sharply + gBattleTextBuff2[3] = 0xD1 >> 8; + index = 4; + } + gBattleTextBuff2[index] = B_BUFF_STRING; + index++; + gBattleTextBuff2[index] = 0xD2; // rose + index++; + gBattleTextBuff2[index] = 0xD2 >> 8; + index++; + gBattleTextBuff2[index] = B_BUFF_EOS; + + if (gBattleMons[gActiveBank].statStages[statId] == 0xC) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = (gBankTarget == gActiveBank); + } + + gBattleMons[gActiveBank].statStages[statId] += statValue; + if (gBattleMons[gActiveBank].statStages[statId] < 0) + gBattleMons[gActiveBank].statStages[statId] = 0; + if (gBattleMons[gActiveBank].statStages[statId] > 0xC) + gBattleMons[gActiveBank].statStages[statId] = 0xC; + + if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && flags & STAT_CHANGE_BS_PTR) + gBattleMoveFlags |= MOVESTATUS_MISSED; + + if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && !(flags & STAT_CHANGE_BS_PTR)) + return STAT_CHANGE_DIDNT_WORK; + + return STAT_CHANGE_WORKED; +} + +void atk89_statbuffchange(void) +{ + const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + if (ChangeStatBuffs(gBattleScripting.statChanger & 0xF0, GET_STAT_BUFF_ID(gBattleScripting.statChanger), BSScriptRead8(gBattlescriptCurrInstr + 1), jumpPtr) == STAT_CHANGE_WORKED) + gBattlescriptCurrInstr += 6; +} + +void atk8A_normalisebuffs(void) // haze +{ + s32 i, j; + + for (i = 0; i < gNoOfAllBanks; i++) + { + for (j = 0; j < BATTLE_STATS_NO; j++) + gBattleMons[i].statStages[j] = 6; + } + + gBattlescriptCurrInstr++; +} + +void atk8B_setbide(void) +{ + gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gBankAttacker] = gCurrentMove; + gTakenDmg[gBankAttacker] = 0; + gBattleMons[gBankAttacker].status2 |= (STATUS2_BIDE - 0x100); // 2 turns + + gBattlescriptCurrInstr++; +} + +void atk8C_confuseifrepeatingattackends(void) +{ + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_LOCK_CONFUSE)) + gBattleCommunication[MOVE_EFFECT_BYTE] = (MOVE_EFFECT_THRASH | MOVE_EFFECT_AFFECTS_USER); + + gBattlescriptCurrInstr++; +} + +void atk8D_setmultihit_counter(void) +{ + if (BSScriptRead8(gBattlescriptCurrInstr + 1)) + { + gMultiHitCounter = BSScriptRead8(gBattlescriptCurrInstr + 1); + } + else + { + gMultiHitCounter = Random() & 3; + if (gMultiHitCounter > 1) + gMultiHitCounter = (Random() & 3) + 2; + else + gMultiHitCounter += 2; + } + + gBattlescriptCurrInstr += 2; +} + +void atk8E_init_multihit_string(void) +{ + PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) + + gBattlescriptCurrInstr++; +} + +bool8 sub_8051064(void) +{ + if (gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + { + *(gBattleStruct->field_58 + gBankTarget) = gBattlePartyID[gBankTarget]; + } + else + { + u16 random = Random() & 0xFF; + if ((u32)((random * (gBattleMons[gBankAttacker].level + gBattleMons[gBankTarget].level) >> 8) + 1) <= (gBattleMons[gBankTarget].level / 4)) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + return FALSE; + } + *(gBattleStruct->field_58 + gBankTarget) = gBattlePartyID[gBankTarget]; + } + + gBattlescriptCurrInstr = gUnknown_082DADD8; + return TRUE; +} + +void atk8F_forcerandomswitch(void) +{ + s32 i; + s32 bank1PartyId = 0; + s32 bank2PartyId = 0; + + #ifdef NONMATCHING + s32 lastMonId = 0; // + 1 + #else + register s32 lastMonId asm("r8") = 0; // + 1 + #endif // NONMATCHING + + s32 firstMonId = 0; + s32 monsCount = 0; + struct Pokemon* party = NULL; + s32 validMons = 0; + s32 minNeeded = 0; + + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER)) + { + if (GetBankSide(gBankTarget) == SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + if ((gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_LINK) + || (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_x2000000) + || (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)) + { + if ((gBankTarget & BIT_MON) != 0) + { + firstMonId = 3; + lastMonId = 6; + } + else + { + firstMonId = 0; + lastMonId = 3; + } + monsCount = 3; + minNeeded = 1; + bank2PartyId = gBattlePartyID[gBankTarget]; + bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; + } + else if ((gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK) + || (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_x2000000)) + { + if (sub_806D82C(sub_806D864(gBankTarget)) == 1) + { + firstMonId = 3; + lastMonId = 6; + } + else + { + firstMonId = 0; + lastMonId = 3; + } + monsCount = 3; + minNeeded = 1; + bank2PartyId = gBattlePartyID[gBankTarget]; + bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; + } + else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + { + if (GetBankSide(gBankTarget) == SIDE_PLAYER) + { + firstMonId = 0; + lastMonId = 6; + monsCount = 6; + minNeeded = 2; // since there are two opponents, it has to be a double battle + } + else + { + if ((gBankTarget & BIT_MON) != 0) + { + firstMonId = 3; + lastMonId = 6; + } + else + { + firstMonId = 0; + lastMonId = 3; + } + monsCount = 3; + minNeeded = 1; + } + bank2PartyId = gBattlePartyID[gBankTarget]; + bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; + } + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + firstMonId = 0; + lastMonId = 6; + monsCount = 6; + minNeeded = 2; + bank2PartyId = gBattlePartyID[gBankTarget]; + bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; + } + else + { + firstMonId = 0; + lastMonId = 6; + monsCount = 6; + minNeeded = 1; + bank2PartyId = gBattlePartyID[gBankTarget]; // there is only one pokemon out in single battles + bank1PartyId = gBattlePartyID[gBankTarget]; + } + + for (i = firstMonId; i < lastMonId; i++) + { + if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[i], MON_DATA_IS_EGG) + && GetMonData(&party[i], MON_DATA_HP) != 0) + { + validMons++; + } + } + + if (validMons <= minNeeded) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + if (sub_8051064()) + { + do + { + i = Random() % monsCount; + i += firstMonId; + } + while (i == bank2PartyId + || i == bank1PartyId + || GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_NONE + || GetMonData(&party[i], MON_DATA_IS_EGG) == TRUE + || GetMonData(&party[i], MON_DATA_HP) == 0); + } + *(gBattleStruct->field_5C + gBankTarget) = i; + + if (!sub_81B1250()) + sub_803BDA0(gBankTarget); + + if ((gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + || (gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_MULTI) + || (gBattleTypeFlags & BATTLE_TYPE_x2000000 && gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + || (gBattleTypeFlags & BATTLE_TYPE_x2000000 && gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + sub_81B8E80(gBankTarget, i, 0); + sub_81B8E80(gBankTarget ^ BIT_MON, i, 1); + } + + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) + sub_80571DC(gBankTarget, i); + } + } + else + { + sub_8051064(); + } +} + +void atk90_conversion_type_change(void) // randomly changes user's type to one of its moves' type +{ + u8 validMoves = 0; + u8 moveChecked; + u8 moveType; + + while (validMoves < 4) + { + if (gBattleMons[gBankAttacker].moves[validMoves] == 0) + break; + + validMoves++; + } + + for (moveChecked = 0; moveChecked < validMoves; moveChecked++) + { + moveType = gBattleMoves[gBattleMons[gBankAttacker].moves[moveChecked]].type; + + if (moveType == TYPE_MYSTERY) + { + if (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST) + moveType = TYPE_GHOST; + else + moveType = TYPE_NORMAL; + } + if (moveType != gBattleMons[gBankAttacker].type1 + && moveType != gBattleMons[gBankAttacker].type2) + { + break; + } + } + + if (moveChecked == validMoves) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + do + { + + while ((moveChecked = Random() & 3) >= validMoves); + + moveType = gBattleMoves[gBattleMons[gBankAttacker].moves[moveChecked]].type; + + if (moveType == TYPE_MYSTERY) + { + if (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST) + moveType = TYPE_GHOST; + else + moveType = TYPE_NORMAL; + } + } + while (moveType == gBattleMons[gBankAttacker].type1 || moveType == gBattleMons[gBankAttacker].type2); + + gBattleMons[gBankAttacker].type1 = moveType; + gBattleMons[gBankAttacker].type2 = moveType; + + PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType) + + gBattlescriptCurrInstr += 5; + } +} + +void atk91_givepaydaymoney(void) +{ + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) && gPaydayMoney != 0) + { + u32 bonusMoney = gPaydayMoney * gBattleStruct->moneyMultiplier; + AddMoney(&gSaveBlock1Ptr->money, bonusMoney); + + PREPARE_HWORD_NUMBER_BUFFER(gBattleTextBuff1, 5, bonusMoney) + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PrintPayDayMoneyString; + } + else + { + gBattlescriptCurrInstr++; + } +} + +void atk92_setlightscreen(void) +{ + if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_LIGHTSCREEN) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_LIGHTSCREEN; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].lightscreenTimer = 5; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].lightscreenBank = gBankAttacker; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_ATK_SIDE) == 2) + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 3; + } + + gBattlescriptCurrInstr++; +} + +void atk93_ko_move(void) +{ + u8 holdEffect, param; + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect; + param = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + param = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < param) + { + RecordItemEffectBattle(gBankTarget, HOLD_EFFECT_FOCUS_BAND); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + + if (gBattleMons[gBankTarget].ability == ABILITY_STURDY) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gLastUsedAbility = ABILITY_STURDY; + gBattlescriptCurrInstr = BattleScript_SturdyPreventsOHKO; + RecordAbilityBattle(gBankTarget, ABILITY_STURDY); + } + else + { + u16 chance; + if (!(gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS)) + { + chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBankAttacker].level - gBattleMons[gBankTarget].level); + if (Random() % 100 + 1 < chance && gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + chance = TRUE; + else + chance = FALSE; + } + else if (gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker + && gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + { + chance = TRUE; + } + else + { + chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBankAttacker].level - gBattleMons[gBankTarget].level); + if (Random() % 100 + 1 < chance && gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + chance = TRUE; + else + chance = FALSE; + } + if (chance) + { + if (gProtectStructs[gBankTarget].endured) + { + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + gBattleMoveFlags |= MOVESTATUS_ENDURED; + } + else if (gSpecialStatuses[gBankTarget].focusBanded) + { + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + gBattleMoveFlags |= MOVESTATUS_HUNGON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + else + { + gBattleMoveDamage = gBattleMons[gBankTarget].hp; + gBattleMoveFlags |= MOVESTATUS_ONEHITKO; + } + gBattlescriptCurrInstr += 5; + } + else + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + if (gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + } +} + +void atk94_damagetohalftargethp(void) // super fang +{ + gBattleMoveDamage = gBattleMons[gBankTarget].hp / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattlescriptCurrInstr++; +} + +void atk95_setsandstorm(void) +{ + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_SANDSTORM_TEMPORARY; + gBattleCommunication[MULTISTRING_CHOOSER] = 3; + gWishFutureKnock.weatherDuration = 5; + } + gBattlescriptCurrInstr++; +} + +void atk96_weatherdamage(void) +{ + if (WEATHER_HAS_EFFECT) + { + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + { + if (gBattleMons[gBankAttacker].type1 != TYPE_ROCK + && gBattleMons[gBankAttacker].type1 != TYPE_STEEL + && gBattleMons[gBankAttacker].type1 != TYPE_GROUND + && gBattleMons[gBankAttacker].type2 != TYPE_ROCK + && gBattleMons[gBankAttacker].type2 != TYPE_STEEL + && gBattleMons[gBankAttacker].type2 != TYPE_GROUND + && gBattleMons[gBankAttacker].ability != ABILITY_SAND_VEIL + && !(gStatuses3[gBankAttacker] & STATUS3_UNDERGROUND) + && !(gStatuses3[gBankAttacker] & STATUS3_UNDERWATER)) + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + else + { + gBattleMoveDamage = 0; + } + } + if (gBattleWeather & WEATHER_HAIL) + { + if (gBattleMons[gBankAttacker].type1 != TYPE_ICE + && gBattleMons[gBankAttacker].type2 != TYPE_ICE + && !(gStatuses3[gBankAttacker] & STATUS3_UNDERGROUND) + && !(gStatuses3[gBankAttacker] & STATUS3_UNDERWATER)) + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + else + { + gBattleMoveDamage = 0; + } + } + } + else + { + gBattleMoveDamage = 0; + } + + if (gAbsentBankFlags & gBitTable[gBankAttacker]) + gBattleMoveDamage = 0; + + gBattlescriptCurrInstr++; +} + +void atk97_try_infatuation(void) +{ + struct Pokemon *monAttacker, *monTarget; + u16 speciesAttacker, speciesTarget; + u32 personalityAttacker, personalityTarget; + + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + monAttacker = &gPlayerParty[gBattlePartyID[gBankAttacker]]; + else + monAttacker = &gEnemyParty[gBattlePartyID[gBankAttacker]]; + + if (GetBankSide(gBankTarget) == SIDE_PLAYER) + monTarget = &gPlayerParty[gBattlePartyID[gBankTarget]]; + else + monTarget = &gEnemyParty[gBattlePartyID[gBankTarget]]; + + speciesAttacker = GetMonData(monAttacker, MON_DATA_SPECIES); + personalityAttacker = GetMonData(monAttacker, MON_DATA_PERSONALITY); + + speciesTarget = GetMonData(monTarget, MON_DATA_SPECIES); + personalityTarget = GetMonData(monTarget, MON_DATA_PERSONALITY); + + if (gBattleMons[gBankTarget].ability == ABILITY_OBLIVIOUS) + { + gBattlescriptCurrInstr = BattleScript_ObliviousPreventsAttraction; + gLastUsedAbility = ABILITY_OBLIVIOUS; + RecordAbilityBattle(gBankTarget, ABILITY_OBLIVIOUS); + } + else + { + if (GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) + || gBattleMons[gBankTarget].status2 & STATUS2_INFATUATION + || GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == MON_GENDERLESS + || GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) == MON_GENDERLESS) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMons[gBankTarget].status2 |= STATUS2_INFATUATED_WITH(gBankAttacker); + gBattlescriptCurrInstr += 5; + } + } +} + +void atk98_status_icon_update(void) +{ + if (gBattleExecBuffer) + return; + + if (BSScriptRead8(gBattlescriptCurrInstr + 1) != BS_ATTACKER_WITH_PARTNER) + { + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + EmitStatusIconUpdate(0, gBattleMons[gActiveBank].status1, gBattleMons[gActiveBank].status2); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 2; + } + else + { + gActiveBank = gBankAttacker; + if (!(gAbsentBankFlags & gBitTable[gActiveBank])) + { + EmitStatusIconUpdate(0, gBattleMons[gActiveBank].status1, gBattleMons[gActiveBank].status2); + MarkBufferBankForExecution(gActiveBank); + } + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gActiveBank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); + if (!(gAbsentBankFlags & gBitTable[gActiveBank])) + { + EmitStatusIconUpdate(0, gBattleMons[gActiveBank].status1, gBattleMons[gActiveBank].status2); + MarkBufferBankForExecution(gActiveBank); + } + } + gBattlescriptCurrInstr += 2; + } +} + +void atk99_setmist(void) +{ + if (gSideTimers[GET_BANK_SIDE(gBankAttacker)].mistTimer) + { + gBattleMoveFlags |= MOVESTATUS_FAILED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gSideTimers[GET_BANK_SIDE(gBankAttacker)].mistTimer = 5; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].mistBank = gBankAttacker; + gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_MIST; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + gBattlescriptCurrInstr++; +} + +void atk9A_set_focusenergy(void) +{ + if (gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) + { + gBattleMoveFlags |= MOVESTATUS_FAILED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gBattleMons[gBankAttacker].status2 |= STATUS2_FOCUS_ENERGY; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + gBattlescriptCurrInstr++; +} + +void atk9B_transformdataexecution(void) +{ + gLastUsedMove = 0xFFFF; + gBattlescriptCurrInstr++; + if (gBattleMons[gBankTarget].status2 & STATUS2_TRANSFORMED + || gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE) + { + gBattleMoveFlags |= MOVESTATUS_FAILED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + s32 i; + u8 *battleMonAttacker, *battleMonTarget; + + gBattleMons[gBankAttacker].status2 |= STATUS2_TRANSFORMED; + gDisableStructs[gBankAttacker].disabledMove = 0; + gDisableStructs[gBankAttacker].disableTimer1 = 0; + gDisableStructs[gBankAttacker].unk0 = gBattleMons[gBankTarget].personality; + gDisableStructs[gBankAttacker].unk18_b = 0; + + PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBankTarget].species) + + battleMonAttacker = (u8*)(&gBattleMons[gBankAttacker]); + battleMonTarget = (u8*)(&gBattleMons[gBankTarget]); + + for (i = 0; i < offsetof(struct BattlePokemon, pp); i++) + battleMonAttacker[i] = battleMonTarget[i]; + + for (i = 0; i < 4; i++) + { + if (gBattleMoves[gBattleMons[gBankAttacker].moves[i]].pp < 5) + gBattleMons[gBankAttacker].pp[i] = gBattleMoves[gBattleMons[gBankAttacker].moves[i]].pp; + else + gBattleMons[gBankAttacker].pp[i] = 5; + } + + gActiveBank = gBankAttacker; + EmitResetActionMoveSelection(0, RESET_MOVE_SELECTION); + MarkBufferBankForExecution(gActiveBank); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } +} + +void atk9C_set_substitute(void) +{ + u32 hp = gBattleMons[gBankAttacker].maxHP / 4; + if (gBattleMons[gBankAttacker].maxHP / 4 == 0) + hp = 1; + + if (gBattleMons[gBankAttacker].hp <= hp) + { + gBattleMoveDamage = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4; // one bit value will only work for pokemon which max hp can go to 1020(which is more than possible in games) + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattleMons[gBankAttacker].status2 |= STATUS2_SUBSTITUTE; + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_WRAPPED); + gDisableStructs[gBankAttacker].substituteHP = gBattleMoveDamage; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE; + } + + gBattlescriptCurrInstr++; +} + +extern const u16 gMovesForbiddenToCopy[]; +#define MIMIC_FORBIDDEN_END 0xFFFE +#define METRONOME_SLEEPTALK_FORBIDDEN_END 0xFFFF + +static bool8 IsMoveUncopyableByMimic(u16 move) +{ + s32 i; + for (i = 0; gMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END + && gMovesForbiddenToCopy[i] != move; i++); + + return (gMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END); +} + +void atk9D_mimicattackcopy(void) +{ + gLastUsedMove = 0xFFFF; + + if (IsMoveUncopyableByMimic(gLastUsedMovesByBanks[gBankTarget]) + || gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED + || gLastUsedMovesByBanks[gBankTarget] == 0 + || gLastUsedMovesByBanks[gBankTarget] == 0xFFFF) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankAttacker].moves[i] == gLastUsedMovesByBanks[gBankTarget]) + break; + } + + if (i == 4) + { + gBattleMons[gBankAttacker].moves[gCurrMovePos] = gLastUsedMovesByBanks[gBankTarget]; + if (gBattleMoves[gLastUsedMovesByBanks[gBankTarget]].pp < 5) + gBattleMons[gBankAttacker].pp[gCurrMovePos] = gBattleMoves[gLastUsedMovesByBanks[gBankTarget]].pp; + else + gBattleMons[gBankAttacker].pp[gCurrMovePos] = 5; + + + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastUsedMovesByBanks[gBankTarget]) + + gDisableStructs[gBankAttacker].unk18_b |= gBitTable[gCurrMovePos]; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + } +} + +#ifdef NONMATCHING +void atk9E_metronome(void) +{ + while (1) + { + const u16 *move; + s32 i, j; + + gCurrentMove = (Random() & 0x1FF) + 1; + if (gCurrentMove > LAST_MOVE_INDEX) + continue; + + for (i = 0; i < 4; i++); // ? + + for (move = gMovesForbiddenToCopy; ; move++) + { + if (*move == gCurrentMove) + break; + if (*move == METRONOME_SLEEPTALK_FORBIDDEN_END) + break; + } + + if (*move == METRONOME_SLEEPTALK_FORBIDDEN_END) + break; + } + + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + gBankTarget = GetMoveTarget(gCurrentMove, 0); +} + +#else +__attribute__((naked)) +void atk9E_metronome(void) +{ + asm( + "\n\ + .syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + ldr r7, =gCurrentMove\n\ + movs r6, 0xB1\n\ + lsls r6, 1\n\ + ldr r5, =gMovesForbiddenToCopy\n\ + ldr r0, =gBattlescriptCurrInstr\n\ + mov r8, r0\n\ +_080524EE:\n\ + bl Random\n\ + ldr r2, =0x000001ff\n\ + adds r1, r2, 0\n\ + ands r0, r1\n\ + adds r0, 0x1\n\ + strh r0, [r7]\n\ + cmp r0, r6\n\ + bhi _080524EE\n\ + movs r0, 0x3\n\ +_08052502:\n\ + subs r0, 0x1\n\ + cmp r0, 0\n\ + bge _08052502\n\ + ldr r4, =gCurrentMove\n\ + ldrh r2, [r4]\n\ + ldr r3, =0x0000ffff\n\ + subs r0, r5, 0x2\n\ +_08052510:\n\ + adds r0, 0x2\n\ + ldrh r1, [r0]\n\ + cmp r1, r2\n\ + beq _0805251C\n\ + cmp r1, r3\n\ + bne _08052510\n\ +_0805251C:\n\ + ldr r0, =0x0000ffff\n\ + cmp r1, r0\n\ + bne _080524EE\n\ + ldr r2, =gHitMarker\n\ + ldr r0, [r2]\n\ + ldr r1, =0xfffffbff\n\ + ands r0, r1\n\ + str r0, [r2]\n\ + ldr r3, =gBattleScriptsForMoveEffects\n\ + ldr r2, =gBattleMoves\n\ + ldrh r1, [r4]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r0, [r0]\n\ + lsls r0, 2\n\ + adds r0, r3\n\ + ldr r0, [r0]\n\ + mov r1, r8\n\ + str r0, [r1]\n\ + ldrh r0, [r4]\n\ + movs r1, 0\n\ + bl GetMoveTarget\n\ + ldr r1, =gBankTarget\n\ + strb r0, [r1]\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} + +#endif // NONMATCHING + +void atk9F_dmgtolevel(void) +{ + gBattleMoveDamage = gBattleMons[gBankAttacker].level; + gBattlescriptCurrInstr++; +} + +void atkA0_psywavedamageeffect(void) +{ + s32 randDamage; + + while ((randDamage = (Random() & 0xF)) > 10); + + randDamage *= 10; + gBattleMoveDamage = gBattleMons[gBankAttacker].level * (randDamage + 50) / 100; + gBattlescriptCurrInstr++; +} + +void atkA1_counterdamagecalculator(void) +{ + u8 sideAttacker = GetBankSide(gBankAttacker); + u8 sideTarget = GetBankSide(gProtectStructs[gBankAttacker].physicalBank); + + if (gProtectStructs[gBankAttacker].physicalDmg + && sideAttacker != sideTarget + && gBattleMons[gProtectStructs[gBankAttacker].physicalBank].hp) + { + gBattleMoveDamage = gProtectStructs[gBankAttacker].physicalDmg * 2; + + if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp) + gBankTarget = gSideTimers[sideTarget].followmeTarget; + else + gBankTarget = gProtectStructs[gBankAttacker].physicalBank; + + gBattlescriptCurrInstr += 5; + } + else + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkA2_mirrorcoatdamagecalculator(void) // a copy of atkA1 with the physical -> special field changes +{ + u8 sideAttacker = GetBankSide(gBankAttacker); + u8 sideTarget = GetBankSide(gProtectStructs[gBankAttacker].specialBank); + + if (gProtectStructs[gBankAttacker].specialDmg && sideAttacker != sideTarget && gBattleMons[gProtectStructs[gBankAttacker].specialBank].hp) + { + gBattleMoveDamage = gProtectStructs[gBankAttacker].specialDmg * 2; + + if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp) + gBankTarget = gSideTimers[sideTarget].followmeTarget; + else + gBankTarget = gProtectStructs[gBankAttacker].specialBank; + + gBattlescriptCurrInstr += 5; + } + else + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkA3_disablelastusedattack(void) +{ + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankTarget].moves[i] == gLastUsedMovesByBanks[gBankTarget]) + break; + } + if (gDisableStructs[gBankTarget].disabledMove == 0 + && i != 4 && gBattleMons[gBankTarget].pp[i] != 0) + { + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBankTarget].moves[i]) + + gDisableStructs[gBankTarget].disabledMove = gBattleMons[gBankTarget].moves[i]; + gDisableStructs[gBankTarget].disableTimer1 = (Random() & 3) + 2; + gDisableStructs[gBankTarget].disableTimer2 = gDisableStructs[gBankTarget].disableTimer1; // used to save the random amount of turns? + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkA4_setencore(void) +{ + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankTarget].moves[i] == gLastUsedMovesByBanks[gBankTarget]) + break; + } + + if (gLastUsedMovesByBanks[gBankTarget] == MOVE_STRUGGLE + || gLastUsedMovesByBanks[gBankTarget] == MOVE_ENCORE + || gLastUsedMovesByBanks[gBankTarget] == MOVE_MIRROR_MOVE) + { + i = 4; + } + + if (gDisableStructs[gBankTarget].encoredMove == 0 + && i != 4 && gBattleMons[gBankTarget].pp[i] != 0) + { + gDisableStructs[gBankTarget].encoredMove = gBattleMons[gBankTarget].moves[i]; + gDisableStructs[gBankTarget].encoredMovePos = i; + gDisableStructs[gBankTarget].encoreTimer1 = (Random() & 3) + 3; + gDisableStructs[gBankTarget].encoreTimer2 = gDisableStructs[gBankTarget].encoreTimer1; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkA5_painsplitdmgcalc(void) +{ + if (!(gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE)) + { + s32 hpDiff = (gBattleMons[gBankAttacker].hp + gBattleMons[gBankTarget].hp) / 2; + s32 painSplitHp = gBattleMoveDamage = gBattleMons[gBankTarget].hp - hpDiff; + u8* storeLoc = (void*)(&gBattleScripting.painSplitHp); + + storeLoc[0] = (painSplitHp); + storeLoc[1] = (painSplitHp & 0x0000FF00) >> 8; + storeLoc[2] = (painSplitHp & 0x00FF0000) >> 16; + storeLoc[3] = (painSplitHp & 0xFF000000) >> 24; + + gBattleMoveDamage = gBattleMons[gBankAttacker].hp - hpDiff; + gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF; + + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +#ifdef NONMATCHING +void atkA6_settypetorandomresistance(void) // conversion 2 +{ + if (gUnknown_02024250[gBankAttacker] == 0 + || gUnknown_02024250[gBankAttacker] == 0xFFFF) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else if (IsTwoTurnsMove(gUnknown_02024250[gBankAttacker]) + && gBattleMons[gUnknown_02024270[gBankAttacker]].status2 & STATUS2_MULTIPLETURNS) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + s32 type = 0, rands = 0; + do + { + while (((type = (Random() & 0x7F)) > 0x70)); + + type *= 3; + + if (gTypeEffectiveness[type] == gUnknown_02024258[gBankAttacker] + && gTypeEffectiveness[type + 2] <= 5 + && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1] + && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1]) + { + gBattleMons[gBankAttacker].type1 = type; + gBattleMons[gBankAttacker].type2 = type; + + PREPARE_TYPE_BUFFER(gBattleTextBuff1, type) + + gBattlescriptCurrInstr += 5; + return; + } + + rands++; + } while (rands <= 999); + + type = 0, rands = 0; + do + { + s8 var = (s8)(gTypeEffectiveness[type]); + if (var > -1 || var < -2) + { + if (gTypeEffectiveness[type] == gUnknown_02024258[gBankAttacker] + && gTypeEffectiveness[type + 2] <= 5 + && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1] + && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1]) + { + gBattleMons[gBankAttacker].type1 = gTypeEffectiveness[rands + 1]; + gBattleMons[gBankAttacker].type2 = gTypeEffectiveness[rands + 1]; + + PREPARE_TYPE_BUFFER(gBattleTextBuff1, gTypeEffectiveness[rands + 1]) + + gBattlescriptCurrInstr += 5; + return; + } + } + type += 3, rands += 3; + } while (rands < 336); + + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +#else +__attribute__((naked)) +void atkA6_settypetorandomresistance(void) // conversion 2 +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + ldr r1, =gUnknown_02024250\n\ + ldr r4, =gBankAttacker\n\ + ldrb r0, [r4]\n\ + lsls r0, 1\n\ + adds r2, r0, r1\n\ + ldrh r1, [r2]\n\ + cmp r1, 0\n\ + beq _08052B7E\n\ + ldr r0, =0x0000ffff\n\ + cmp r1, r0\n\ + beq _08052B7E\n\ + ldrh r0, [r2]\n\ + bl IsTwoTurnsMove\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08052C1C\n\ + ldr r1, =gBattleMons\n\ + ldr r2, =gUnknown_02024270\n\ + ldrb r0, [r4]\n\ + adds r0, r2\n\ + ldrb r2, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r1, 0x50\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 5\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08052C1C\n\ +_08052B7E:\n\ + ldr r3, =gBattlescriptCurrInstr\n\ + ldr r2, [r3]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + str r1, [r3]\n\ + b _08052D08\n\ + .pool\n\ +_08052BB4:\n\ + mov r0, r12\n\ + strb r5, [r0]\n\ + mov r1, r10\n\ + ldrb r0, [r1]\n\ + muls r0, r2\n\ + adds r0, r7\n\ + adds r0, 0x22\n\ + strb r5, [r0]\n\ + ldr r1, =gBattleTextBuff1\n\ + movs r0, 0xFD\n\ + strb r0, [r1]\n\ + movs r0, 0x3\n\ + strb r0, [r1, 0x1]\n\ + strb r5, [r1, 0x2]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x3]\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + b _08052C0A\n\ + .pool\n\ +_08052BE0:\n\ + mov r0, r8\n\ + adds r0, 0x1\n\ + adds r0, r3\n\ + ldrb r2, [r0]\n\ + strb r2, [r4]\n\ + mov r4, r10\n\ + ldrb r0, [r4]\n\ + muls r0, r6\n\ + ldr r7, =gBattleMons\n\ + adds r0, r7\n\ + adds r0, 0x22\n\ + strb r2, [r0]\n\ + ldr r1, =gBattleTextBuff1\n\ + movs r0, 0xFD\n\ + strb r0, [r1]\n\ + movs r0, 0x3\n\ + strb r0, [r1, 0x1]\n\ + strb r2, [r1, 0x2]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x3]\n\ + mov r1, r12\n\ +_08052C0A:\n\ + ldr r0, [r1]\n\ + adds r0, 0x5\n\ + str r0, [r1]\n\ + b _08052D08\n\ + .pool\n\ +_08052C1C:\n\ + movs r4, 0\n\ + mov r8, r4\n\ + movs r7, 0x7F\n\ + mov r9, r7\n\ +_08052C24:\n\ + bl Random\n\ + mov r4, r9\n\ + ands r4, r0\n\ + cmp r4, 0x70\n\ + bhi _08052C24\n\ + lsls r0, r4, 1\n\ + adds r4, r0, r4\n\ + ldr r6, =gTypeEffectiveness\n\ + adds r3, r4, r6\n\ + ldr r1, =gUnknown_02024258\n\ + ldr r2, =gBankAttacker\n\ + ldrb r5, [r2]\n\ + lsls r0, r5, 1\n\ + adds r0, r1\n\ + ldrb r1, [r3]\n\ + mov r10, r2\n\ + ldrh r0, [r0]\n\ + cmp r1, r0\n\ + bne _08052C80\n\ + adds r0, r4, 0x2\n\ + adds r0, r6\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x5\n\ + bhi _08052C80\n\ + ldr r7, =gBattleMons\n\ + movs r2, 0x58\n\ + adds r0, r5, 0\n\ + muls r0, r2\n\ + adds r3, r0, r7\n\ + movs r0, 0x21\n\ + adds r0, r3\n\ + mov r12, r0\n\ + adds r0, r4, 0x1\n\ + adds r0, r6\n\ + ldrb r5, [r0]\n\ + mov r1, r12\n\ + ldrb r0, [r1]\n\ + adds r1, r5, 0\n\ + cmp r0, r1\n\ + beq _08052C80\n\ + adds r0, r3, 0\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, r1\n\ + bne _08052BB4\n\ +_08052C80:\n\ + movs r7, 0x1\n\ + add r8, r7\n\ + ldr r0, =0x000003e7\n\ + cmp r8, r0\n\ + ble _08052C24\n\ + movs r0, 0\n\ + mov r8, r0\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + mov r12, r1\n\ + ldr r3, =gTypeEffectiveness\n\ + adds r0, r4, 0x1\n\ + adds r0, r3\n\ + mov r9, r0\n\ + adds r5, r3, 0\n\ +_08052C9C:\n\ + ldrb r1, [r5]\n\ + cmp r1, 0xFF\n\ + bgt _08052CA6\n\ + cmp r1, 0xFE\n\ + bge _08052CE0\n\ +_08052CA6:\n\ + mov r4, r10\n\ + ldrb r2, [r4]\n\ + lsls r0, r2, 1\n\ + ldr r7, =gUnknown_02024258\n\ + adds r0, r7\n\ + ldrh r0, [r0]\n\ + cmp r1, r0\n\ + bne _08052CE0\n\ + ldrb r0, [r5, 0x2]\n\ + cmp r0, 0x5\n\ + bhi _08052CE0\n\ + movs r6, 0x58\n\ + adds r0, r2, 0\n\ + muls r0, r6\n\ + ldr r1, =gBattleMons\n\ + adds r2, r0, r1\n\ + adds r4, r2, 0\n\ + adds r4, 0x21\n\ + ldrb r0, [r4]\n\ + mov r7, r9\n\ + ldrb r1, [r7]\n\ + cmp r0, r1\n\ + beq _08052CE0\n\ + adds r0, r2, 0\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, r1\n\ + beq _08052CE0\n\ + b _08052BE0\n\ +_08052CE0:\n\ + adds r5, 0x3\n\ + movs r0, 0x3\n\ + add r8, r0\n\ + ldr r0, =0x0000014f\n\ + cmp r8, r0\n\ + bls _08052C9C\n\ + mov r1, r12\n\ + ldr r2, [r1]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + mov r4, r12\n\ + str r1, [r4]\n\ +_08052D08:\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} +#endif // NONMATCHING + +void atkA7_setalwayshitflag(void) +{ + gStatuses3[gBankTarget] &= ~(STATUS3_ALWAYS_HITS); + gStatuses3[gBankTarget] |= 0x10; + gDisableStructs[gBankTarget].bankWithSureHit = gBankAttacker; + gBattlescriptCurrInstr++; +} + +void atkA8_copymovepermanently(void) // sketch +{ + gLastUsedMove = 0xFFFF; + + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED) + && gUnknownMovesUsedByBanks[gBankTarget] != MOVE_STRUGGLE + && gUnknownMovesUsedByBanks[gBankTarget] != 0 + && gUnknownMovesUsedByBanks[gBankTarget] != 0xFFFF + && gUnknownMovesUsedByBanks[gBankTarget] != MOVE_SKETCH) + { + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankAttacker].moves[i] == MOVE_SKETCH) + continue; + if (gBattleMons[gBankAttacker].moves[i] == gUnknownMovesUsedByBanks[gBankTarget]) + break; + } + + if (i != 4) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else // sketch worked + { + struct MovePpInfo movePpData; + + gBattleMons[gBankAttacker].moves[gCurrMovePos] = gUnknownMovesUsedByBanks[gBankTarget]; + gBattleMons[gBankAttacker].pp[gCurrMovePos] = gBattleMoves[gUnknownMovesUsedByBanks[gBankTarget]].pp; + gActiveBank = gBankAttacker; + + for (i = 0; i < 4; i++) + { + movePpData.move[i] = gBattleMons[gBankAttacker].moves[i]; + movePpData.pp[i] = gBattleMons[gBankAttacker].pp[i]; + } + movePpData.ppBonuses = gBattleMons[gBankAttacker].ppBonuses; + + EmitSetMonData(0, REQUEST_MOVES_PP_BATTLE, 0, sizeof(struct MovePpInfo), &movePpData); + MarkBufferBankForExecution(gActiveBank); + + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gUnknownMovesUsedByBanks[gBankTarget]) + + gBattlescriptCurrInstr += 5; + } + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + diff --git a/src/battle_ai.c b/src/battle_ai.c index 75b5eb2ed..8590b0f03 100644 --- a/src/battle_ai.c +++ b/src/battle_ai.c @@ -1802,7 +1802,7 @@ static void BattleAICmd_count_alive_pokemon(void) u32 status; bankOnField1 = gBattlePartyID[index]; status = GetBankIdentity(index) ^ 2; - bankOnField2 = gBattlePartyID[GetBankByPlayerAI(status)]; + bankOnField2 = gBattlePartyID[GetBankByIdentity(status)]; } else // in singles there's only one bank by side { diff --git a/src/calculate_base_damage.c b/src/calculate_base_damage.c index 105b334f2..8996059f9 100644 --- a/src/calculate_base_damage.c +++ b/src/calculate_base_damage.c @@ -19,7 +19,6 @@ extern struct BattleEnigmaBerry gEnigmaBerries[]; extern u16 gBattleMovePower; extern u16 gTrainerBattleOpponent_A; -u8 CountAliveMonsInBattle(u8); bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 bank); extern const struct BattleMove gBattleMoves[]; diff --git a/src/pokemon_2.c b/src/pokemon_2.c index cf073570d..b6359f76a 100644 --- a/src/pokemon_2.c +++ b/src/pokemon_2.c @@ -35,7 +35,7 @@ extern const u8 gText_BadEgg[]; extern const u8 gText_EggNickname[]; extern u8 GetBankSide(u8 bank); -extern u8 GetBankByPlayerAI(u8 bank); +extern u8 GetBankByIdentity(u8 bank); extern u8 GetBankIdentity(u8 bank); u8 CountAliveMonsInBattle(u8 caseId) @@ -90,7 +90,7 @@ u8 sub_8069F34(u8 bank) status ^= 1; if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - return GetBankByPlayerAI(status); + return GetBankByIdentity(status); if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) > 1) { u8 val; @@ -99,14 +99,14 @@ u8 sub_8069F34(u8 bank) val = status ^ 2; else val = status; - return GetBankByPlayerAI(val); + return GetBankByIdentity(val); } else { if ((gAbsentBankFlags & gBitTable[status])) - return GetBankByPlayerAI(status ^ 2); + return GetBankByIdentity(status ^ 2); else - return GetBankByPlayerAI(status); + return GetBankByIdentity(status); } } diff --git a/src/pokemon_3.c b/src/pokemon_3.c index aaa02c5d4..d381c7544 100644 --- a/src/pokemon_3.c +++ b/src/pokemon_3.c @@ -216,7 +216,7 @@ void sub_806CF24(s32 stat) gBankTarget = gBankInMenu; StringCopy(gBattleTextBuff1, gStatNamesTable[gUnknown_08329EC8[stat]]); StringCopy(gBattleTextBuff2, gText_StatRose); - StrCpyDecodeToDisplayedStringBattle(gText_PkmnsStatChanged2); + BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnsStatChanged2); } u8 *sub_806CF78(u16 itemId) @@ -251,7 +251,7 @@ u8 *sub_806CF78(u16 itemId) else { gBankAttacker = gBankInMenu; - StrCpyDecodeToDisplayedStringBattle(gText_PkmnGettingPumped); + BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnGettingPumped); } } } @@ -259,7 +259,7 @@ u8 *sub_806CF78(u16 itemId) if (itemEffect[3] & 0x80) { gBankAttacker = gBankInMenu; - StrCpyDecodeToDisplayedStringBattle(gText_PkmnShroudedInMist); + BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnShroudedInMist); } return gDisplayedStringBattle; diff --git a/src/window.c b/src/window.c index 164031bee..704060b9d 100644 --- a/src/window.c +++ b/src/window.c @@ -451,7 +451,7 @@ void FillWindowPixelRect(u8 windowId, u8 fillValue, u16 x, u16 y, u16 width, u16 FillBitmapRect4Bit(&pixelRect, x, y, width, height, fillValue); } -void CopyToWindowPixelBuffer(u8 windowId, u8 *src, u16 size, u16 tileOffset) +void CopyToWindowPixelBuffer(u8 windowId, const u8 *src, u16 size, u16 tileOffset) { if (size != 0) CpuCopy16(src, gWindows[windowId].tileData + (0x20 * tileOffset), size); -- cgit v1.2.3 From 69928d3904a610791d5e34e32364d9ee5f9392ee Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 27 Sep 2017 23:43:45 +0200 Subject: battle 4 up to 0xE5 --- src/battle_3.c | 21 +- src/battle_4.c | 1756 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/pokemon_3.c | 20 +- 3 files changed, 1726 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index 1fd84a61b..9ac439390 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -261,7 +261,7 @@ u8 sub_803FB4C(void) // msg, can't select a move } } - if (IsImprisoned(gActiveBank, move)) + if (GetImprisonedMovesCount(gActiveBank, move)) { gCurrentMove = move; if (gBattleTypeFlags & BATTLE_TYPE_PALACE) @@ -314,13 +314,6 @@ u8 sub_803FB4C(void) // msg, can't select a move return limitations; } -#define MOVE_LIMITATION_ZEROMOVE (1 << 0) -#define MOVE_LIMITATION_PP (1 << 1) -#define MOVE_LIMITATION_DISABLED (1 << 2) -#define MOVE_LIMITATION_TORMENTED (1 << 3) -#define MOVE_LIMITATION_TAUNT (1 << 4) -#define MOVE_LIMITATION_IMPRISION (1 << 5) - u8 CheckMoveLimitations(u8 bank, u8 unusableMoves, u8 check) { u8 holdEffect; @@ -346,7 +339,7 @@ u8 CheckMoveLimitations(u8 bank, u8 unusableMoves, u8 check) unusableMoves |= gBitTable[i]; if (gDisableStructs[bank].tauntTimer1 && check & MOVE_LIMITATION_TAUNT && gBattleMoves[gBattleMons[bank].moves[i]].power == 0) unusableMoves |= gBitTable[i]; - if (IsImprisoned(bank, gBattleMons[bank].moves[i]) && check & MOVE_LIMITATION_IMPRISION) + if (GetImprisonedMovesCount(bank, gBattleMons[bank].moves[i]) && check & MOVE_LIMITATION_IMPRISION) unusableMoves |= gBitTable[i]; if (gDisableStructs[bank].encoreTimer1 && gDisableStructs[bank].encoredMove != gBattleMons[bank].moves[i]) unusableMoves |= gBitTable[i]; @@ -374,7 +367,7 @@ bool8 AreAllMovesUnusable(void) return (unusable == 0xF); } -u8 IsImprisoned(u8 bank, u16 move) +u8 GetImprisonedMovesCount(u8 bank, u16 move) { s32 i; u8 imprisionedMoves = 0; @@ -382,7 +375,7 @@ u8 IsImprisoned(u8 bank, u16 move) for (i = 0; i < gNoOfAllBanks; i++) { - if (bankSide != GetBankSide(i) && gStatuses3[i] & STATUS3_IMPRISIONED) + if (bankSide != GetBankSide(i) && gStatuses3[i] & STATUS3_IMPRISONED_OTHERS) { s32 j; for (j = 0; j < 4; j++) @@ -1327,7 +1320,7 @@ u8 AtkCanceller_UnableToUseMove(void) gBattleStruct->atkCancellerTracker++; break; case 8: // imprisoned - if (IsImprisoned(gBankAttacker, gCurrentMove)) + if (GetImprisonedMovesCount(gBankAttacker, gCurrentMove)) { gProtectStructs[gBankAttacker].usedImprisionedMove = 1; CancelMultiTurnMoves(gBankAttacker); @@ -2379,7 +2372,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) } } break; - case ABILITYEFFECT_COUNT_OTHER_SIZE: // 16 + case ABILITYEFFECT_COUNT_OTHER_SIDE: // 16 side = GetBankSide(bank); for (i = 0; i < gNoOfAllBanks; i++) { @@ -6238,7 +6231,7 @@ u8 GetMoveTarget(u16 move, u8 useMoveTarget) targetBank = Random() % gNoOfAllBanks; } while (targetBank == gBankAttacker || side == GetBankSide(targetBank) || gAbsentBankFlags & gBitTable[targetBank]); if (gBattleMoves[move].type == TYPE_ELECTRIC - && AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIZE, gBankAttacker, ABILITY_LIGHTNING_ROD, 0, 0) + && AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIDE, gBankAttacker, ABILITY_LIGHTNING_ROD, 0, 0) && gBattleMons[targetBank].ability != ABILITY_LIGHTNING_ROD) { targetBank ^= 2; diff --git a/src/battle_4.c b/src/battle_4.c index 0f52ee0dd..9ef443b70 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -29,6 +29,7 @@ #include "pokemon_icon.h" #include "pokemon_item_effects.h" #include "m4a.h" +#include "mail.h" // variables @@ -96,6 +97,7 @@ extern u16 gUnknownMovesUsedByBanks[BATTLE_BANKS_COUNT]; extern u16 gLastUsedMovesByBanks[BATTLE_BANKS_COUNT]; extern u16 gTrainerBattleOpponent_A; extern u16 gTrainerBattleOpponent_B; +extern u8 gUnknown_020241E9; extern struct MusicPlayerInfo gMPlay_BGM; struct TrainerMoney @@ -127,6 +129,7 @@ extern void sub_81A5BF8(void); // battle frontier 2 extern void sub_81A5D44(void); // battle frontier 2 extern void sub_81B8E80(u8 bank, u8, u8); // party menu extern bool8 sub_81B1250(void); // ? +extern u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale); // battle interface // BattleScripts extern const u8 BattleScript_MoveEnd[]; @@ -150,7 +153,7 @@ extern const u8 BattleScript_ItemSteal[]; extern const u8 BattleScript_RapidSpinAway[]; extern const u8 BattleScript_TargetPRLZHeal[]; extern const u8 BattleScript_KnockedOff[]; -extern const u8 BattleScript_StickyHoldOnKnockOff[]; +extern const u8 BattleScript_StickyHoldActivates[]; extern const u8 BattleScript_AllStatsUp[]; extern const u8 BattleScript_AtkDefDown[]; extern const u8 BattleScript_SAtkDown2[]; @@ -197,6 +200,7 @@ extern const u8 gUnknown_082DADD8[]; extern const u8 BattleScript_PrintPayDayMoneyString[]; extern const u8 BattleScript_SturdyPreventsOHKO[]; extern const u8 BattleScript_ObliviousPreventsAttraction[]; +extern const u8 BattleScript_PauseEffectivenessSoundResultMsgEndMove[]; // strings extern const u8 gText_BattleYesNoChoice[]; @@ -252,7 +256,7 @@ void atk11_printstring_playeronly(void); void atk12_waitmessage(void); void atk13_printfromtable(void); void atk14_printfromtable_playeronly(void); -void atk15_seteffectwithchancetarget(void); +void atk15_seteffectwithchance(void); void atk16_seteffectprimary(void); void atk17_seteffectsecondary(void); void atk18_status_effect_clear(void); @@ -421,15 +425,15 @@ void atkBA_jumpifnopursuitswitchdmg(void); void atkBB_setsunny(void); void atkBC_maxattackhalvehp(void); void atkBD_copyfoestats(void); -void atkBE_breakfree(void); +void atkBE_rapidspinfree(void); void atkBF_set_defense_curl(void); void atkC0_recoverbasedonsunlight(void); void atkC1_hidden_power(void); void atkC2_selectnexttarget(void); void atkC3_setfutureattack(void); void atkC4_beat_up(void); -void atkC5_hidepreattack(void); -void atkC6_unhidepostattack(void); +void atkC5_setsemiinvulnerablebit(void); +void atkC6_clearsemiinvulnerablebit(void); void atkC7_setminimize(void); void atkC8_sethail(void); void atkC9_jumpifattackandspecialattackcannotfall(void); @@ -458,7 +462,7 @@ void atkDF_setmagiccoat(void); void atkE0_setstealstatchange(void); void atkE1_intimidate_string_loader(void); void atkE2_switchout_abilities(void); -void atkE3_jumpiffainted(void); +void atkE3_jumpifhasnohp(void); void atkE4_getsecretpowereffect(void); void atkE5_pickup(void); void atkE6_castform_change_animation(void); @@ -504,7 +508,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = atk12_waitmessage, atk13_printfromtable, atk14_printfromtable_playeronly, - atk15_seteffectwithchancetarget, + atk15_seteffectwithchance, atk16_seteffectprimary, atk17_seteffectsecondary, atk18_status_effect_clear, @@ -673,15 +677,15 @@ void (* const gBattleScriptingCommandsTable[])(void) = atkBB_setsunny, atkBC_maxattackhalvehp, atkBD_copyfoestats, - atkBE_breakfree, + atkBE_rapidspinfree, atkBF_set_defense_curl, atkC0_recoverbasedonsunlight, atkC1_hidden_power, atkC2_selectnexttarget, atkC3_setfutureattack, atkC4_beat_up, - atkC5_hidepreattack, - atkC6_unhidepostattack, + atkC5_setsemiinvulnerablebit, + atkC6_clearsemiinvulnerablebit, atkC7_setminimize, atkC8_sethail, atkC9_jumpifattackandspecialattackcannotfall, @@ -710,7 +714,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = atkE0_setstealstatchange, atkE1_intimidate_string_loader, atkE2_switchout_abilities, - atkE3_jumpiffainted, + atkE3_jumpifhasnohp, atkE4_getsecretpowereffect, atkE5_pickup, atkE6_castform_change_animation, @@ -871,6 +875,8 @@ static const struct WindowTemplate sUnusedWinTemplate = {0, 1, 3, 7, 0xF, 0x1F, extern const struct SpriteTemplate SpriteTemplate_MonIconOnLvlUpBox; extern const u16 sProtectSuccessRates[]; +extern const u16 sNaturePowerMoves[]; +extern const u16 sWeightToDamageTable[]; void atk00_attackcanceler(void) { @@ -1163,7 +1169,7 @@ void atk02_attackstring(void) void atk03_ppreduce(void) { - s32 to_deduct = 1; + s32 ppToDeduct = 1; if (gBattleExecBuffer) return; @@ -1173,15 +1179,15 @@ void atk03_ppreduce(void) switch (gBattleMoves[gCurrentMove].target) { case MOVE_TARGET_FOES_AND_ALLY: - to_deduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_ON_FIELD, gBankAttacker, ABILITY_PRESSURE, 0, 0); + ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_ON_FIELD, gBankAttacker, ABILITY_PRESSURE, 0, 0); break; case MOVE_TARGET_BOTH: case MOVE_TARGET_OPPONENTS_FIELD: - to_deduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIZE, gBankAttacker, ABILITY_PRESSURE, 0, 0); + ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIDE, gBankAttacker, ABILITY_PRESSURE, 0, 0); break; default: if (gBankAttacker != gBankTarget && gBattleMons[gBankTarget].ability == ABILITY_PRESSURE) - to_deduct++; + ppToDeduct++; break; } } @@ -1190,8 +1196,8 @@ void atk03_ppreduce(void) { gProtectStructs[gBankAttacker].notFirstStrike = 1; - if (gBattleMons[gBankAttacker].pp[gCurrMovePos] > to_deduct) - gBattleMons[gBankAttacker].pp[gCurrMovePos] -= to_deduct; + if (gBattleMons[gBankAttacker].pp[gCurrMovePos] > ppToDeduct) + gBattleMons[gBankAttacker].pp[gCurrMovePos] -= ppToDeduct; else gBattleMons[gBankAttacker].pp[gCurrMovePos] = 0; @@ -2126,10 +2132,10 @@ void atk13_printfromtable(void) { if (gBattleExecBuffer == 0) { - u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + const u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); ptr += gBattleCommunication[MULTISTRING_CHOOSER]; - PrepareStringBattle(*(u16*)ptr, gBankAttacker); + PrepareStringBattle(*ptr, gBankAttacker); gBattlescriptCurrInstr += 5; gBattleCommunication[MSG_DISPLAY] = 1; @@ -2140,11 +2146,11 @@ void atk14_printfromtable_playeronly(void) { if (gBattleExecBuffer == 0) { - u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + const u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); ptr += gBattleCommunication[MULTISTRING_CHOOSER]; gActiveBank = gBankAttacker; - EmitPrintStringPlayerOnly(0, *(u16*)ptr); + EmitPrintStringPlayerOnly(0, *ptr); MarkBufferBankForExecution(gActiveBank); gBattlescriptCurrInstr += 5; @@ -2729,23 +2735,17 @@ void SetMoveEffect(bool8 primary, u8 certain) gLastUsedAbility = gBattleMons[gBankTarget].ability; RecordAbilityBattle(gBankTarget, gLastUsedAbility); } - else if (gBattleMons[gBankAttacker].item + else if (gBattleMons[gBankAttacker].item != 0 || gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY - || (gBattleMons[gBankTarget].item > 0x78 && gBattleMons[gBankTarget].item < 0x85) + || IS_ITEM_MAIL(gBattleMons[gBankTarget].item) || gBattleMons[gBankTarget].item == 0) { gBattlescriptCurrInstr++; } else { - // This is a leftover from R/S direct use of ewram addresses - u16* changedItem; - GET_CHANGED_ITEM_PTR_VIA_MEME_ACCESS(gBankAttacker, changedItem); + u16* changedItem = &gBattleStruct->changedItems[gBankAttacker]; gLastUsedItem = *changedItem = gBattleMons[gBankTarget].item; - - // A sane representation of this would simply be: - // gLastUsedItem = gBattleStruct->changedItems[gBankAttacker] = gBattleMons[gBankTarget].item; - gBattleMons[gBankTarget].item = 0; gActiveBank = gBankAttacker; @@ -2833,7 +2833,7 @@ void SetMoveEffect(bool8 primary, u8 certain) else { gLastUsedAbility = ABILITY_STICKY_HOLD; - gBattlescriptCurrInstr = BattleScript_StickyHoldOnKnockOff; + gBattlescriptCurrInstr = BattleScript_StickyHoldActivates; RecordAbilityBattle(gEffectBank, ABILITY_STICKY_HOLD); } break; @@ -2868,7 +2868,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleCommunication[MOVE_EFFECT_BYTE] = 0; } -void atk15_seteffectwithchancetarget(void) +void atk15_seteffectwithchance(void) { u32 percentChance; @@ -3351,8 +3351,8 @@ void atk23_getexp(void) } else { - i = 0x149; - } + i = 0x149; + } // get exp getter bank if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) @@ -4816,8 +4816,7 @@ void atk49_moveend(void) case 7: // changed held items for (i = 0; i < gNoOfAllBanks; i++) { - u16* changedItem; - GET_CHANGED_ITEM_PTR_VIA_MEME_ACCESS(i, changedItem); + u16* changedItem = &gBattleStruct->changedItems[i]; if (*changedItem != 0) { gBattleMons[i].item = *changedItem; @@ -5775,8 +5774,7 @@ void atk52_switch_in_effects(void) for (i = 0; i < gNoOfAllBanks; i++) { - u16* hpOnSwitchout; - GET_HP_SWITCHOUT_PTR_VIA_MEME_ACCESS(GetBankSide(i), hpOnSwitchout) + u16* hpOnSwitchout = &gBattleStruct->hpOnSwitchout[GetBankSide(i)]; *hpOnSwitchout = gBattleMons[i].hp; } @@ -6413,7 +6411,7 @@ void atk6A_removeitem(void) gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); - GET_USED_ITEM_PTR_VIA_MEME_ACCESS(gActiveBank, usedHeldItem) + usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBank]; *usedHeldItem = gBattleMons[gActiveBank].item; gBattleMons[gActiveBank].item = 0; @@ -6653,7 +6651,7 @@ bool8 sub_804F344(void) return (gBattle_BG2_X != 0x1A0); } -#define MON_ICON_LVLUP_BOX_TAG 0xD75A +#define MON_ICON_LVLUP_BOX_TAG 0xD75A #define sDestroy data0 #define sSavedLvlUpBoxXPosition data1 @@ -8148,9 +8146,9 @@ void atk97_try_infatuation(void) || gBattleMons[gBankTarget].status2 & STATUS2_INFATUATION || GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == MON_GENDERLESS || GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) == MON_GENDERLESS) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } else { gBattleMons[gBankTarget].status2 |= STATUS2_INFATUATED_WITH(gBankAttacker); @@ -8296,8 +8294,9 @@ void atk9C_set_substitute(void) } extern const u16 gMovesForbiddenToCopy[]; -#define MIMIC_FORBIDDEN_END 0xFFFE -#define METRONOME_SLEEPTALK_FORBIDDEN_END 0xFFFF +#define MIMIC_FORBIDDEN_END 0xFFFE +#define METRONOME_FORBIDDEN_END 0xFFFF +#define ASSIST_FORBIDDEN_END 0xFFFF static bool8 IsMoveUncopyableByMimic(u16 move) { @@ -8368,11 +8367,11 @@ void atk9E_metronome(void) { if (*move == gCurrentMove) break; - if (*move == METRONOME_SLEEPTALK_FORBIDDEN_END) + if (*move == METRONOME_FORBIDDEN_END) break; } - if (*move == METRONOME_SLEEPTALK_FORBIDDEN_END) + if (*move == METRONOME_FORBIDDEN_END) break; } @@ -8974,3 +8973,1666 @@ void atkA8_copymovepermanently(void) // sketch } } +bool8 IsTwoTurnsMove(u16 move) +{ + if (gBattleMoves[move].effect == EFFECT_SKULL_BASH + || gBattleMoves[move].effect == EFFECT_RAZOR_WIND + || gBattleMoves[move].effect == EFFECT_SKY_ATTACK + || gBattleMoves[move].effect == EFFECT_SOLARBEAM + || gBattleMoves[move].effect == EFFECT_FLY + || gBattleMoves[move].effect == EFFECT_BIDE) + return TRUE; + else + return FALSE; +} + +static bool8 IsInvalidForSleepTalkOrAssist(u16 move) +{ + if (move == 0 || move == MOVE_SLEEP_TALK || move == MOVE_ASSIST + || move == MOVE_MIRROR_MOVE || move == MOVE_METRONOME) + return TRUE; + else + return FALSE; +} + +u8 AttacksThisTurn(u8 bank, u16 move) // Note: returns 1 if it's a charging turn, otherwise 2 +{ + // first argument is unused + if (gBattleMoves[move].effect == EFFECT_SOLARBEAM + && (gBattleWeather & WEATHER_SUN_ANY)) + return 2; + + if (gBattleMoves[move].effect == EFFECT_SKULL_BASH + || gBattleMoves[move].effect == EFFECT_RAZOR_WIND + || gBattleMoves[move].effect == EFFECT_SKY_ATTACK + || gBattleMoves[move].effect == EFFECT_SOLARBEAM + || gBattleMoves[move].effect == EFFECT_FLY + || gBattleMoves[move].effect == EFFECT_BIDE) + { + if ((gHitMarker & HITMARKER_x8000000)) + return 1; + } + return 2; +} + +void atkA9_sleeptalk_choose_move(void) +{ + s32 i; + u8 unusableMovesBits = 0; + + for (i = 0; i < 4; i++) + { + if (IsInvalidForSleepTalkOrAssist(gBattleMons[gBankAttacker].moves[i]) + || gBattleMons[gBankAttacker].moves[i] == MOVE_FOCUS_PUNCH + || gBattleMons[gBankAttacker].moves[i] == MOVE_UPROAR + || IsTwoTurnsMove(gBattleMons[gBankAttacker].moves[i])) + { + unusableMovesBits |= gBitTable[i]; + } + + } + + unusableMovesBits = CheckMoveLimitations(gBankAttacker, unusableMovesBits, ~(MOVE_LIMITATION_PP)); + if (unusableMovesBits == 0xF) // all 4 moves cannot be chosen + { + gBattlescriptCurrInstr += 5; + } + else // at least one move can be chosen + { + u32 movePosition; + + do + { + movePosition = Random() & 3; + } while ((gBitTable[movePosition] & unusableMovesBits)); + + gRandomMove = gBattleMons[gBankAttacker].moves[movePosition]; + gCurrMovePos = movePosition; + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gBankTarget = GetMoveTarget(gRandomMove, 0); + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkAA_set_destinybond(void) +{ + gBattleMons[gBankAttacker].status2 |= STATUS2_DESTINY_BOND; + gBattlescriptCurrInstr++; +} + +void DestinyBondFlagUpdate(void) +{ + u8 sideAttacker = GetBankSide(gBankAttacker); + u8 sideTarget = GetBankSide(gBankTarget); + if (gBattleMons[gBankTarget].status2 & STATUS2_DESTINY_BOND + && sideAttacker != sideTarget + && !(gHitMarker & HITMARKER_GRUDGE)) + { + gHitMarker |= HITMARKER_DESTINYBOND; + } +} + +void atkAB_DestinyBondFlagUpdate(void) +{ + DestinyBondFlagUpdate(); + gBattlescriptCurrInstr++; +} + +extern const u8 sFlailHpScaleToPowerTable[12]; + +void atkAC_remaininghptopower(void) +{ + s32 i; + s32 hpFraction = GetScaledHPFraction(gBattleMons[gBankAttacker].hp, gBattleMons[gBankAttacker].maxHP, 48); + + for (i = 0; i < (s32) sizeof(sFlailHpScaleToPowerTable); i += 2) + { + if (hpFraction <= sFlailHpScaleToPowerTable[i]) + break; + } + + gDynamicBasePower = sFlailHpScaleToPowerTable[i + 1]; + gBattlescriptCurrInstr++; +} + +void atkAD_spite_ppreduce(void) +{ + if (gLastUsedMovesByBanks[gBankTarget] != 0 + && gLastUsedMovesByBanks[gBankTarget] != 0xFFFF) + { + s32 i; + + for (i = 0; i < 4; i++) + { + if (gLastUsedMovesByBanks[gBankTarget] == gBattleMons[gBankTarget].moves[i]) + break; + } + + if (i != 4 && gBattleMons[gBankTarget].pp[i] > 1) + { + s32 ppToDeduct = (Random() & 3) + 2; + if (gBattleMons[gBankTarget].pp[i] < ppToDeduct) + ppToDeduct = gBattleMons[gBankTarget].pp[i]; + + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastUsedMovesByBanks[gBankTarget]) + + ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, 0, 1); + + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct) + + gBattleMons[gBankTarget].pp[i] -= ppToDeduct; + gActiveBank = gBankTarget; + + if (!(gDisableStructs[gActiveBank].unk18_b & gBitTable[i]) + && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) + { + EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + i, 0, 1, &gBattleMons[gActiveBank].pp[i]); + MarkBufferBankForExecution(gActiveBank); + } + + gBattlescriptCurrInstr += 5; + + if (gBattleMons[gBankTarget].pp[i] == 0) + CancelMultiTurnMoves(gBankTarget); + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkAE_heal_party_status(void) +{ + u32 zero = 0; + u8 toHeal = 0; + + if (gCurrentMove == MOVE_HEAL_BELL) + { + struct Pokemon* party; + s32 i; + + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + if (gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF) + { + gBattleMons[gBankAttacker].status1 = 0; + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + } + else + { + RecordAbilityBattle(gBankAttacker, gBattleMons[gBankAttacker].ability); + gBattleCommunication[MULTISTRING_CHOOSER] |= 1; + } + + gActiveBank = gBattleScripting.bank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !(gAbsentBankFlags & gBitTable[gActiveBank])) + { + if (gBattleMons[gActiveBank].ability != ABILITY_SOUNDPROOF) + { + gBattleMons[gActiveBank].status1 = 0; + gBattleMons[gActiveBank].status2 &= ~(STATUS2_NIGHTMARE); + } + else + { + RecordAbilityBattle(gActiveBank, gBattleMons[gActiveBank].ability); + gBattleCommunication[MULTISTRING_CHOOSER] |= 2; + } + } + + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&party[i], MON_DATA_SPECIES2); + u8 abilityBit = GetMonData(&party[i], MON_DATA_ALT_ABILITY); + + if (species != 0 && species != SPECIES_EGG) + { + u8 ability; + + if (gBattlePartyID[gBankAttacker] == i) + ability = gBattleMons[gBankAttacker].ability; + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && gBattlePartyID[gActiveBank] == i + && !(gAbsentBankFlags & gBitTable[gActiveBank])) + ability = gBattleMons[gActiveBank].ability; + else + ability = GetAbilityBySpecies(species, abilityBit); + + if (ability != ABILITY_SOUNDPROOF) + toHeal |= (1 << i); + } + } + } + else // Aromatherapy + { + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + toHeal = 0x3F; + + gBattleMons[gBankAttacker].status1 = 0; + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + + gActiveBank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ 2); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !(gAbsentBankFlags & gBitTable[gActiveBank])) + { + gBattleMons[gActiveBank].status1 = 0; + gBattleMons[gActiveBank].status2 &= ~(STATUS2_NIGHTMARE); + } + + } + + if (toHeal) + { + gActiveBank = gBankAttacker; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, toHeal, 4, &zero); + MarkBufferBankForExecution(gActiveBank); + } + + gBattlescriptCurrInstr++; +} + +void atkAF_cursetarget(void) +{ + if (gBattleMons[gBankTarget].status2 & STATUS2_CURSED) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMons[gBankTarget].status2 |= STATUS2_CURSED; + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattlescriptCurrInstr += 5; + } +} + +void atkB0_set_spikes(void) +{ + u8 targetSide = GetBankSide(gBankAttacker) ^ BIT_SIDE; + + if (gSideTimers[targetSide].spikesAmount == 3) + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gSideAffecting[targetSide] |= SIDE_STATUS_SPIKES; + gSideTimers[targetSide].spikesAmount++; + gBattlescriptCurrInstr += 5; + } +} + +void atkB1_set_foresight(void) +{ + gBattleMons[gBankTarget].status2 |= STATUS2_FORESIGHT; + gBattlescriptCurrInstr++; +} + +void atkB2_setperishsong(void) +{ + s32 i; + s32 notAffectedCount = 0; + + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gStatuses3[i] & STATUS3_PERISH_SONG + || gBattleMons[i].ability == ABILITY_SOUNDPROOF) + { + notAffectedCount++; + } + else + { + gStatuses3[i] |= STATUS3_PERISH_SONG; + gDisableStructs[i].perishSong1 = 3; + gDisableStructs[i].perishSong2 = 3; + } + } + + PressurePPLoseOnUsingPerishSong(gBankAttacker); + + if (notAffectedCount == gNoOfAllBanks) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; +} + +void atkB3_rolloutdamagecalculation(void) +{ + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) + { + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_PauseEffectivenessSoundResultMsgEndMove; + } + else + { + s32 i; + + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) // first hit + { + gDisableStructs[gBankAttacker].rolloutTimer1 = 5; + gDisableStructs[gBankAttacker].rolloutTimer2 = 5; + gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gBankAttacker] = gCurrentMove; + } + if (--gDisableStructs[gBankAttacker].rolloutTimer1 == 0) // last hit + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS); + } + + gDynamicBasePower = gBattleMoves[gCurrentMove].power; + + for (i = 1; i < (5 - gDisableStructs[gBankAttacker].rolloutTimer1); i++) + gDynamicBasePower *= 2; + + if (gBattleMons[gBankAttacker].status2 & STATUS2_DEFENSE_CURL) + gDynamicBasePower *= 2; + + gBattlescriptCurrInstr++; + } +} + +void atkB4_jumpifconfusedandstatmaxed(void) +{ + if (gBattleMons[gBankTarget].status2 & STATUS2_CONFUSION + && gBattleMons[gBankTarget].statStages[gBattlescriptCurrInstr[1]] == 0xC) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; +} + +void atkB5_furycuttercalc(void) +{ + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) + { + gDisableStructs[gBankAttacker].furyCutterCounter = 0; + gBattlescriptCurrInstr = BattleScript_PauseEffectivenessSoundResultMsgEndMove; + } + else + { + s32 i; + + if (gDisableStructs[gBankAttacker].furyCutterCounter != 5) + gDisableStructs[gBankAttacker].furyCutterCounter++; + + gDynamicBasePower = gBattleMoves[gCurrentMove].power; + + for (i = 1; i < gDisableStructs[gBankAttacker].furyCutterCounter; i++) + gDynamicBasePower *= 2; + + gBattlescriptCurrInstr++; + } +} + +void atkB6_happinesstodamagecalculation(void) +{ + if (gBattleMoves[gCurrentMove].effect == EFFECT_RETURN) + gDynamicBasePower = 10 * (gBattleMons[gBankAttacker].friendship) / 25; + else // EFFECT_FRUSTRATION + gDynamicBasePower = 10 * (255 - gBattleMons[gBankAttacker].friendship) / 25; + + gBattlescriptCurrInstr++; +} + +extern const u8 BattleScript_PresentDamageTarget[]; +extern const u8 BattleScript_AlreadyAtFullHp[]; +extern const u8 BattleScript_PresentHealTarget[]; + +void atkB7_presentdamagecalculation(void) +{ + s32 rand = Random() & 0xFF; + + if (rand < 102) + gDynamicBasePower = 40; + else if (rand < 178) + gDynamicBasePower = 80; + else if (rand < 204) + gDynamicBasePower = 120; + else + { + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + } + if (rand < 204) + gBattlescriptCurrInstr = BattleScript_PresentDamageTarget; + else if (gBattleMons[gBankTarget].maxHP == gBattleMons[gBankTarget].hp) + gBattlescriptCurrInstr = BattleScript_AlreadyAtFullHp; + else + { + gBattleMoveFlags &= ~(MOVESTATUS_NOTAFFECTED); + gBattlescriptCurrInstr = BattleScript_PresentHealTarget; + } +} + +void atkB8_set_safeguard(void) +{ + if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_SAFEGUARD) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_SAFEGUARD; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].safeguardTimer = 5; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].safeguardBank = gBankAttacker; + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + } + + gBattlescriptCurrInstr++; +} + +void atkB9_magnitudedamagecalculation(void) +{ + s32 magnitude = Random() % 100; + + if (magnitude < 5) + { + gDynamicBasePower = 10; + magnitude = 4; + } + else if (magnitude < 15) + { + gDynamicBasePower = 30; + magnitude = 5; + } + else if (magnitude < 35) + { + gDynamicBasePower = 50; + magnitude = 6; + } + else if (magnitude < 65) + { + gDynamicBasePower = 70; + magnitude = 7; + } + else if (magnitude < 85) + { + gDynamicBasePower = 90; + magnitude = 8; + } + else if (magnitude < 95) + { + gDynamicBasePower = 110; + magnitude = 9; + } + else + { + gDynamicBasePower = 150; + magnitude = 10; + } + + + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 2, magnitude) + + for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBankFlags & gBitTable[gBankTarget])) // a valid target was found + break; + } + + gBattlescriptCurrInstr++; +} + +void atkBA_jumpifnopursuitswitchdmg(void) +{ + if (gMultiHitCounter == 1) + { + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + gBankTarget = GetBankByIdentity(IDENTITY_OPPONENT_MON1); + else + gBankTarget = GetBankByIdentity(IDENTITY_PLAYER_MON1); + } + else + { + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + gBankTarget = GetBankByIdentity(IDENTITY_OPPONENT_MON2); + else + gBankTarget = GetBankByIdentity(IDENTITY_PLAYER_MON2); + } + + if (gActionForBanks[gBankTarget] == 0 + && gBankAttacker == *(gBattleStruct->moveTarget + gBankTarget) + && !(gBattleMons[gBankTarget].status1 & (STATUS_SLEEP | STATUS_FREEZE)) + && gBattleMons[gBankAttacker].hp + && !gDisableStructs[gBankTarget].truantCounter + && gChosenMovesByBanks[gBankTarget] == MOVE_PURSUIT) + { + s32 i; + + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gTurnOrder[i] == gBankTarget) + gUnknown_0202407A[i] = 11; + } + + gCurrentMove = MOVE_PURSUIT; + gCurrMovePos = gUnknown_020241E9 = *(gBattleStruct->chosenMovesIds + gBankTarget); + gBattlescriptCurrInstr += 5; + gBattleScripting.animTurn = 1; + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkBB_setsunny(void) +{ + if (gBattleWeather & WEATHER_SUN_ANY) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_SUN_TEMPORARY; + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + gWishFutureKnock.weatherDuration = 5; + } + + gBattlescriptCurrInstr++; +} + +void atkBC_maxattackhalvehp(void) // belly drum +{ + u32 halfHp = gBattleMons[gBankAttacker].maxHP / 2; + + if (!(gBattleMons[gBankAttacker].maxHP / 2)) + halfHp = 1; + + if (gBattleMons[gBankAttacker].statStages[STAT_STAGE_ATK] < 12 + && gBattleMons[gBankAttacker].hp > halfHp) + { + gBattleMons[gBankAttacker].statStages[STAT_STAGE_ATK] = 12; + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkBD_copyfoestats(void) // psych up +{ + s32 i; + + for (i = 0; i < BATTLE_STATS_NO; i++) + { + gBattleMons[gBankAttacker].statStages[i] = gBattleMons[gBankTarget].statStages[i]; + } + + gBattlescriptCurrInstr += 5; // Has an unused jump ptr(possibly for a failed attempt) parameter. +} + +extern const u8 BattleScript_WrapFree[]; +extern const u8 BattleScript_LeechSeedFree[]; +extern const u8 BattleScript_SpikesFree[]; + +void atkBE_rapidspinfree(void) +{ + if (gBattleMons[gBankAttacker].status2 & STATUS2_WRAPPED) + { + gBattleScripting.bank = gBankTarget; + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_WRAPPED); + gBankTarget = *(gBattleStruct->wrappedBy + gBankAttacker); + + gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN; + gBattleTextBuff1[1] = B_BUFF_MOVE; + gBattleTextBuff1[2] = *(gBattleStruct->wrappedMove + gBankAttacker * 2 + 0); + gBattleTextBuff1[3] = *(gBattleStruct->wrappedMove + gBankAttacker * 2 + 1); + gBattleTextBuff1[4] = B_BUFF_EOS; + + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_WrapFree; + } + else if (gStatuses3[gBankAttacker] & STATUS3_LEECHSEED) + { + gStatuses3[gBankAttacker] &= ~(STATUS3_LEECHSEED); + gStatuses3[gBankAttacker] &= ~(STATUS3_LEECHSEED_BANK); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_LeechSeedFree; + } + else if (gSideAffecting[GetBankSide(gBankAttacker)] & SIDE_STATUS_SPIKES) + { + gSideAffecting[GetBankSide(gBankAttacker)] &= ~(SIDE_STATUS_SPIKES); + gSideTimers[GetBankSide(gBankAttacker)].spikesAmount = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SpikesFree; + } + else + { + gBattlescriptCurrInstr++; + } +} + +void atkBF_set_defense_curl(void) +{ + gBattleMons[gBankAttacker].status2 |= STATUS2_DEFENSE_CURL; + gBattlescriptCurrInstr++; +} + +void atkC0_recoverbasedonsunlight(void) +{ + gBankTarget = gBankAttacker; + + if (gBattleMons[gBankAttacker].hp != gBattleMons[gBankAttacker].maxHP) + { + if (gBattleWeather == 0 || !WEATHER_HAS_EFFECT) + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; + else if (gBattleWeather & WEATHER_SUN_ANY) + gBattleMoveDamage = 20 * gBattleMons[gBankAttacker].maxHP / 30; + else // not sunny weather + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4; + + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +#ifdef NONMATCHING +void atkC1_hidden_power(void) +{ + s32 powerBits; + s32 typeBits; + + powerBits = ((gBattleMons[gBankAttacker].hpIV & 2) >> 1) + | ((gBattleMons[gBankAttacker].attackIV & 2) << 0) + | ((gBattleMons[gBankAttacker].defenseIV & 2) << 1) + | ((gBattleMons[gBankAttacker].speedIV & 2) << 2) + | ((gBattleMons[gBankAttacker].spAttackIV & 2) << 3) + | ((gBattleMons[gBankAttacker].spDefenseIV & 2) << 4); + + typeBits = ((gBattleMons[gBankAttacker].hpIV & 1) << 0) + | ((gBattleMons[gBankAttacker].attackIV & 1) << 1) + | ((gBattleMons[gBankAttacker].defenseIV & 1) << 2) + | ((gBattleMons[gBankAttacker].speedIV & 1) << 3) + | ((gBattleMons[gBankAttacker].spAttackIV & 1) << 4) + | ((gBattleMons[gBankAttacker].spDefenseIV & 1) << 5); + + gDynamicBasePower = (40 * powerBits) / 63 + 30; + + gBattleStruct->dynamicMoveType = (15 * typeBits) / 63 + 1; + if (gBattleStruct->dynamicMoveType > 8) + gBattleStruct->dynamicMoveType++; + gBattleStruct->dynamicMoveType |= 0xC0; + + gBattlescriptCurrInstr++; +} + +#else +__attribute__((naked)) +void atkC1_hidden_power(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + ldr r2, =gBattleMons\n\ + ldr r0, =gBankAttacker\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + adds r4, r1, 0\n\ + muls r4, r0\n\ + adds r4, r2\n\ + ldrb r0, [r4, 0x14]\n\ + mov r10, r0\n\ + mov r7, r10\n\ + lsls r7, 27\n\ + adds r0, r7, 0\n\ + lsrs r0, 27\n\ + mov r10, r0\n\ + movs r1, 0x2\n\ + mov r2, r10\n\ + ands r2, r1\n\ + asrs r2, 1\n\ + ldrh r7, [r4, 0x14]\n\ + mov r9, r7\n\ + mov r0, r9\n\ + lsls r0, 22\n\ + mov r9, r0\n\ + lsrs r3, r0, 27\n\ + adds r0, r1, 0\n\ + ands r0, r3\n\ + orrs r2, r0\n\ + ldrb r7, [r4, 0x15]\n\ + mov r8, r7\n\ + mov r0, r8\n\ + lsls r0, 25\n\ + mov r8, r0\n\ + lsrs r3, r0, 27\n\ + adds r0, r1, 0\n\ + ands r0, r3\n\ + lsls r0, 1\n\ + orrs r2, r0\n\ + ldr r6, [r4, 0x14]\n\ + lsls r6, 12\n\ + lsrs r3, r6, 27\n\ + adds r0, r1, 0\n\ + ands r0, r3\n\ + lsls r0, 2\n\ + orrs r2, r0\n\ + ldrh r5, [r4, 0x16]\n\ + lsls r5, 23\n\ + lsrs r3, r5, 27\n\ + adds r0, r1, 0\n\ + ands r0, r3\n\ + lsls r0, 3\n\ + orrs r2, r0\n\ + ldrb r3, [r4, 0x17]\n\ + lsls r3, 26\n\ + lsrs r0, r3, 27\n\ + ands r1, r0\n\ + lsls r1, 4\n\ + orrs r2, r1\n\ + movs r1, 0x1\n\ + adds r4, r1, 0\n\ + mov r7, r10\n\ + ands r4, r7\n\ + mov r0, r9\n\ + lsrs r0, 27\n\ + mov r9, r0\n\ + adds r0, r1, 0\n\ + mov r7, r9\n\ + ands r0, r7\n\ + lsls r0, 1\n\ + orrs r4, r0\n\ + mov r0, r8\n\ + lsrs r0, 27\n\ + mov r8, r0\n\ + adds r0, r1, 0\n\ + mov r7, r8\n\ + ands r0, r7\n\ + lsls r0, 2\n\ + orrs r4, r0\n\ + lsrs r6, 27\n\ + adds r0, r1, 0\n\ + ands r0, r6\n\ + lsls r0, 3\n\ + orrs r4, r0\n\ + lsrs r5, 27\n\ + adds r0, r1, 0\n\ + ands r0, r5\n\ + lsls r0, 4\n\ + orrs r4, r0\n\ + lsrs r3, 27\n\ + ands r1, r3\n\ + lsls r1, 5\n\ + orrs r4, r1\n\ + ldr r5, =gDynamicBasePower\n\ + lsls r0, r2, 2\n\ + adds r0, r2\n\ + lsls r0, 3\n\ + movs r1, 0x3F\n\ + bl __divsi3\n\ + adds r0, 0x1E\n\ + strh r0, [r5]\n\ + ldr r6, =gBattleStruct\n\ + ldr r5, [r6]\n\ + lsls r0, r4, 4\n\ + subs r0, r4\n\ + movs r1, 0x3F\n\ + bl __divsi3\n\ + adds r0, 0x1\n\ + strb r0, [r5, 0x13]\n\ + ldr r1, [r6]\n\ + ldrb r0, [r1, 0x13]\n\ + cmp r0, 0x8\n\ + bls _080544F0\n\ + adds r0, 0x1\n\ + strb r0, [r1, 0x13]\n\ +_080544F0:\n\ + ldr r2, [r6]\n\ + ldrb r0, [r2, 0x13]\n\ + movs r1, 0xC0\n\ + orrs r0, r1\n\ + strb r0, [r2, 0x13]\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x1\n\ + str r0, [r1]\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} +#endif // NONMATCHING + +void atkC2_selectnexttarget(void) +{ + for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBankFlags & gBitTable[gBankTarget])) + break; + } + gBattlescriptCurrInstr++; +} + +void atkC3_setfutureattack(void) +{ + if (gWishFutureKnock.futureSightCounter[gBankTarget] != 0) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gSideAffecting[GET_BANK_SIDE(gBankTarget)] |= SIDE_STATUS_FUTUREATTACK; + gWishFutureKnock.futureSightMove[gBankTarget] = gCurrentMove; + gWishFutureKnock.futureSightAttacker[gBankTarget] = gBankAttacker; + gWishFutureKnock.futureSightCounter[gBankTarget] = 3; + gWishFutureKnock.futureSightDmg[gBankTarget] = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, + gSideAffecting[GET_BANK_SIDE(gBankTarget)], 0, + 0, gBankAttacker, gBankTarget); + + if (gProtectStructs[gBankAttacker].helpingHand) + gWishFutureKnock.futureSightDmg[gBankTarget] = gWishFutureKnock.futureSightDmg[gBankTarget] * 15 / 10; + + if (gCurrentMove == MOVE_DOOM_DESIRE) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + + gBattlescriptCurrInstr += 5; + } +} + +void atkC4_beat_up(void) +{ + struct Pokemon* party; + + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + if (gBattleMons[gBankTarget].hp == 0) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + u8 beforeLoop = gBattleCommunication[0]; + for (;gBattleCommunication[0] < 6; gBattleCommunication[0]++) + { + if (GetMonData(&party[gBattleCommunication[0]], MON_DATA_HP) + && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) + && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) != SPECIES_EGG + && !GetMonData(&party[gBattleCommunication[0]], MON_DATA_STATUS)) + break; + } + if (gBattleCommunication[0] < 6) + { + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBankAttacker, gBattleCommunication[0]) + + gBattlescriptCurrInstr += 9; + + gBattleMoveDamage = gBaseStats[GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES)].baseAttack; + gBattleMoveDamage *= gBattleMoves[gCurrentMove].power; + gBattleMoveDamage *= (GetMonData(&party[gBattleCommunication[0]], MON_DATA_LEVEL) * 2 / 5 + 2); + gBattleMoveDamage /= gBaseStats[gBattleMons[gBankTarget].species].baseDefense; + gBattleMoveDamage = (gBattleMoveDamage / 50) + 2; + if (gProtectStructs[gBankAttacker].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; + + gBattleCommunication[0]++; + } + else if (beforeLoop != 0) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 5); + } +} + +void atkC5_setsemiinvulnerablebit(void) +{ + switch (gCurrentMove) + { + case MOVE_FLY: + case MOVE_BOUNCE: + gStatuses3[gBankAttacker] |= STATUS3_ON_AIR; + break; + case MOVE_DIG: + gStatuses3[gBankAttacker] |= STATUS3_UNDERGROUND; + break; + case MOVE_DIVE: + gStatuses3[gBankAttacker] |= STATUS3_UNDERWATER; + break; + } + + gBattlescriptCurrInstr++; +} + +void atkC6_clearsemiinvulnerablebit(void) +{ + switch (gCurrentMove) + { + case MOVE_FLY: + case MOVE_BOUNCE: + gStatuses3[gBankAttacker] &= ~STATUS3_ON_AIR; + break; + case MOVE_DIG: + gStatuses3[gBankAttacker] &= ~STATUS3_UNDERGROUND; + break; + case MOVE_DIVE: + gStatuses3[gBankAttacker] &= ~STATUS3_UNDERWATER; + break; + } + + gBattlescriptCurrInstr++; +} + +void atkC7_setminimize(void) +{ + if (gHitMarker & HITMARKER_OBEYS) + gStatuses3[gBankAttacker] |= STATUS3_MINIMIZED; + + gBattlescriptCurrInstr++; +} + +void atkC8_sethail(void) +{ + if (gBattleWeather & WEATHER_HAIL_ANY) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_HAIL; + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + gWishFutureKnock.weatherDuration = 5; + } + + gBattlescriptCurrInstr++; +} + +void atkC9_jumpifattackandspecialattackcannotfall(void) // memento +{ + if (gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] == 0 + && gBattleMons[gBankTarget].statStages[STAT_STAGE_SPATK] == 0 + && gBattleCommunication[6] != 1) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gActiveBank = gBankAttacker; + gBattleMoveDamage = gBattleMons[gActiveBank].hp; + EmitHealthBarUpdate(0, 0x7FFF); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 5; + } +} + +void atkCA_setforcedtarget(void) // follow me +{ + gSideTimers[GetBankSide(gBankAttacker)].followmeTimer = 1; + gSideTimers[GetBankSide(gBankAttacker)].followmeTarget = gBankAttacker; + gBattlescriptCurrInstr++; +} + +void atkCB_setcharge(void) +{ + gStatuses3[gBankAttacker] |= STATUS3_CHARGED_UP; + gDisableStructs[gBankAttacker].chargeTimer1 = 2; + gDisableStructs[gBankAttacker].chargeTimer2 = 2; + gBattlescriptCurrInstr++; +} + +void atkCC_callterrainattack(void) // nature power +{ + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gCurrentMove = sNaturePowerMoves[gBattleTerrain]; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); + gBattlescriptCurrInstr++; +} + +void atkCD_cureifburnedparalysedorpoisoned(void) // refresh +{ + if (gBattleMons[gBankAttacker].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON)) + { + gBattleMons[gBankAttacker].status1 = 0; + gBattlescriptCurrInstr += 5; + gActiveBank = gBankAttacker; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkCE_settorment(void) +{ + if (gBattleMons[gBankTarget].status2 & STATUS2_TORMENT) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMons[gBankTarget].status2 |= STATUS2_TORMENT; + gBattlescriptCurrInstr += 5; + } +} + +void atkCF_jumpifnodamage(void) +{ + if (gProtectStructs[gBankAttacker].physicalDmg || gProtectStructs[gBankAttacker].specialDmg) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); +} + +void atkD0_settaunt(void) +{ + if (gDisableStructs[gBankTarget].tauntTimer1 == 0) + { + gDisableStructs[gBankTarget].tauntTimer1 = 2; + gDisableStructs[gBankTarget].tauntTimer2 = 2; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkD1_set_helpinghand(void) +{ + gBankTarget = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !(gAbsentBankFlags & gBitTable[gBankTarget]) + && !gProtectStructs[gBankAttacker].helpingHand + && !gProtectStructs[gBankTarget].helpingHand) + { + gProtectStructs[gBankTarget].helpingHand = 1; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkD2_swap_items(void) // trick +{ + // opponent can't swap items with player in regular battles + if (gBattleTypeFlags & BATTLE_TYPE_x4000000 + || (GetBankSide(gBankAttacker) == SIDE_OPPONENT + && !(gBattleTypeFlags & (BATTLE_TYPE_LINK + | BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_SECRET_BASE + | BATTLE_TYPE_x2000000)))) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + u8 sideAttacker = GetBankSide(gBankAttacker); + u8 sideTarget = GetBankSide(gBankTarget); + + // you can't swap items if they were knocked off in regular battles + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK + | BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_SECRET_BASE + | BATTLE_TYPE_x2000000)) + && (gWishFutureKnock.knockedOffPokes[sideAttacker] & gBitTable[gBattlePartyID[gBankAttacker]] + || gWishFutureKnock.knockedOffPokes[sideTarget] & gBitTable[gBattlePartyID[gBankTarget]])) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + // can't swap if two pokemon don't have an item + // or if either of them is an enigma berry or a mail + else if ((gBattleMons[gBankAttacker].item == 0 && gBattleMons[gBankTarget].item == 0) + || gBattleMons[gBankAttacker].item == ITEM_ENIGMA_BERRY + || gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY + || IS_ITEM_MAIL(gBattleMons[gBankAttacker].item) + || IS_ITEM_MAIL(gBattleMons[gBankTarget].item)) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + // check if ability prevents swapping + else if (gBattleMons[gBankTarget].ability == ABILITY_STICKY_HOLD) + { + gBattlescriptCurrInstr = BattleScript_StickyHoldActivates; + gLastUsedAbility = gBattleMons[gBankTarget].ability; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + // took a while, but all checks passed and items can be safely swapped + else + { + u16 oldItemAtk, *newItemAtk; + + newItemAtk = &gBattleStruct->changedItems[gBankAttacker]; + oldItemAtk = gBattleMons[gBankAttacker].item; + *newItemAtk = gBattleMons[gBankTarget].item; + + gBattleMons[gBankAttacker].item = 0; + gBattleMons[gBankTarget].item = oldItemAtk; + + gActiveBank = gBankAttacker; + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, newItemAtk); + MarkBufferBankForExecution(gBankAttacker); + + gActiveBank = gBankTarget; + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); + MarkBufferBankForExecution(gBankTarget); + + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 0) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 1) = 0; + + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankAttacker]) + 0) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankAttacker]) + 1) = 0; + + gBattlescriptCurrInstr += 5; + + PREPARE_ITEM_BUFFER(gBattleTextBuff1, *newItemAtk) + PREPARE_ITEM_BUFFER(gBattleTextBuff2, oldItemAtk) + + if (oldItemAtk != 0 && *newItemAtk != 0) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; // attacker's item -> <- target's item + else if (oldItemAtk == 0 && *newItemAtk != 0) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; // nothing -> <- target's item + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; // attacker's item -> <- nothing + } + } +} + +void atkD3_copy_ability(void) // role play +{ + if (gBattleMons[gBankTarget].ability != 0 + && gBattleMons[gBankTarget].ability != ABILITY_WONDER_GUARD) + { + gBattleMons[gBankAttacker].ability = gBattleMons[gBankTarget].ability; + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkD4_wish_effect(void) +{ + switch (BSScriptRead8(gBattlescriptCurrInstr + 1)) + { + case 0: // use wish + if (gWishFutureKnock.wishCounter[gBankAttacker] == 0) + { + gWishFutureKnock.wishCounter[gBankAttacker] = 2; + gWishFutureKnock.wishUserID[gBankAttacker] = gBattlePartyID[gBankAttacker]; + gBattlescriptCurrInstr += 6; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + } + break; + case 1: // heal effect + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBankTarget, gWishFutureKnock.wishUserID[gBankTarget]) + + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + + if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + + break; + } +} + +void atkD5_setroots(void) // ingrain +{ + if (gStatuses3[gBankAttacker] & STATUS3_ROOTED) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gStatuses3[gBankAttacker] |= STATUS3_ROOTED; + gBattlescriptCurrInstr += 5; + } +} + +void atkD6_doubledamagedealtifdamaged(void) +{ + if ((gProtectStructs[gBankAttacker].physicalDmg + && gProtectStructs[gBankAttacker].physicalBank == gBankTarget) + || (gProtectStructs[gBankAttacker].specialDmg + && gProtectStructs[gBankAttacker].specialBank == gBankTarget)) + { + gBattleScripting.dmgMultiplier = 2; + } + + gBattlescriptCurrInstr++; +} + +void atkD7_setyawn(void) +{ + if (gStatuses3[gBankTarget] & STATUS3_YAWN + || gBattleMons[gBankTarget].status1 & STATUS_ANY) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gStatuses3[gBankTarget] |= 0x1000; + gBattlescriptCurrInstr += 5; + } +} + +void atkD8_setdamagetohealthdifference(void) +{ + if (gBattleMons[gBankTarget].hp <= gBattleMons[gBankAttacker].hp) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMoveDamage = gBattleMons[gBankTarget].hp - gBattleMons[gBankAttacker].hp; + gBattlescriptCurrInstr += 5; + } +} + +void atkD9_scaledamagebyhealthratio(void) +{ + if (gDynamicBasePower == 0) + { + u8 power = gBattleMoves[gCurrentMove].power; + gDynamicBasePower = gBattleMons[gBankAttacker].hp * power / gBattleMons[gBankAttacker].maxHP; + if (gDynamicBasePower == 0) + gDynamicBasePower = 1; + } + gBattlescriptCurrInstr++; +} + +void atkDA_abilityswap(void) // skill swap +{ + if ((gBattleMons[gBankAttacker].ability == 0 + && gBattleMons[gBankTarget].ability == 0) + || gBattleMons[gBankAttacker].ability == ABILITY_WONDER_GUARD + || gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD + || gBattleMoveFlags & MOVESTATUS_NOEFFECT) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + u8 abilityAtk = gBattleMons[gBankAttacker].ability; + gBattleMons[gBankAttacker].ability = gBattleMons[gBankTarget].ability; + gBattleMons[gBankTarget].ability = abilityAtk; + + gBattlescriptCurrInstr += 5; + } +} + +void atkDB_imprisoneffect(void) +{ + if ((gStatuses3[gBankAttacker] & STATUS3_IMPRISONED_OTHERS)) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + u8 bank, sideAttacker; + + sideAttacker = GetBankSide(gBankAttacker); + PressurePPLoseOnUsingImprision(gBankAttacker); + for (bank = 0; bank < gNoOfAllBanks; bank++) + { + if (sideAttacker != GetBankSide(bank)) + { + s32 attackerMoveId; + for (attackerMoveId = 0; attackerMoveId < 4; attackerMoveId++) + { + s32 i; + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankAttacker].moves[attackerMoveId] == gBattleMons[bank].moves[i] + && gBattleMons[gBankAttacker].moves[attackerMoveId] != MOVE_NONE) + break; + } + if (i != 4) + break; + } + if (attackerMoveId != 4) + { + gStatuses3[gBankAttacker] |= STATUS3_IMPRISONED_OTHERS; + gBattlescriptCurrInstr += 5; + break; + } + } + } + if (bank == gNoOfAllBanks) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkDC_setgrudge(void) +{ + if (gStatuses3[gBankAttacker] & STATUS3_GRUDGE) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gStatuses3[gBankAttacker] |= STATUS3_GRUDGE; + gBattlescriptCurrInstr += 5; + } +} + +void atkDD_weightdamagecalculation(void) +{ + s32 i; + for (i = 0; sWeightToDamageTable[i] != 0xFFFF; i += 2) + { + if (sWeightToDamageTable[i] > GetPokedexHeightWeight(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 1)) + break; + } + + if (sWeightToDamageTable[i] != 0xFFFF) + gDynamicBasePower = sWeightToDamageTable[i + 1]; + else + gDynamicBasePower = 120; + + gBattlescriptCurrInstr++; +} + +void atkDE_asistattackselect(void) +{ + s32 chooseableMovesNo = 0; + struct Pokemon* party; + s32 monId, moveId; + u16* movesArray = gBattleStruct->assistPossibleMoves; + + if (GET_BANK_SIDE(gBankAttacker) != SIDE_PLAYER) + party = gEnemyParty; + else + party = gPlayerParty; + + for (monId = 0; monId < 6; monId++) + { + if (monId == gBattlePartyID[gBankAttacker]) + continue; + if (GetMonData(&party[monId], MON_DATA_SPECIES2) == SPECIES_NONE) + continue; + if (GetMonData(&party[monId], MON_DATA_SPECIES2) == SPECIES_EGG) + continue; + + for (moveId = 0; moveId < 4; moveId++) + { + s32 i = 0; + u16 move = GetMonData(&party[monId], MON_DATA_MOVE1 + moveId); + + if (IsInvalidForSleepTalkOrAssist(move)) + continue; + + for (; gMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END && move != gMovesForbiddenToCopy[i]; i++); + + if (gMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END) + continue; + if (move == MOVE_NONE) + continue; + + movesArray[chooseableMovesNo] = move; + chooseableMovesNo++; + } + } + if (chooseableMovesNo) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gRandomMove = movesArray[((Random() & 0xFF) * chooseableMovesNo) >> 8]; + gBankTarget = GetMoveTarget(gRandomMove, 0); + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +void atkDF_setmagiccoat(void) +{ + gBankTarget = gBankAttacker; + gSpecialStatuses[gBankAttacker].flag20 = 1; + if (gCurrentMoveTurn == gNoOfAllBanks - 1) // moves last turn + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gProtectStructs[gBankAttacker].bounceMove = 1; + gBattlescriptCurrInstr += 5; + } +} + +void atkE0_setstealstatchange(void) // snatch +{ + gSpecialStatuses[gBankAttacker].flag20 = 1; + if (gCurrentMoveTurn == gNoOfAllBanks - 1) // moves last turn + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gProtectStructs[gBankAttacker].stealMove = 1; + gBattlescriptCurrInstr += 5; + } +} + +void atkE1_intimidate_string_loader(void) +{ + u8 side; + + gBattleScripting.bank = gBattleStruct->intimidateBank; + side = GetBankSide(gBattleScripting.bank); + + PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gBattleMons[gBattleScripting.bank].ability) + + for (;gBankTarget < gNoOfAllBanks; gBankTarget++) + { + if (GetBankSide(gBankTarget) == side) + continue; + if (!(gAbsentBankFlags & gBitTable[gBankTarget])) + break; + } + + if (gBankTarget >= gNoOfAllBanks) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; +} + +void atkE2_switchout_abilities(void) +{ + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + switch (gBattleMons[gActiveBank].ability) + { + case ABILITY_NATURAL_CURE: + gBattleMons[gActiveBank].status1 = 0; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBank)], 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + break; + } + + gBattlescriptCurrInstr += 2; +} + +void atkE3_jumpifhasnohp(void) +{ + gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + + if (gBattleMons[gActiveBank].hp == 0) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; +} + +void atkE4_getsecretpowereffect(void) +{ + switch (gBattleTerrain) + { + case BATTLE_TERRAIN_GRASS: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_POISON; + break; + case BATTLE_TERRAIN_LONG_GRASS: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_SLEEP; + break; + case BATTLE_TERRAIN_SAND: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_ACC_MINUS_1; + break; + case BATTLE_TERRAIN_UNDERWATER: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_DEF_MINUS_1; + break; + case BATTLE_TERRAIN_WATER: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_ATK_MINUS_1; + break; + case BATTLE_TERRAIN_POND: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_SPD_MINUS_1; + break; + case BATTLE_TERRAIN_ROCK: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_CONFUSION; + break; + case BATTLE_TERRAIN_CAVE: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_FLINCH; + break; + default: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_PARALYSIS; + break; + } + gBattlescriptCurrInstr++; +} + +extern bool8 InBattlePike(void); +extern bool8 InBattlePyramid(void); +extern u16 GetBattlePyramidPickupItemId(void); + +extern const u16 gRarePickupItems[]; +extern const u16 gPickupItems[]; +extern const u8 gPickupProbabilities[]; + +void atkE5_pickup(void) +{ + if (!InBattlePike()) + { + s32 i; + u16 species, heldItem; + u8 ability; + + if (InBattlePyramid()) + { + for (i = 0; i < 6; i++) + { + species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); + heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + + if (GetMonData(&gPlayerParty[i], MON_DATA_ALT_ABILITY)) + ability = gBaseStats[species].ability2; + else + ability = gBaseStats[species].ability1; + + if (ability == ABILITY_PICKUP + && species != 0 + && species != SPECIES_EGG + && heldItem == ITEM_NONE + && (Random() % 10) == 0) + { + heldItem = GetBattlePyramidPickupItemId(); + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &heldItem); + } + } + } + else + { + for (i = 0; i < 6; i++) + { + species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); + heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + + if (GetMonData(&gPlayerParty[i], MON_DATA_ALT_ABILITY)) + ability = gBaseStats[species].ability2; + else + ability = gBaseStats[species].ability1; + + if (ability == ABILITY_PICKUP + && species != 0 + && species != SPECIES_EGG + && heldItem == ITEM_NONE + && (Random() % 10) == 0) + { + s32 j; + s32 rand = Random() % 100; + u8 lvlDivBy10 = (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL) - 1) / 10; + if (lvlDivBy10 > 9) + lvlDivBy10 = 9; + + for (j = 0; j < 9; j++) + { + if (gPickupProbabilities[j] > rand) + { + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &gPickupItems[lvlDivBy10 + j]); + break; + } + else if (rand == 99 || rand == 98) + { + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &gRarePickupItems[lvlDivBy10 + (99 - rand)]); + break; + } + } + } + } + } + } + + gBattlescriptCurrInstr++; +} diff --git a/src/pokemon_3.c b/src/pokemon_3.c index d381c7544..d44c0cb2f 100644 --- a/src/pokemon_3.c +++ b/src/pokemon_3.c @@ -1361,20 +1361,20 @@ void BoxMonRestorePP(struct BoxPokemon *boxMon) void sub_806E994(void) { gLastUsedAbility = gBattleStruct->field_B0; - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 4; + + gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN; + gBattleTextBuff1[1] = B_BUFF_MON_NICK_WITH_PREFIX; gBattleTextBuff1[2] = gBattleStruct->field_49; - gBattleTextBuff1[4] = EOS; + gBattleTextBuff1[4] = B_BUFF_EOS; + if (!GetBankSide(gBattleStruct->field_49)) gBattleTextBuff1[3] = pokemon_order_func(gBattlePartyID[gBattleStruct->field_49]); else gBattleTextBuff1[3] = gBattlePartyID[gBattleStruct->field_49]; - gBattleTextBuff2[0] = 0xFD; - gBattleTextBuff2[1] = 4; - gBattleTextBuff2[2] = gBankInMenu; - gBattleTextBuff2[3] = pokemon_order_func(gBattlePartyID[gBankInMenu]); - gBattleTextBuff2[4] = EOS; - BattleStringExpandPlaceholders(gText_PkmnsXPreventsSwitching, gStringVar4); + + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff2, gBankInMenu, pokemon_order_func(gBattlePartyID[gBankInMenu])) + + BattleStringExpandPlaceholders(gText_PkmnsXPreventsSwitching, gStringVar4); } struct PokeItem @@ -1388,7 +1388,7 @@ extern const struct PokeItem gAlteringCaveWildMonHeldItems[9]; static s32 GetWildMonTableIdInAlteringCave(u16 species) { s32 i; - for (i = 0; i < 9; i++) + for (i = 0; i < (s32) ARRAY_COUNT(gAlteringCaveWildMonHeldItems); i++) if (gAlteringCaveWildMonHeldItems[i].species == species) return i; return 0; -- cgit v1.2.3 From bc3b4b4d9ae6ab59c9ce3892b7d287ebd0ee13fa Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 28 Sep 2017 15:34:21 +0200 Subject: battle 4 commands are decompiled --- src/battle_3.c | 172 +++--- src/battle_4.c | 1890 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 1331 insertions(+), 731 deletions(-) (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index 9ac439390..e81d527d0 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -179,13 +179,9 @@ extern const u8 gStatusConditionString_ConfusionJpn[]; extern const u8 gStatusConditionString_LoveJpn[]; extern const u16 gSoundMovesTable[]; -extern void CancelMultiTurnMoves(u8 bank); extern u8 b_first_side(u8, u8, u8); extern void sub_803CEDC(u8, u8); -extern void b_call_bc_move_exec(const u8 *); extern void BattleTurnPassed(void); -extern void SetMoveEffect(bool8 primary, u8 certainArg); -extern bool8 UproarWakeUpCheck(u8 bank); extern void sub_803F9EC(); extern bool8 sub_80423F4(u8 bank, u8, u8); extern u8 weather_get_current(void); @@ -441,7 +437,7 @@ u8 UpdateTurnCounters(void) if (--gSideTimers[sideBank].reflectTimer == 0) { gSideAffecting[sideBank] &= ~SIDE_STATUS_REFLECT; - b_call_bc_move_exec(gUnknown_082DACFA); + BattleScriptExecute(gUnknown_082DACFA); gBattleTextBuff1[0] = 0xFD; gBattleTextBuff1[1] = 2; gBattleTextBuff1[2] = MOVE_REFLECT; @@ -470,7 +466,7 @@ u8 UpdateTurnCounters(void) if (--gSideTimers[sideBank].lightscreenTimer == 0) { gSideAffecting[sideBank] &= ~SIDE_STATUS_LIGHTSCREEN; - b_call_bc_move_exec(gUnknown_082DACFA); + BattleScriptExecute(gUnknown_082DACFA); gBattleCommunication[MULTISTRING_CHOOSER] = sideBank; gBattleTextBuff1[0] = 0xFD; gBattleTextBuff1[1] = 2; @@ -499,7 +495,7 @@ u8 UpdateTurnCounters(void) && --gSideTimers[sideBank].mistTimer == 0) { gSideAffecting[sideBank] &= ~SIDE_STATUS_MIST; - b_call_bc_move_exec(gUnknown_082DACFA); + BattleScriptExecute(gUnknown_082DACFA); gBattleCommunication[MULTISTRING_CHOOSER] = sideBank; gBattleTextBuff1[0] = 0xFD; gBattleTextBuff1[1] = 2; @@ -528,7 +524,7 @@ u8 UpdateTurnCounters(void) if (--gSideTimers[sideBank].safeguardTimer == 0) { gSideAffecting[sideBank] &= ~SIDE_STATUS_SAFEGUARD; - b_call_bc_move_exec(gUnknown_082DAD0B); + BattleScriptExecute(gUnknown_082DAD0B); effect++; } } @@ -551,7 +547,7 @@ u8 UpdateTurnCounters(void) && gBattleMons[gActiveBank].hp != 0) { gBankTarget = gActiveBank; - b_call_bc_move_exec(BattleScript_WishComesTrue); + BattleScriptExecute(BattleScript_WishComesTrue); effect++; } gBattleStruct->turnSideTracker++; @@ -583,7 +579,7 @@ u8 UpdateTurnCounters(void) gBattleCommunication[MULTISTRING_CHOOSER] = 1; else gBattleCommunication[MULTISTRING_CHOOSER] = 0; - b_call_bc_move_exec(gUnknown_082DAC2C); + BattleScriptExecute(gUnknown_082DAC2C); effect++; } gBattleStruct->turncountersTracker++; @@ -601,7 +597,7 @@ u8 UpdateTurnCounters(void) gBattleScripting.animArg1 = 0xC; gBattleCommunication[MULTISTRING_CHOOSER] = 0; - b_call_bc_move_exec(gBattlescriptCurrInstr); + BattleScriptExecute(gBattlescriptCurrInstr); effect++; } gBattleStruct->turncountersTracker++; @@ -617,7 +613,7 @@ u8 UpdateTurnCounters(void) else gBattlescriptCurrInstr = gUnknown_082DACD2; - b_call_bc_move_exec(gBattlescriptCurrInstr); + BattleScriptExecute(gBattlescriptCurrInstr); effect++; } gBattleStruct->turncountersTracker++; @@ -635,7 +631,7 @@ u8 UpdateTurnCounters(void) gBattleScripting.animArg1 = 0xD; gBattleCommunication[MULTISTRING_CHOOSER] = 1; - b_call_bc_move_exec(gBattlescriptCurrInstr); + BattleScriptExecute(gBattlescriptCurrInstr); effect++; } gBattleStruct->turncountersTracker++; @@ -675,7 +671,7 @@ u8 TurnBasedEffects(void) if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; gBattleMoveDamage *= -1; - b_call_bc_move_exec(BattleScript_IngrainTurnHeal); + BattleScriptExecute(BattleScript_IngrainTurnHeal); effect++; } gBattleStruct->turnEffectsTracker++; @@ -706,7 +702,7 @@ u8 TurnBasedEffects(void) gBattleMoveDamage = 1; gBattleScripting.animArg1 = gBankTarget; gBattleScripting.animArg2 = gBankAttacker; - b_call_bc_move_exec(BattleScript_LeechSeedTurnDrain); + BattleScriptExecute(BattleScript_LeechSeedTurnDrain); effect++; } gBattleStruct->turnEffectsTracker++; @@ -717,7 +713,7 @@ u8 TurnBasedEffects(void) gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_call_bc_move_exec(BattleScript_PoisonTurnDmg); + BattleScriptExecute(BattleScript_PoisonTurnDmg); effect++; } gBattleStruct->turnEffectsTracker++; @@ -731,7 +727,7 @@ u8 TurnBasedEffects(void) if ((gBattleMons[gActiveBank].status1 & 0xF00) != 0xF00) //not 16 turns gBattleMons[gActiveBank].status1 += 0x100; gBattleMoveDamage *= (gBattleMons[gActiveBank].status1 & 0xF00) >> 8; - b_call_bc_move_exec(BattleScript_PoisonTurnDmg); + BattleScriptExecute(BattleScript_PoisonTurnDmg); effect++; } gBattleStruct->turnEffectsTracker++; @@ -742,7 +738,7 @@ u8 TurnBasedEffects(void) gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_call_bc_move_exec(BattleScript_BurnTurnDmg); + BattleScriptExecute(BattleScript_BurnTurnDmg); effect++; } gBattleStruct->turnEffectsTracker++; @@ -757,7 +753,7 @@ u8 TurnBasedEffects(void) gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 4; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_call_bc_move_exec(BattleScript_NightmareTurnDmg); + BattleScriptExecute(BattleScript_NightmareTurnDmg); effect++; } else @@ -773,7 +769,7 @@ u8 TurnBasedEffects(void) gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 4; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_call_bc_move_exec(BattleScript_CurseTurnDmg); + BattleScriptExecute(BattleScript_CurseTurnDmg); effect++; } gBattleStruct->turnEffectsTracker++; @@ -806,7 +802,7 @@ u8 TurnBasedEffects(void) gBattleTextBuff1[4] = EOS; gBattlescriptCurrInstr = BattleScript_WrapEnds; } - b_call_bc_move_exec(gBattlescriptCurrInstr); + BattleScriptExecute(gBattlescriptCurrInstr); effect++; } gBattleStruct->turnEffectsTracker++; @@ -822,7 +818,7 @@ u8 TurnBasedEffects(void) gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); gBattleCommunication[MULTISTRING_CHOOSER] = 1; - b_call_bc_move_exec(gUnknown_082DB234); + BattleScriptExecute(gUnknown_082DB234); gActiveBank = gBankAttacker; EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); @@ -853,7 +849,7 @@ u8 TurnBasedEffects(void) gBattleCommunication[MULTISTRING_CHOOSER] = 1; CancelMultiTurnMoves(gActiveBank); } - b_call_bc_move_exec(gUnknown_082DB2A6); + BattleScriptExecute(gUnknown_082DB2A6); effect = 1; } } @@ -875,7 +871,7 @@ u8 TurnBasedEffects(void) gBattleCommunication[MOVE_EFFECT_BYTE] = 0x47; SetMoveEffect(1, 0); if (gBattleMons[gActiveBank].status2 & STATUS2_CONFUSION) - b_call_bc_move_exec(BattleScript_ThrashConfuses); + BattleScriptExecute(BattleScript_ThrashConfuses); effect++; } } @@ -899,7 +895,7 @@ u8 TurnBasedEffects(void) else if (--gDisableStructs[gActiveBank].disableTimer1 == 0) // disable ends { gDisableStructs[gActiveBank].disabledMove = 0; - b_call_bc_move_exec(BattleScript_DisabledNoMore); + BattleScriptExecute(BattleScript_DisabledNoMore); effect++; } } @@ -918,7 +914,7 @@ u8 TurnBasedEffects(void) { gDisableStructs[gActiveBank].encoredMove = 0; gDisableStructs[gActiveBank].encoreTimer1 = 0; - b_call_bc_move_exec(BattleScript_EncoredNoMore); + BattleScriptExecute(BattleScript_EncoredNoMore); effect++; } } @@ -952,7 +948,7 @@ u8 TurnBasedEffects(void) EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); gEffectBank = gActiveBank; - b_call_bc_move_exec(BattleScript_YawnMakesAsleep); + BattleScriptExecute(BattleScript_YawnMakesAsleep); effect++; } } @@ -1006,7 +1002,7 @@ bool8 sub_8041364(void) gBankAttacker = gWishFutureKnock.futureSightAttacker[gActiveBank]; gBattleMoveDamage = gWishFutureKnock.futureSightDmg[gActiveBank]; gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF; - b_call_bc_move_exec(gUnknown_082DAFE4); + BattleScriptExecute(gUnknown_082DAFE4); if (gWishFutureKnock.futureSightCounter[gActiveBank] == 0 && gWishFutureKnock.futureSightCounter[gActiveBank ^ 2] == 0) @@ -1052,7 +1048,7 @@ bool8 sub_8041364(void) gDisableStructs[gActiveBank].perishSong1--; gBattlescriptCurrInstr = gUnknown_082DAF20; } - b_call_bc_move_exec(gBattlescriptCurrInstr); + BattleScriptExecute(gBattlescriptCurrInstr); return 1; } } @@ -1074,7 +1070,7 @@ bool8 sub_8041364(void) CancelMultiTurnMoves(i); gBattlescriptCurrInstr = gUnknown_082DB8F3; - b_call_bc_move_exec(gUnknown_082DB8F3); + BattleScriptExecute(gUnknown_082DB8F3); gBattleStruct->field_1A0++; return 1; } @@ -1114,7 +1110,7 @@ bool8 sub_8041728(void) && !(gBattleStruct->field_DF & gBitTable[gBattlePartyID[gBattleStruct->field_4E]]) && !(gAbsentBankFlags & gBitTable[gBattleStruct->field_4E])) { - b_call_bc_move_exec(gUnknown_082DA7C4); + BattleScriptExecute(gUnknown_082DA7C4); gBattleStruct->field_4D = 2; return TRUE; } @@ -1139,7 +1135,7 @@ bool8 sub_8041728(void) if (gBattleMons[gBattleStruct->field_4E].hp == 0 && !(gAbsentBankFlags & gBitTable[gBattleStruct->field_4E])) { - b_call_bc_move_exec(gUnknown_082DA7CD); + BattleScriptExecute(gUnknown_082DA7CD); gBattleStruct->field_4D = 5; return TRUE; } @@ -1709,7 +1705,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) if (effect) { gBattleCommunication[MULTISTRING_CHOOSER] = weather_get_current(); - b_push_move_exec(gUnknown_082DACE7); + BattleScriptPushCursorAndCallback(gUnknown_082DACE7); } break; case ABILITY_DRIZZLE: @@ -1717,7 +1713,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)) { gBattleWeather = (WEATHER_RAIN_PERMANENT | WEATHER_RAIN_TEMPORARY); - b_push_move_exec(BattleScript_DrizzleActivates); + BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates); gBattleScripting.bank = bank; effect++; } @@ -1727,7 +1723,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT)) { gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY); - b_push_move_exec(BattleScript_SandstreamActivates); + BattleScriptPushCursorAndCallback(BattleScript_SandstreamActivates); gBattleScripting.bank = bank; effect++; } @@ -1737,7 +1733,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) if (!(gBattleWeather & WEATHER_SUN_PERMANENT)) { gBattleWeather = (WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY); - b_push_move_exec(BattleScript_DroughtActivates); + BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates); gBattleScripting.bank = bank; effect++; } @@ -1755,7 +1751,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) effect = CastformDataTypeChange(bank); if (effect != 0) { - b_push_move_exec(BattleScript_CastformChange); + BattleScriptPushCursorAndCallback(BattleScript_CastformChange); gBattleScripting.bank = bank; gBattleStruct->formToChangeInto = effect - 1; } @@ -1779,7 +1775,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) effect = CastformDataTypeChange(i); if (effect != 0) { - b_push_move_exec(BattleScript_CastformChange); + BattleScriptPushCursorAndCallback(BattleScript_CastformChange); gBattleScripting.bank = i; gBattleStruct->formToChangeInto = effect - 1; break; @@ -1802,7 +1798,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) && gBattleMons[bank].maxHP > gBattleMons[bank].hp) { gLastUsedAbility = ABILITY_RAIN_DISH; //why - b_push_move_exec(BattleScript_RainDishActivates); + BattleScriptPushCursorAndCallback(BattleScript_RainDishActivates); gBattleMoveDamage = gBattleMons[bank].maxHP / 16; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; @@ -1827,7 +1823,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattleMons[bank].status1 = 0; gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); // fix nighmare glitch gBattleScripting.bank = gActiveBank = bank; - b_push_move_exec(BattleScript_ShedSkinActivates); + BattleScriptPushCursorAndCallback(BattleScript_ShedSkinActivates); EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); MarkBufferBankForExecution(gActiveBank); effect++; @@ -1840,7 +1836,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) gBattleMons[bank].statStages[STAT_STAGE_SPEED]++; gBattleScripting.animArg1 = 0x11; gBattleScripting.animArg2 = 0; - b_push_move_exec(BattleScript_SpeedBoostActivates); + BattleScriptPushCursorAndCallback(BattleScript_SpeedBoostActivates); gBattleScripting.bank = bank; effect++; } @@ -2167,7 +2163,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) effect = CastformDataTypeChange(i); if (effect) { - b_push_move_exec(BattleScript_CastformChange); + BattleScriptPushCursorAndCallback(BattleScript_CastformChange); gBattleScripting.bank = i; gBattleStruct->formToChangeInto = effect - 1; return effect; @@ -2215,7 +2211,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) { gLastUsedAbility = ABILITY_INTIMIDATE; gStatuses3[i] &= ~(STATUS3_INTIMIDATE_POKES); - b_push_move_exec(gUnknown_082DB4B8); + BattleScriptPushCursorAndCallback(gUnknown_082DB4B8); gBattleStruct->intimidateBank = i; effect++; break; @@ -2267,7 +2263,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) } if (effect) { - b_push_move_exec(BattleScript_TraceActivates); + BattleScriptPushCursorAndCallback(BattleScript_TraceActivates); gStatuses3[i] &= ~(STATUS3_TRACE); gBattleScripting.bank = i; @@ -2774,7 +2770,7 @@ _08042B56:\n\ ldr r1, =gBattleCommunication\n\ strb r0, [r1, 0x5]\n\ ldr r0, =gUnknown_082DACE7\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ bl _0804441E\n\ .pool\n\ _08042B78:\n\ @@ -2789,7 +2785,7 @@ _08042B88:\n\ movs r0, 0x5\n\ strh r0, [r2]\n\ ldr r0, =BattleScript_DrizzleActivates\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ ldr r0, =gBattleScripting\n\ mov r1, r10\n\ strb r1, [r0, 0x17]\n\ @@ -2807,7 +2803,7 @@ _08042BB8:\n\ movs r0, 0x18\n\ strh r0, [r2]\n\ ldr r0, =BattleScript_SandstreamActivates\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ ldr r0, =gBattleScripting\n\ mov r2, r10\n\ strb r2, [r0, 0x17]\n\ @@ -2825,7 +2821,7 @@ _08042BE8:\n\ movs r0, 0x60\n\ strh r0, [r2]\n\ ldr r0, =BattleScript_DroughtActivates\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ ldr r0, =gBattleScripting\n\ mov r3, r10\n\ strb r3, [r0, 0x17]\n\ @@ -2866,7 +2862,7 @@ _08042C3C:\n\ bl _0804443A\n\ _08042C50:\n\ ldr r0, =BattleScript_CastformChange\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ ldr r0, =gBattleScripting\n\ mov r1, r10\n\ strb r1, [r0, 0x17]\n\ @@ -2999,7 +2995,7 @@ _08042D66:\n\ _08042D72:\n\ strb r5, [r7]\n\ ldr r0, =BattleScript_RainDishActivates\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ ldr r1, =gBattleMoveDamage\n\ ldrh r0, [r4, 0x2C]\n\ lsrs r0, 4\n\ @@ -3093,7 +3089,7 @@ _08042E24:\n\ strb r3, [r4]\n\ strb r3, [r0, 0x17]\n\ ldr r0, =BattleScript_ShedSkinActivates\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ str r5, [sp]\n\ movs r0, 0\n\ movs r1, 0x28\n\ @@ -3131,7 +3127,7 @@ _08042EA8:\n\ strb r0, [r4, 0x10]\n\ strb r1, [r4, 0x11]\n\ ldr r0, =BattleScript_SpeedBoostActivates\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ strb r5, [r4, 0x17]\n\ bl _080443D0\n\ .pool\n\ @@ -5288,7 +5284,7 @@ _080442C0:\n\ .pool\n\ _080442D8:\n\ ldr r0, =BattleScript_CastformChange\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ ldr r0, =gBattleScripting\n\ strb r6, [r0, 0x17]\n\ _080442E2:\n\ @@ -5302,7 +5298,7 @@ _080442E2:\n\ .pool\n\ _080442FC:\n\ ldr r0, =BattleScript_CastformChange\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ ldr r0, =gBattleScripting\n\ mov r5, r10\n\ strb r5, [r0, 0x17]\n\ @@ -5321,12 +5317,12 @@ _08044324:\n\ ands r0, r1\n\ str r0, [r2]\n\ ldr r0, =gUnknown_082DB4B8\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ b _080443C8\n\ .pool\n\ _08044340:\n\ ldr r0, =BattleScript_TraceActivates\n\ - bl b_push_move_exec\n\ + bl BattleScriptPushCursorAndCallback\n\ ldr r1, =gStatuses3\n\ ldr r0, [sp, 0x18]\n\ adds r1, r0, r1\n\ @@ -5445,7 +5441,7 @@ _0804443A:\n\ } #endif // NONMATCHING -void b_call_bc_move_exec(const u8* BS_ptr) +void BattleScriptExecute(const u8* BS_ptr) { gBattlescriptCurrInstr = BS_ptr; BATTLE_CALLBACKS_STACK->function[BATTLE_CALLBACKS_STACK->size++] = gBattleMainFunc; @@ -5453,7 +5449,7 @@ void b_call_bc_move_exec(const u8* BS_ptr) gFightStateTracker = 0; } -void b_push_move_exec(const u8* BS_ptr) +void BattleScriptPushCursorAndCallback(const u8* BS_ptr) { BattleScriptPushCursor(); gBattlescriptCurrInstr = BS_ptr; @@ -5549,7 +5545,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleScripting.bank = bank; gStringBank = bank; gActiveBank = gBankAttacker = bank; - b_call_bc_move_exec(BattleScript_WhiteHerbEnd2); + BattleScriptExecute(BattleScript_WhiteHerbEnd2); } break; } @@ -5566,7 +5562,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].hp + bankQuality > gBattleMons[bank].maxHP) gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; gBattleMoveDamage *= -1; - b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); effect = 4; } break; @@ -5601,7 +5597,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleTextBuff1[2] = move; gBattleTextBuff1[3] = move >> 8; gBattleTextBuff1[4] = 0xFF; - b_call_bc_move_exec(BattleScript_BerryPPHealEnd2); + BattleScriptExecute(BattleScript_BerryPPHealEnd2); EmitSetMonData(0, i + REQUEST_PPMOVE1_BATTLE, 0, 1, &changedPP); MarkBufferBankForExecution(gActiveBank); effect = ITEM_PP_CHANGE; @@ -5622,7 +5618,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleScripting.bank = bank; gStringBank = bank; gActiveBank = gBankAttacker = bank; - b_call_bc_move_exec(BattleScript_WhiteHerbEnd2); + BattleScriptExecute(BattleScript_WhiteHerbEnd2); } break; case HOLD_EFFECT_LEFTOVERS: @@ -5634,7 +5630,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; gBattleMoveDamage *= -1; - b_call_bc_move_exec(BattleScript_ItemHealHP_End2); + BattleScriptExecute(BattleScript_ItemHealHP_End2); effect = ITEM_HP_CHANGE; RecordItemEffectBattle(bank, bankHoldEffect); } @@ -5654,9 +5650,9 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; gBattleMoveDamage *= -1; if (GetFlavourRelationByPersonality(gBattleMons[bank].personality, FLAVOR_SPICY) < 0) - b_call_bc_move_exec(BattleScript_BerryConfuseHealEnd2); + BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); else - b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); effect = ITEM_HP_CHANGE; } break; @@ -5674,9 +5670,9 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; gBattleMoveDamage *= -1; if (GetFlavourRelationByPersonality(gBattleMons[bank].personality, FLAVOR_DRY) < 0) - b_call_bc_move_exec(BattleScript_BerryConfuseHealEnd2); + BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); else - b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); effect = ITEM_HP_CHANGE; } break; @@ -5694,9 +5690,9 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; gBattleMoveDamage *= -1; if (GetFlavourRelationByPersonality(gBattleMons[bank].personality, FLAVOR_SWEET) < 0) - b_call_bc_move_exec(BattleScript_BerryConfuseHealEnd2); + BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); else - b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); effect = ITEM_HP_CHANGE; } break; @@ -5714,9 +5710,9 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; gBattleMoveDamage *= -1; if (GetFlavourRelationByPersonality(gBattleMons[bank].personality, FLAVOR_BITTER) < 0) - b_call_bc_move_exec(BattleScript_BerryConfuseHealEnd2); + BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); else - b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); effect = ITEM_HP_CHANGE; } break; @@ -5734,9 +5730,9 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; gBattleMoveDamage *= -1; if (GetFlavourRelationByPersonality(gBattleMons[bank].personality, FLAVOR_SOUR) < 0) - b_call_bc_move_exec(BattleScript_BerryConfuseHealEnd2); + BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); else - b_call_bc_move_exec(BattleScript_ItemHealHP_RemoveItem); + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); effect = ITEM_HP_CHANGE; } break; @@ -5759,7 +5755,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleScripting.statChanger = 0x10 + STAT_STAGE_ATK; gBattleScripting.animArg1 = 0xE + STAT_STAGE_ATK; gBattleScripting.animArg2 = 0; - b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } break; @@ -5775,7 +5771,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleScripting.statChanger = 0x10 + STAT_STAGE_DEF; gBattleScripting.animArg1 = 0xE + STAT_STAGE_DEF; gBattleScripting.animArg2 = 0; - b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } break; @@ -5791,7 +5787,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleScripting.statChanger = 0x10 + STAT_STAGE_SPEED; gBattleScripting.animArg1 = 0xE + STAT_STAGE_SPEED; gBattleScripting.animArg2 = 0; - b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } break; @@ -5807,7 +5803,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleScripting.statChanger = 0x10 + STAT_STAGE_SPATK; gBattleScripting.animArg1 = 0xE + STAT_STAGE_SPATK; gBattleScripting.animArg2 = 0; - b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } break; @@ -5823,7 +5819,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleScripting.statChanger = 0x10 + STAT_STAGE_SPDEF; gBattleScripting.animArg1 = 0xE + STAT_STAGE_SPDEF; gBattleScripting.animArg2 = 0; - b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } break; @@ -5831,7 +5827,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && !(gBattleMons[bank].status2 & STATUS2_FOCUS_ENERGY)) { gBattleMons[bank].status2 |= STATUS2_FOCUS_ENERGY; - b_call_bc_move_exec(BattleScript_BerryFocusEnergyEnd2); + BattleScriptExecute(BattleScript_BerryFocusEnergyEnd2); effect = ITEM_EFFECT_OTHER; } break; @@ -5868,7 +5864,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleScripting.statChanger = 0x21 + i; gBattleScripting.animArg1 = 0x21 + i + 6; gBattleScripting.animArg2 = 0; - b_call_bc_move_exec(BattleScript_BerryStatRaiseEnd2); + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } } @@ -5877,7 +5873,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].status1 & STATUS_PARALYSIS) { gBattleMons[bank].status1 &= ~(STATUS_PARALYSIS); - b_call_bc_move_exec(BattleScript_BerryCurePrlzEnd2); + BattleScriptExecute(BattleScript_BerryCurePrlzEnd2); effect = ITEM_STATUS_CHANGE; } break; @@ -5885,7 +5881,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].status1 & STATUS_PSN_ANY) { gBattleMons[bank].status1 &= ~(STATUS_PSN_ANY | STATUS_TOXIC_COUNTER); - b_call_bc_move_exec(BattleScript_BerryCurePsnEnd2); + BattleScriptExecute(BattleScript_BerryCurePsnEnd2); effect = ITEM_STATUS_CHANGE; } break; @@ -5893,7 +5889,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].status1 & STATUS_BURN) { gBattleMons[bank].status1 &= ~(STATUS_BURN); - b_call_bc_move_exec(BattleScript_BerryCureBrnEnd2); + BattleScriptExecute(BattleScript_BerryCureBrnEnd2); effect = ITEM_STATUS_CHANGE; } break; @@ -5901,7 +5897,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].status1 & STATUS_FREEZE) { gBattleMons[bank].status1 &= ~(STATUS_FREEZE); - b_call_bc_move_exec(BattleScript_BerryCureFrzEnd2); + BattleScriptExecute(BattleScript_BerryCureFrzEnd2); effect = ITEM_STATUS_CHANGE; } break; @@ -5910,7 +5906,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) { gBattleMons[bank].status1 &= ~(STATUS_SLEEP); gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); - b_call_bc_move_exec(BattleScript_BerryCureSlpEnd2); + BattleScriptExecute(BattleScript_BerryCureSlpEnd2); effect = ITEM_STATUS_CHANGE; } break; @@ -5918,7 +5914,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) if (gBattleMons[bank].status2 & STATUS2_CONFUSION) { gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); - b_call_bc_move_exec(BattleScript_BerryCureConfusionEnd2); + BattleScriptExecute(BattleScript_BerryCureConfusionEnd2); effect = ITEM_EFFECT_OTHER; } break; @@ -5963,7 +5959,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleCommunication[MULTISTRING_CHOOSER] = 1; gBattleMons[bank].status1 = 0; gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); - b_call_bc_move_exec(BattleScript_BerryCureChosenStatusEnd2); + BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2); effect = ITEM_STATUS_CHANGE; } break; @@ -5972,7 +5968,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) { gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); - b_call_bc_move_exec(BattleScript_BerryCureChosenStatusEnd2); + BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2); gBattleCommunication[MULTISTRING_CHOOSER] = 0; effect = ITEM_EFFECT_OTHER; } diff --git a/src/battle_4.c b/src/battle_4.c index 9ef443b70..33ac48261 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -30,6 +30,10 @@ #include "pokemon_item_effects.h" #include "m4a.h" #include "mail.h" +#include "event_data.h" +#include "pokemon_storage_system.h" +#include "task.h" +#include "naming_screen.h" // variables @@ -98,6 +102,11 @@ extern u16 gLastUsedMovesByBanks[BATTLE_BANKS_COUNT]; extern u16 gTrainerBattleOpponent_A; extern u16 gTrainerBattleOpponent_B; extern u8 gUnknown_020241E9; +extern u16 gBattle_BG1_X; +extern u16 gBattle_BG1_Y; +extern u16 gBattle_BG2_X; +extern u16 gBattle_BG2_Y; +extern u16 gBattle_BG3_X; extern struct MusicPlayerInfo gMPlay_BGM; struct TrainerMoney @@ -130,6 +139,14 @@ extern void sub_81A5D44(void); // battle frontier 2 extern void sub_81B8E80(u8 bank, u8, u8); // party menu extern bool8 sub_81B1250(void); // ? extern u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale); // battle interface +extern bool8 InBattlePike(void); +extern bool8 InBattlePyramid(void); +extern u16 GetBattlePyramidPickupItemId(void); +extern u8 sav1_map_get_light_level(void); +extern u8 sub_813B21C(void); +extern u16 get_unknown_box_id(void); +extern void c2_berry_program_update_menu(void); +extern void sub_8035AA4(void); // BattleScripts extern const u8 BattleScript_MoveEnd[]; @@ -201,13 +218,24 @@ extern const u8 BattleScript_PrintPayDayMoneyString[]; extern const u8 BattleScript_SturdyPreventsOHKO[]; extern const u8 BattleScript_ObliviousPreventsAttraction[]; extern const u8 BattleScript_PauseEffectivenessSoundResultMsgEndMove[]; +extern const u8 BattleScript_CastformChange[]; +extern const u8 BattleScript_TrainerBallBlock[]; +extern const u8 BattleScript_WallyBallThrow[]; +extern const u8 BattleScript_SuccessBallThrow[]; +extern const u8 BattleScript_ShakeBallThrow[]; +extern const u8 BattleScript_PresentDamageTarget[]; +extern const u8 BattleScript_AlreadyAtFullHp[]; +extern const u8 BattleScript_PresentHealTarget[]; +extern const u8 BattleScript_WrapFree[]; +extern const u8 BattleScript_LeechSeedFree[]; +extern const u8 BattleScript_SpikesFree[]; // strings extern const u8 gText_BattleYesNoChoice[]; // read via orr #define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) -#define BSScriptRead8(ptr) (((u8)((ptr)[0]))) +#define BSScriptRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8)) #define BSScriptReadPtr(ptr) ((void *)BSScriptRead32(ptr)) // read via add @@ -220,270 +248,269 @@ extern const u8 gText_BattleYesNoChoice[]; #define TARGET_TURN_DAMAGED (((gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special))) // this file's functions -bool8 IsTwoTurnsMove(u16 move); -void DestinyBondFlagUpdate(void); -u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. +static bool8 IsTwoTurnsMove(u16 move); +static void DestinyBondFlagUpdate(void); +static u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. static void CheckWonderGuardAndLevitate(void); -u8 ChangeStatBuffs(s8 statValue, u8 statId, u8, const u8* BS_ptr); -void sub_8056A3C(u8 arg0, u8 arg1, u8 arg2, u8 arg3, u8 arg4); -bool32 IsMonGettingExpSentOut(void); -void sub_804F17C(void); -bool8 sub_804F1CC(void); -void sub_804F100(void); -void sub_804F144(void); -bool8 sub_804F344(void); -void PutMonIconOnLvlUpBox(void); -void PutLevelAndGenderOnLvlUpBox(void); - -void atk00_attackcanceler(void); -void atk01_accuracycheck(void); -void atk02_attackstring(void); -void atk03_ppreduce(void); -void atk04_critcalc(void); -void atk05_damagecalc1(void); -void atk06_typecalc(void); -void atk07_dmg_adjustment(void); -void atk08_dmg_adjustment2(void); -void atk09_attackanimation(void); -void atk0A_waitanimation(void); -void atk0B_healthbarupdate(void); -void atk0C_datahpupdate(void); -void atk0D_critmessage(void); -void atk0E_effectiveness_sound(void); -void atk0F_resultmessage(void); -void atk10_printstring(void); -void atk11_printstring_playeronly(void); -void atk12_waitmessage(void); -void atk13_printfromtable(void); -void atk14_printfromtable_playeronly(void); -void atk15_seteffectwithchance(void); -void atk16_seteffectprimary(void); -void atk17_seteffectsecondary(void); -void atk18_status_effect_clear(void); -void atk19_faint_pokemon(void); -void atk1A_faint_animation(void); -void atk1B_faint_effects_clear(void); -void atk1C_jumpifstatus(void); -void atk1D_jumpifstatus2(void); -void atk1E_jumpifability(void); -void atk1F_jumpifsideaffecting(void); -void atk20_jumpifstat(void); -void atk21_jumpifstatus3(void); -void atk22_jumpiftype(void); -void atk23_getexp(void); -void atk24(void); -void atk25_move_values_cleanup(void); -void atk26_set_multihit(void); -void atk27_decrement_multihit(void); -void atk28_goto(void); -void atk29_jumpifbyte(void); -void atk2A_jumpifhalfword(void); -void atk2B_jumpifword(void); -void atk2C_jumpifarrayequal(void); -void atk2D_jumpifarraynotequal(void); -void atk2E_setbyte(void); -void atk2F_addbyte(void); -void atk30_subbyte(void); -void atk31_copyarray(void); -void atk32_copyarray_withindex(void); -void atk33_orbyte(void); -void atk34_orhalfword(void); -void atk35_orword(void); -void atk36_bicbyte(void); -void atk37_bichalfword(void); -void atk38_bicword(void); -void atk39_pause(void); -void atk3A_waitstate(void); -void atk3B_healthbar_update(void); -void atk3C_return(void); -void atk3D_end(void); -void atk3E_end2(void); -void atk3F_end3(void); -void atk40_jump_if_move_affected_by_protect(void); -void atk41_call(void); -void atk42_jumpiftype2(void); -void atk43_jumpifabilitypresent(void); -void atk44(void); -void atk45_playanimation(void); -void atk46_playanimation2(void); -void atk47_setgraphicalstatchangevalues(void); -void atk48_playstatchangeanimation(void); -void atk49_moveend(void); -void atk4A_typecalc2(void); -void atk4B_return_atk_to_ball(void); -void atk4C_copy_poke_data(void); -void atk4D_switch_data_update(void); -void atk4E_switchin_anim(void); -void atk4F_jump_if_cannot_switch(void); -void atk50_openpartyscreen(void); -void atk51_switch_handle_order(void); -void atk52_switch_in_effects(void); -void atk53_trainer_slide(void); -void atk54_effectiveness_sound(void); -void atk55_play_sound(void); -void atk56_fainting_cry(void); -void atk57(void); -void atk58_return_to_ball(void); -void atk59_learnmove_inbattle(void); -void atk5A_yesnoboxlearnmove(void); -void atk5B_yesnoboxstoplearningmove(void); -void atk5C_hitanimation(void); -void atk5D_getmoneyreward(void); -void atk5E_8025A70(void); -void atk5F_8025B24(void); -void atk60_increment_gamestat(void); -void atk61_8025BA4(void); -void atk62_08025C6C(void); -void atk63_jumptorandomattack(void); -void atk64_statusanimation(void); -void atk65_status2animation(void); -void atk66_chosenstatusanimation(void); -void atk67_yesnobox(void); -void atk68_80246A0(void); -void atk69_dmg_adjustment3(void); -void atk6A_removeitem(void); -void atk6B_atknameinbuff1(void); -void atk6C_draw_lvlupbox(void); -void atk6D_reset_sentpokes_value(void); -void atk6E_set_atk_to_player0(void); -void atk6F_set_visible(void); -void atk70_record_last_used_ability(void); -void atk71_buffer_move_to_learn(void); -void atk72_jump_if_can_run_frombattle(void); -void atk73_hp_thresholds(void); -void atk74_hp_thresholds2(void); -void atk75_item_effect_on_opponent(void); -void atk76_various(void); -void atk77_set_protect_like(void); -void atk78_faintifabilitynotdamp(void); -void atk79_setatkhptozero(void); -void atk7A_jumpwhiletargetvalid(void); -void atk7B_healhalfHP_if_possible(void); -void atk7C_trymirrormove(void); -void atk7D_set_rain(void); -void atk7E_setreflect(void); -void atk7F_setseeded(void); -void atk80_manipulatedamage(void); -void atk81_setrest(void); -void atk82_jumpifnotfirstturn(void); -void atk83_nop(void); -void atk84_jump_if_cant_sleep(void); -void atk85_stockpile(void); -void atk86_stockpiletobasedamage(void); -void atk87_stockpiletohpheal(void); -void atk88_negativedamage(void); -void atk89_statbuffchange(void); -void atk8A_normalisebuffs(void); -void atk8B_setbide(void); -void atk8C_confuseifrepeatingattackends(void); -void atk8D_setmultihit_counter(void); -void atk8E_init_multihit_string(void); -void atk8F_forcerandomswitch(void); -void atk90_conversion_type_change(void); -void atk91_givepaydaymoney(void); -void atk92_setlightscreen(void); -void atk93_ko_move(void); -void atk94_damagetohalftargethp(void); -void atk95_setsandstorm(void); -void atk96_weatherdamage(void); -void atk97_try_infatuation(void); -void atk98_status_icon_update(void); -void atk99_setmist(void); -void atk9A_set_focusenergy(void); -void atk9B_transformdataexecution(void); -void atk9C_set_substitute(void); -void atk9D_mimicattackcopy(void); -void atk9E_metronome(void); -void atk9F_dmgtolevel(void); -void atkA0_psywavedamageeffect(void); -void atkA1_counterdamagecalculator(void); -void atkA2_mirrorcoatdamagecalculator(void); -void atkA3_disablelastusedattack(void); -void atkA4_setencore(void); -void atkA5_painsplitdmgcalc(void); -void atkA6_settypetorandomresistance(void); -void atkA7_setalwayshitflag(void); -void atkA8_copymovepermanently(void); -void atkA9_sleeptalk_choose_move(void); -void atkAA_set_destinybond(void); -void atkAB_DestinyBondFlagUpdate(void); -void atkAC_remaininghptopower(void); -void atkAD_spite_ppreduce(void); -void atkAE_heal_party_status(void); -void atkAF_cursetarget(void); -void atkB0_set_spikes(void); -void atkB1_set_foresight(void); -void atkB2_setperishsong(void); -void atkB3_rolloutdamagecalculation(void); -void atkB4_jumpifconfusedandstatmaxed(void); -void atkB5_furycuttercalc(void); -void atkB6_happinesstodamagecalculation(void); -void atkB7_presentdamagecalculation(void); -void atkB8_set_safeguard(void); -void atkB9_magnitudedamagecalculation(void); -void atkBA_jumpifnopursuitswitchdmg(void); -void atkBB_setsunny(void); -void atkBC_maxattackhalvehp(void); -void atkBD_copyfoestats(void); -void atkBE_rapidspinfree(void); -void atkBF_set_defense_curl(void); -void atkC0_recoverbasedonsunlight(void); -void atkC1_hidden_power(void); -void atkC2_selectnexttarget(void); -void atkC3_setfutureattack(void); -void atkC4_beat_up(void); -void atkC5_setsemiinvulnerablebit(void); -void atkC6_clearsemiinvulnerablebit(void); -void atkC7_setminimize(void); -void atkC8_sethail(void); -void atkC9_jumpifattackandspecialattackcannotfall(void); -void atkCA_setforcedtarget(void); -void atkCB_setcharge(void); -void atkCC_callterrainattack(void); -void atkCD_cureifburnedparalysedorpoisoned(void); -void atkCE_settorment(void); -void atkCF_jumpifnodamage(void); -void atkD0_settaunt(void); -void atkD1_set_helpinghand(void); -void atkD2_swap_items(void); -void atkD3_copy_ability(void); -void atkD4_wish_effect(void); -void atkD5_setroots(void); -void atkD6_doubledamagedealtifdamaged(void); -void atkD7_setyawn(void); -void atkD8_setdamagetohealthdifference(void); -void atkD9_scaledamagebyhealthratio(void); -void atkDA_abilityswap(void); -void atkDB_imprisoneffect(void); -void atkDC_setgrudge(void); -void atkDD_weightdamagecalculation(void); -void atkDE_asistattackselect(void); -void atkDF_setmagiccoat(void); -void atkE0_setstealstatchange(void); -void atkE1_intimidate_string_loader(void); -void atkE2_switchout_abilities(void); -void atkE3_jumpifhasnohp(void); -void atkE4_getsecretpowereffect(void); -void atkE5_pickup(void); -void atkE6_castform_change_animation(void); -void atkE7_castform_data_change(void); -void atkE8_settypebasedhalvers(void); -void atkE9_setweatherballtype(void); -void atkEA_recycleitem(void); -void atkEB_settypetoterrain(void); -void atkEC_pursuit_sth(void); -void atkED_802B4B4(void); -void atkEE_removelightscreenreflect(void); -void atkEF_pokeball_catch_calculation(void); -void atkF0_copy_caught_poke(void); -void atkF1_setpoke_as_caught(void); -void atkF2_display_dex_info(void); -void atkF3_nickname_caught_poke(void); -void atkF4_802BEF0(void); -void atkF5_removeattackerstatus1(void); -void atkF6_802BF48(void); -void atkF7_802BF54(void); -void sub_8056EF8(void); +static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8, const u8* BS_ptr); +static bool32 IsMonGettingExpSentOut(void); +static void sub_804F17C(void); +static bool8 sub_804F1CC(void); +static void sub_804F100(void); +static void sub_804F144(void); +static bool8 sub_804F344(void); +static void PutMonIconOnLvlUpBox(void); +static void PutLevelAndGenderOnLvlUpBox(void); + +static void atk00_attackcanceler(void); +static void atk01_accuracycheck(void); +static void atk02_attackstring(void); +static void atk03_ppreduce(void); +static void atk04_critcalc(void); +static void atk05_damagecalc1(void); +static void atk06_typecalc(void); +static void atk07_dmg_adjustment(void); +static void atk08_dmg_adjustment2(void); +static void atk09_attackanimation(void); +static void atk0A_waitanimation(void); +static void atk0B_healthbarupdate(void); +static void atk0C_datahpupdate(void); +static void atk0D_critmessage(void); +static void atk0E_effectiveness_sound(void); +static void atk0F_resultmessage(void); +static void atk10_printstring(void); +static void atk11_printstring_playeronly(void); +static void atk12_waitmessage(void); +static void atk13_printfromtable(void); +static void atk14_printfromtable_playeronly(void); +static void atk15_seteffectwithchance(void); +static void atk16_seteffectprimary(void); +static void atk17_seteffectsecondary(void); +static void atk18_status_effect_clear(void); +static void atk19_faint_pokemon(void); +static void atk1A_faint_animation(void); +static void atk1B_faint_effects_clear(void); +static void atk1C_jumpifstatus(void); +static void atk1D_jumpifstatus2(void); +static void atk1E_jumpifability(void); +static void atk1F_jumpifsideaffecting(void); +static void atk20_jumpifstat(void); +static void atk21_jumpifstatus3(void); +static void atk22_jumpiftype(void); +static void atk23_getexp(void); +static void atk24(void); +static void atk25_move_values_cleanup(void); +static void atk26_set_multihit(void); +static void atk27_decrement_multihit(void); +static void atk28_goto(void); +static void atk29_jumpifbyte(void); +static void atk2A_jumpifhalfword(void); +static void atk2B_jumpifword(void); +static void atk2C_jumpifarrayequal(void); +static void atk2D_jumpifarraynotequal(void); +static void atk2E_setbyte(void); +static void atk2F_addbyte(void); +static void atk30_subbyte(void); +static void atk31_copyarray(void); +static void atk32_copyarray_withindex(void); +static void atk33_orbyte(void); +static void atk34_orhalfword(void); +static void atk35_orword(void); +static void atk36_bicbyte(void); +static void atk37_bichalfword(void); +static void atk38_bicword(void); +static void atk39_pause(void); +static void atk3A_waitstate(void); +static void atk3B_healthbar_update(void); +static void atk3C_return(void); +static void atk3D_end(void); +static void atk3E_end2(void); +static void atk3F_end3(void); +static void atk40_jump_if_move_affected_by_protect(void); +static void atk41_call(void); +static void atk42_jumpiftype2(void); +static void atk43_jumpifabilitypresent(void); +static void atk44(void); +static void atk45_playanimation(void); +static void atk46_playanimation2(void); +static void atk47_setgraphicalstatchangevalues(void); +static void atk48_playstatchangeanimation(void); +static void atk49_moveend(void); +static void atk4A_typecalc2(void); +static void atk4B_return_atk_to_ball(void); +static void atk4C_copy_poke_data(void); +static void atk4D_switch_data_update(void); +static void atk4E_switchin_anim(void); +static void atk4F_jump_if_cannot_switch(void); +static void atk50_openpartyscreen(void); +static void atk51_switch_handle_order(void); +static void atk52_switch_in_effects(void); +static void atk53_trainer_slide(void); +static void atk54_effectiveness_sound(void); +static void atk55_play_sound(void); +static void atk56_fainting_cry(void); +static void atk57(void); +static void atk58_return_to_ball(void); +static void atk59_learnmove_inbattle(void); +static void atk5A_yesnoboxlearnmove(void); +static void atk5B_yesnoboxstoplearningmove(void); +static void atk5C_hitanimation(void); +static void atk5D_getmoneyreward(void); +static void atk5E_8025A70(void); +static void atk5F_8025B24(void); +static void atk60_increment_gamestat(void); +static void atk61_8025BA4(void); +static void atk62_08025C6C(void); +static void atk63_jumptorandomattack(void); +static void atk64_statusanimation(void); +static void atk65_status2animation(void); +static void atk66_chosenstatusanimation(void); +static void atk67_yesnobox(void); +static void atk68_80246A0(void); +static void atk69_dmg_adjustment3(void); +static void atk6A_removeitem(void); +static void atk6B_atknameinbuff1(void); +static void atk6C_draw_lvlupbox(void); +static void atk6D_reset_sentpokes_value(void); +static void atk6E_set_atk_to_player0(void); +static void atk6F_set_visible(void); +static void atk70_record_last_used_ability(void); +static void atk71_buffer_move_to_learn(void); +static void atk72_jump_if_can_run_frombattle(void); +static void atk73_hp_thresholds(void); +static void atk74_hp_thresholds2(void); +static void atk75_item_effect_on_opponent(void); +static void atk76_various(void); +static void atk77_set_protect_like(void); +static void atk78_faintifabilitynotdamp(void); +static void atk79_setatkhptozero(void); +static void atk7A_jumpwhiletargetvalid(void); +static void atk7B_healhalfHP_if_possible(void); +static void atk7C_trymirrormove(void); +static void atk7D_set_rain(void); +static void atk7E_setreflect(void); +static void atk7F_setseeded(void); +static void atk80_manipulatedamage(void); +static void atk81_setrest(void); +static void atk82_jumpifnotfirstturn(void); +static void atk83_nop(void); +static void atk84_jump_if_cant_sleep(void); +static void atk85_stockpile(void); +static void atk86_stockpiletobasedamage(void); +static void atk87_stockpiletohpheal(void); +static void atk88_negativedamage(void); +static void atk89_statbuffchange(void); +static void atk8A_normalisebuffs(void); +static void atk8B_setbide(void); +static void atk8C_confuseifrepeatingattackends(void); +static void atk8D_setmultihit_counter(void); +static void atk8E_init_multihit_string(void); +static void atk8F_forcerandomswitch(void); +static void atk90_conversion_type_change(void); +static void atk91_givepaydaymoney(void); +static void atk92_setlightscreen(void); +static void atk93_ko_move(void); +static void atk94_damagetohalftargethp(void); +static void atk95_setsandstorm(void); +static void atk96_weatherdamage(void); +static void atk97_try_infatuation(void); +static void atk98_status_icon_update(void); +static void atk99_setmist(void); +static void atk9A_set_focusenergy(void); +static void atk9B_transformdataexecution(void); +static void atk9C_set_substitute(void); +static void atk9D_mimicattackcopy(void); +static void atk9E_metronome(void); +static void atk9F_dmgtolevel(void); +static void atkA0_psywavedamageeffect(void); +static void atkA1_counterdamagecalculator(void); +static void atkA2_mirrorcoatdamagecalculator(void); +static void atkA3_disablelastusedattack(void); +static void atkA4_setencore(void); +static void atkA5_painsplitdmgcalc(void); +static void atkA6_settypetorandomresistance(void); +static void atkA7_setalwayshitflag(void); +static void atkA8_copymovepermanently(void); +static void atkA9_sleeptalk_choose_move(void); +static void atkAA_set_destinybond(void); +static void atkAB_DestinyBondFlagUpdate(void); +static void atkAC_remaininghptopower(void); +static void atkAD_spite_ppreduce(void); +static void atkAE_heal_party_status(void); +static void atkAF_cursetarget(void); +static void atkB0_set_spikes(void); +static void atkB1_set_foresight(void); +static void atkB2_setperishsong(void); +static void atkB3_rolloutdamagecalculation(void); +static void atkB4_jumpifconfusedandstatmaxed(void); +static void atkB5_furycuttercalc(void); +static void atkB6_happinesstodamagecalculation(void); +static void atkB7_presentdamagecalculation(void); +static void atkB8_set_safeguard(void); +static void atkB9_magnitudedamagecalculation(void); +static void atkBA_jumpifnopursuitswitchdmg(void); +static void atkBB_setsunny(void); +static void atkBC_maxattackhalvehp(void); +static void atkBD_copyfoestats(void); +static void atkBE_rapidspinfree(void); +static void atkBF_set_defense_curl(void); +static void atkC0_recoverbasedonsunlight(void); +static void atkC1_hidden_power(void); +static void atkC2_selectnexttarget(void); +static void atkC3_setfutureattack(void); +static void atkC4_beat_up(void); +static void atkC5_setsemiinvulnerablebit(void); +static void atkC6_clearsemiinvulnerablebit(void); +static void atkC7_setminimize(void); +static void atkC8_sethail(void); +static void atkC9_jumpifattackandspecialattackcannotfall(void); +static void atkCA_setforcedtarget(void); +static void atkCB_setcharge(void); +static void atkCC_callterrainattack(void); +static void atkCD_cureifburnedparalysedorpoisoned(void); +static void atkCE_settorment(void); +static void atkCF_jumpifnodamage(void); +static void atkD0_settaunt(void); +static void atkD1_set_helpinghand(void); +static void atkD2_swap_items(void); +static void atkD3_copy_ability(void); +static void atkD4_wish_effect(void); +static void atkD5_setroots(void); +static void atkD6_doubledamagedealtifdamaged(void); +static void atkD7_setyawn(void); +static void atkD8_setdamagetohealthdifference(void); +static void atkD9_scaledamagebyhealthratio(void); +static void atkDA_abilityswap(void); +static void atkDB_imprisoneffect(void); +static void atkDC_setgrudge(void); +static void atkDD_weightdamagecalculation(void); +static void atkDE_asistattackselect(void); +static void atkDF_setmagiccoat(void); +static void atkE0_setstealstatchange(void); +static void atkE1_intimidate_string_loader(void); +static void atkE2_switchout_abilities(void); +static void atkE3_jumpifhasnohp(void); +static void atkE4_getsecretpowereffect(void); +static void atkE5_pickup(void); +static void atkE6_castform_change_animation(void); +static void atkE7_castform_data_change(void); +static void atkE8_settypebasedhalvers(void); +static void atkE9_setweatherballtype(void); +static void atkEA_recycleitem(void); +static void atkEB_settypetoterrain(void); +static void atkEC_pursuit_sth(void); +static void atkED_802B4B4(void); +static void atkEE_removelightscreenreflect(void); +static void atkEF_pokeball_catch_calculation(void); +static void atkF0_give_caught_mon(void); +static void atkF1_set_caught_mon_dex_flags(void); +static void atkF2_display_dex_info(void); +static void atkF3_nickname_caught_poke(void); +static void atkF4_subattackerhpbydmg(void); +static void atkF5_removeattackerstatus1(void); +static void atkF6_802BF48(void); +static void atkF7_802BF54(void); +static void atkF8_trainer_slide_back(void); void (* const gBattleScriptingCommandsTable[])(void) = { @@ -727,15 +754,15 @@ void (* const gBattleScriptingCommandsTable[])(void) = atkED_802B4B4, atkEE_removelightscreenreflect, atkEF_pokeball_catch_calculation, - atkF0_copy_caught_poke, - atkF1_setpoke_as_caught, + atkF0_give_caught_mon, + atkF1_set_caught_mon_dex_flags, atkF2_display_dex_info, atkF3_nickname_caught_poke, - atkF4_802BEF0, + atkF4_subattackerhpbydmg, atkF5_removeattackerstatus1, atkF6_802BF48, atkF7_802BF54, - sub_8056EF8 + atkF8_trainer_slide_back }; struct StatFractions @@ -877,8 +904,22 @@ extern const struct SpriteTemplate SpriteTemplate_MonIconOnLvlUpBox; extern const u16 sProtectSuccessRates[]; extern const u16 sNaturePowerMoves[]; extern const u16 sWeightToDamageTable[]; +extern const u8 sTerrainToType[]; +extern const u8 sBallCatchBonuses[]; +extern const u16 gUnknown_0831C2C8[]; +extern const u8 gUnknown_0831C2E8[]; +extern const u8 gUnknown_0831C4F8[]; +extern const u8 sFlailHpScaleToPowerTable[12]; +extern const u16 gRarePickupItems[]; +extern const u16 gPickupItems[]; +extern const u8 gPickupProbabilities[]; + +extern const u16 gMovesForbiddenToCopy[]; +#define MIMIC_FORBIDDEN_END 0xFFFE +#define METRONOME_FORBIDDEN_END 0xFFFF +#define ASSIST_FORBIDDEN_END 0xFFFF -void atk00_attackcanceler(void) +static void atk00_attackcanceler(void) { s32 i; @@ -972,7 +1013,7 @@ void atk00_attackcanceler(void) } } -void JumpIfMoveFailed(u8 adder, u16 move) +static void JumpIfMoveFailed(u8 adder, u16 move) { const void* BS_ptr = gBattlescriptCurrInstr + adder; if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) @@ -990,7 +1031,7 @@ void JumpIfMoveFailed(u8 adder, u16 move) gBattlescriptCurrInstr = BS_ptr; } -void atk40_jump_if_move_affected_by_protect(void) +static void atk40_jump_if_move_affected_by_protect(void) { if (TARGET_PROTECT_AFFECTED) { @@ -1062,7 +1103,7 @@ bool8 AccuracyCalcHelper(u16 move) return FALSE; } -void atk01_accuracycheck(void) +static void atk01_accuracycheck(void) { u16 move = BS2ScriptRead16(gBattlescriptCurrInstr + 5); @@ -1154,7 +1195,7 @@ void atk01_accuracycheck(void) } } -void atk02_attackstring(void) +static void atk02_attackstring(void) { if (gBattleExecBuffer) return; @@ -1167,7 +1208,7 @@ void atk02_attackstring(void) gBattleCommunication[MSG_DISPLAY] = 0; } -void atk03_ppreduce(void) +static void atk03_ppreduce(void) { s32 ppToDeduct = 1; @@ -1214,7 +1255,7 @@ void atk03_ppreduce(void) gBattlescriptCurrInstr++; } -void atk04_critcalc(void) +static void atk04_critcalc(void) { u8 holdEffect; u16 item, critChance; @@ -1251,7 +1292,7 @@ void atk04_critcalc(void) gBattlescriptCurrInstr++; } -void atk05_damagecalc1(void) +static void atk05_damagecalc1(void) { u16 sideStatus = gSideAffecting[GET_BANK_SIDE(gBankTarget)]; gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, @@ -1282,7 +1323,7 @@ void AI_CalcDmg(u8 bankAtk, u8 bankDef) gBattleMoveDamage = gBattleMoveDamage * 15 / 10; } -void ModulateDmgByType(u8 multiplier) +static void ModulateDmgByType(u8 multiplier) { gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; if (gBattleMoveDamage == 0 && multiplier != 0) @@ -1319,7 +1360,7 @@ void ModulateDmgByType(u8 multiplier) #define TYPE_FORESIGHT 0xFE #define TYPE_ENDTABLE 0xFF -void atk06_typecalc(void) +static void atk06_typecalc(void) { s32 i = 0; u8 moveType; @@ -1464,7 +1505,7 @@ static void CheckWonderGuardAndLevitate(void) } } -void ModulateDmgByType2(u8 multiplier, u16 move, u8* flags) // same as ModulateDmgByType except different arguments +static void ModulateDmgByType2(u8 multiplier, u16 move, u8* flags) // same as ModulateDmgByType except different arguments { gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; if (gBattleMoveDamage == 0 && multiplier != 0) @@ -1615,12 +1656,12 @@ static inline void ApplyRandomDmgMultiplier(void) } } -void Unused_ApplyRandomDmgMultiplier(void) +static void Unused_ApplyRandomDmgMultiplier(void) { ApplyRandomDmgMultiplier(); } -void atk07_dmg_adjustment(void) +static void atk07_dmg_adjustment(void) { u8 holdEffect, quality; @@ -1668,7 +1709,7 @@ void atk07_dmg_adjustment(void) gBattlescriptCurrInstr++; } -void atk08_dmg_adjustment2(void) // The same as 0x7 except it doesn't check for false swipe move effect. +static void atk08_dmg_adjustment2(void) // The same as 0x7 except it doesn't check for false swipe move effect. { u8 holdEffect, quality; @@ -1714,7 +1755,7 @@ void atk08_dmg_adjustment2(void) // The same as 0x7 except it doesn't check for gBattlescriptCurrInstr++; } -void atk09_attackanimation(void) +static void atk09_attackanimation(void) { if (gBattleExecBuffer) return; @@ -1768,20 +1809,20 @@ void atk09_attackanimation(void) } } -void atk0A_waitanimation(void) +static void atk0A_waitanimation(void) { if (gBattleExecBuffer == 0) gBattlescriptCurrInstr++; } -void atk0B_healthbarupdate(void) +static void atk0B_healthbarupdate(void) { if (gBattleExecBuffer) return; if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) { @@ -1810,7 +1851,7 @@ void atk0B_healthbarupdate(void) gBattlescriptCurrInstr += 2; } -void atk0C_datahpupdate(void) +static void atk0C_datahpupdate(void) { u32 moveType; @@ -1826,7 +1867,7 @@ void atk0C_datahpupdate(void) if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) { if (gDisableStructs[gActiveBank].substituteHP >= gBattleMoveDamage) @@ -1871,7 +1912,7 @@ void atk0C_datahpupdate(void) else { gTakenDmg[gActiveBank] += gBattleMoveDamage; - if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_TARGET) + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) gTakenDmgBanks[gActiveBank] = gBankAttacker; else gTakenDmgBanks[gActiveBank] = gBankTarget; @@ -1895,7 +1936,7 @@ void atk0C_datahpupdate(void) { gProtectStructs[gActiveBank].physicalDmg = gHpDealt; gSpecialStatuses[gActiveBank].moveturnLostHP_physical = gHpDealt; - if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_TARGET) + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) { gProtectStructs[gActiveBank].physicalBank = gBankAttacker; gSpecialStatuses[gActiveBank].moveturnPhysicalBank = gBankAttacker; @@ -1910,7 +1951,7 @@ void atk0C_datahpupdate(void) { gProtectStructs[gActiveBank].specialDmg = gHpDealt; gSpecialStatuses[gActiveBank].moveturnLostHP_special = gHpDealt; - if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_TARGET) + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) { gProtectStructs[gActiveBank].specialBank = gBankAttacker; gSpecialStatuses[gActiveBank].moveturnSpecialBank = gBankAttacker; @@ -1929,14 +1970,14 @@ void atk0C_datahpupdate(void) } else { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (gSpecialStatuses[gActiveBank].moveturnLostHP == 0) gSpecialStatuses[gActiveBank].moveturnLostHP = 0xFFFF; } gBattlescriptCurrInstr += 2; } -void atk0D_critmessage(void) +static void atk0D_critmessage(void) { if (gBattleExecBuffer == 0) { @@ -1949,7 +1990,7 @@ void atk0D_critmessage(void) } } -void atk0E_effectiveness_sound(void) +static void atk0E_effectiveness_sound(void) { if (gBattleExecBuffer) return; @@ -1996,7 +2037,7 @@ void atk0E_effectiveness_sound(void) gBattlescriptCurrInstr++; } -void atk0F_resultmessage(void) +static void atk0F_resultmessage(void) { u32 stringId = 0; @@ -2085,7 +2126,7 @@ void atk0F_resultmessage(void) gBattlescriptCurrInstr++; } -void atk10_printstring(void) +static void atk10_printstring(void) { if (gBattleExecBuffer == 0) { @@ -2096,7 +2137,7 @@ void atk10_printstring(void) } } -void atk11_printstring_playeronly(void) +static void atk11_printstring_playeronly(void) { gActiveBank = gBankAttacker; @@ -2107,7 +2148,7 @@ void atk11_printstring_playeronly(void) gBattleCommunication[MSG_DISPLAY] = 1; } -void atk12_waitmessage(void) +static void atk12_waitmessage(void) { if (gBattleExecBuffer == 0) { @@ -2128,7 +2169,7 @@ void atk12_waitmessage(void) } } -void atk13_printfromtable(void) +static void atk13_printfromtable(void) { if (gBattleExecBuffer == 0) { @@ -2142,7 +2183,7 @@ void atk13_printfromtable(void) } } -void atk14_printfromtable_playeronly(void) +static void atk14_printfromtable_playeronly(void) { if (gBattleExecBuffer == 0) { @@ -2868,7 +2909,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleCommunication[MOVE_EFFECT_BYTE] = 0; } -void atk15_seteffectwithchance(void) +static void atk15_seteffectwithchance(void) { u32 percentChance; @@ -2901,19 +2942,19 @@ void atk15_seteffectwithchance(void) gBattleScripting.field_16 = 0; } -void atk16_seteffectprimary(void) +static void atk16_seteffectprimary(void) { SetMoveEffect(TRUE, 0); } -void atk17_seteffectsecondary(void) +static void atk17_seteffectsecondary(void) { SetMoveEffect(FALSE, 0); } -void atk18_status_effect_clear(void) +static void atk18_status_effect_clear(void) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (gBattleCommunication[MOVE_EFFECT_BYTE] <= MOVE_EFFECT_TOXIC) gBattleMons[gActiveBank].status1 &= (~gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); @@ -2925,7 +2966,7 @@ void atk18_status_effect_clear(void) gBattleScripting.field_16 = 0; } -void atk19_faint_pokemon(void) +static void atk19_faint_pokemon(void) { const u8 *BS_ptr; @@ -3012,22 +3053,22 @@ void atk19_faint_pokemon(void) } } -void atk1A_faint_animation(void) +static void atk1A_faint_animation(void) { if (gBattleExecBuffer == 0) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); EmitFaintAnimation(0); MarkBufferBankForExecution(gActiveBank); gBattlescriptCurrInstr += 2; } } -void atk1B_faint_effects_clear(void) +static void atk1B_faint_effects_clear(void) { if (gBattleExecBuffer == 0) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || gBattleMons[gActiveBank].hp == 0) { @@ -3041,9 +3082,9 @@ void atk1B_faint_effects_clear(void) } } -void atk1C_jumpifstatus(void) +static void atk1C_jumpifstatus(void) { - u8 bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); @@ -3053,9 +3094,9 @@ void atk1C_jumpifstatus(void) gBattlescriptCurrInstr += 10; } -void atk1D_jumpifstatus2(void) +static void atk1D_jumpifstatus2(void) { - u8 bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); @@ -3065,13 +3106,13 @@ void atk1D_jumpifstatus2(void) gBattlescriptCurrInstr += 10; } -void atk1E_jumpifability(void) +static void atk1E_jumpifability(void) { u8 bank; - u8 ability = BSScriptRead8(gBattlescriptCurrInstr + 2); + u8 ability = gBattlescriptCurrInstr[2]; const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); - if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_ATTACKER_SIDE) + if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER_SIDE) { bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_BANK_SIDE, gBankAttacker, ability, 0, 0); if (bank) @@ -3084,7 +3125,7 @@ void atk1E_jumpifability(void) else gBattlescriptCurrInstr += 7; } - else if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_NOT_ATTACKER_SIDE) + else if (gBattlescriptCurrInstr[1] == BS_GET_NOT_ATTACKER_SIDE) { bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gBankAttacker, ability, 0, 0); if (bank) @@ -3099,7 +3140,7 @@ void atk1E_jumpifability(void) } else { - bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + bank = GetBattleBank(gBattlescriptCurrInstr[1]); if (gBattleMons[bank].ability == ability) { gLastUsedAbility = ability; @@ -3112,13 +3153,13 @@ void atk1E_jumpifability(void) } } -void atk1F_jumpifsideaffecting(void) +static void atk1F_jumpifsideaffecting(void) { u8 side; u16 flags; const u8* jumpPtr; - if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_ATTACKER) + if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER) side = GET_BANK_SIDE(gBankAttacker); else side = GET_BANK_SIDE(gBankTarget); @@ -3132,36 +3173,36 @@ void atk1F_jumpifsideaffecting(void) gBattlescriptCurrInstr += 8; } -void atk20_jumpifstat(void) +static void atk20_jumpifstat(void) { u8 ret = 0; - u8 bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); - u8 value = gBattleMons[bank].statStages[BSScriptRead8(gBattlescriptCurrInstr + 3)]; + u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + u8 value = gBattleMons[bank].statStages[gBattlescriptCurrInstr[3]]; - switch (BSScriptRead8(gBattlescriptCurrInstr + 2)) + switch (gBattlescriptCurrInstr[2]) { case CMP_EQUAL: - if (value == BSScriptRead8(gBattlescriptCurrInstr + 4)) + if (value == gBattlescriptCurrInstr[4]) ret++; break; case CMP_NOT_EQUAL: - if (value != BSScriptRead8(gBattlescriptCurrInstr + 4)) + if (value != gBattlescriptCurrInstr[4]) ret++; break; case CMP_GREATER_THAN: - if (value > BSScriptRead8(gBattlescriptCurrInstr + 4)) + if (value > gBattlescriptCurrInstr[4]) ret++; break; case CMP_LESS_THAN: - if (value < BSScriptRead8(gBattlescriptCurrInstr + 4)) + if (value < gBattlescriptCurrInstr[4]) ret++; break; case CMP_COMMON_BITS: - if (value & BSScriptRead8(gBattlescriptCurrInstr + 4)) + if (value & gBattlescriptCurrInstr[4]) ret++; break; case CMP_NO_COMMON_BITS: - if (!(value & BSScriptRead8(gBattlescriptCurrInstr + 4))) + if (!(value & gBattlescriptCurrInstr[4])) ret++; break; } @@ -3172,16 +3213,16 @@ void atk20_jumpifstat(void) gBattlescriptCurrInstr += 9; } -void atk21_jumpifstatus3(void) +static void atk21_jumpifstatus3(void) { u32 flags; const u8* jumpPtr; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7); - if (BSScriptRead8(gBattlescriptCurrInstr + 6)) + if (gBattlescriptCurrInstr[6]) { if ((gStatuses3[gActiveBank] & flags) != 0) gBattlescriptCurrInstr += 11; @@ -3197,10 +3238,10 @@ void atk21_jumpifstatus3(void) } } -void atk22_jumpiftype(void) +static void atk22_jumpiftype(void) { - u8 bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); - u8 type = BSScriptRead8(gBattlescriptCurrInstr + 2); + u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + u8 type = gBattlescriptCurrInstr[2]; const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); if (gBattleMons[bank].type1 == type || gBattleMons[bank].type2 == type) @@ -3209,7 +3250,7 @@ void atk22_jumpiftype(void) gBattlescriptCurrInstr += 7; } -void atk23_getexp(void) +static void atk23_getexp(void) { u16 item; s32 i; // also used as stringId @@ -3219,7 +3260,7 @@ void atk23_getexp(void) s32 viaExpShare = 0; u16* exp = &gBattleStruct->expValue; - gBank1 = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gBank1 = GetBattleBank(gBattlescriptCurrInstr[1]); sentIn = gSentPokesToOpponent[(gBank1 & 2) >> 1]; switch (gBattleScripting.atk23_state) @@ -3487,7 +3528,7 @@ void atk23_getexp(void) } #ifdef NONMATCHING -void atk24(void) +static void atk24(void) { u16 HP_count = 0; s32 i; @@ -3570,7 +3611,7 @@ void atk24(void) } #else __attribute__((naked)) -void atk24(void) +static void atk24(void) { asm("\n\ .syntax unified\n\ @@ -3864,7 +3905,7 @@ void atk24(void) #endif // NONMATCHING -void MoveValuesCleanUp(void) +static void MoveValuesCleanUp(void) { gBattleMoveFlags = 0; gBattleScripting.dmgMultiplier = 1; @@ -3875,19 +3916,19 @@ void MoveValuesCleanUp(void) gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); } -void atk25_move_values_cleanup(void) +static void atk25_move_values_cleanup(void) { MoveValuesCleanUp(); gBattlescriptCurrInstr += 1; } -void atk26_set_multihit(void) +static void atk26_set_multihit(void) { - gMultiHitCounter = BSScriptRead8(gBattlescriptCurrInstr + 1); + gMultiHitCounter = gBattlescriptCurrInstr[1]; gBattlescriptCurrInstr += 2; } -void atk27_decrement_multihit(void) +static void atk27_decrement_multihit(void) { if (--gMultiHitCounter == 0) gBattlescriptCurrInstr += 5; @@ -3895,16 +3936,16 @@ void atk27_decrement_multihit(void) gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); } -void atk28_goto(void) +static void atk28_goto(void) { gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); } -void atk29_jumpifbyte(void) +static void atk29_jumpifbyte(void) { - u8 caseID = BSScriptRead8(gBattlescriptCurrInstr + 1); + u8 caseID = gBattlescriptCurrInstr[1]; const u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); - u8 value = BSScriptRead8(gBattlescriptCurrInstr + 6); + u8 value = gBattlescriptCurrInstr[6]; const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7); gBattlescriptCurrInstr += 11; @@ -3938,9 +3979,9 @@ void atk29_jumpifbyte(void) } } -void atk2A_jumpifhalfword(void) +static void atk2A_jumpifhalfword(void) { - u8 caseID = BSScriptRead8(gBattlescriptCurrInstr + 1); + u8 caseID = gBattlescriptCurrInstr[1]; const u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); u16 value = BS2ScriptRead16(gBattlescriptCurrInstr + 6); const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 8); @@ -3976,9 +4017,9 @@ void atk2A_jumpifhalfword(void) } } -void atk2B_jumpifword(void) +static void atk2B_jumpifword(void) { - u8 caseID = BSScriptRead8(gBattlescriptCurrInstr + 1); + u8 caseID = gBattlescriptCurrInstr[1]; const u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); u32 value = BSScriptRead32(gBattlescriptCurrInstr + 6); const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); @@ -4014,11 +4055,11 @@ void atk2B_jumpifword(void) } } -void atk2C_jumpifarrayequal(void) +static void atk2C_jumpifarrayequal(void) { const u8* mem1 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); const u8* mem2 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); - u32 size = BSScriptRead8(gBattlescriptCurrInstr + 9); + u32 size = gBattlescriptCurrInstr[9]; const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); u8 i; @@ -4036,12 +4077,12 @@ void atk2C_jumpifarrayequal(void) gBattlescriptCurrInstr = jumpPtr; } -void atk2D_jumpifarraynotequal(void) +static void atk2D_jumpifarraynotequal(void) { u8 equalBytes = 0; const u8* mem1 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); const u8* mem2 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); - u32 size = BSScriptRead8(gBattlescriptCurrInstr + 9); + u32 size = gBattlescriptCurrInstr[9]; const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); u8 i; @@ -4060,33 +4101,33 @@ void atk2D_jumpifarraynotequal(void) gBattlescriptCurrInstr += 14; } -void atk2E_setbyte(void) +static void atk2E_setbyte(void) { u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - *memByte = BSScriptRead8(gBattlescriptCurrInstr + 5); + *memByte = gBattlescriptCurrInstr[5]; gBattlescriptCurrInstr += 6; } -void atk2F_addbyte(void) +static void atk2F_addbyte(void) { u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - *memByte += BSScriptRead8(gBattlescriptCurrInstr + 5); + *memByte += gBattlescriptCurrInstr[5]; gBattlescriptCurrInstr += 6; } -void atk30_subbyte(void) +static void atk30_subbyte(void) { u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - *memByte -= BSScriptRead8(gBattlescriptCurrInstr + 5); + *memByte -= gBattlescriptCurrInstr[5]; gBattlescriptCurrInstr += 6; } -void atk31_copyarray(void) +static void atk31_copyarray(void) { u8* dest = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); const u8* src = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); - s32 size = BSScriptRead8(gBattlescriptCurrInstr + 9); + s32 size = gBattlescriptCurrInstr[9]; s32 i; for (i = 0; i < size; i++) @@ -4097,12 +4138,12 @@ void atk31_copyarray(void) gBattlescriptCurrInstr += 10; } -void atk32_copyarray_withindex(void) +static void atk32_copyarray_withindex(void) { u8* dest = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); const u8* src = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); const u8* index = BS2ScriptReadPtr(gBattlescriptCurrInstr + 9); - s32 size = BSScriptRead8(gBattlescriptCurrInstr + 13); + s32 size = gBattlescriptCurrInstr[13]; s32 i; for (i = 0; i < size; i++) @@ -4113,14 +4154,14 @@ void atk32_copyarray_withindex(void) gBattlescriptCurrInstr += 14; } -void atk33_orbyte(void) +static void atk33_orbyte(void) { u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - *memByte |= BSScriptRead8(gBattlescriptCurrInstr + 5); + *memByte |= gBattlescriptCurrInstr[5]; gBattlescriptCurrInstr += 6; } -void atk34_orhalfword(void) +static void atk34_orhalfword(void) { u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); u16 val = BS2ScriptRead16(gBattlescriptCurrInstr + 5); @@ -4129,7 +4170,7 @@ void atk34_orhalfword(void) gBattlescriptCurrInstr += 7; } -void atk35_orword(void) +static void atk35_orword(void) { u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); u32 val = BS2ScriptRead32(gBattlescriptCurrInstr + 5); @@ -4138,14 +4179,14 @@ void atk35_orword(void) gBattlescriptCurrInstr += 9; } -void atk36_bicbyte(void) +static void atk36_bicbyte(void) { u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - *memByte &= ~(BSScriptRead8(gBattlescriptCurrInstr + 5)); + *memByte &= ~(gBattlescriptCurrInstr[5]); gBattlescriptCurrInstr += 6; } -void atk37_bichalfword(void) +static void atk37_bichalfword(void) { u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); u16 val = BS2ScriptRead16(gBattlescriptCurrInstr + 5); @@ -4154,7 +4195,7 @@ void atk37_bichalfword(void) gBattlescriptCurrInstr += 7; } -void atk38_bicword(void) +static void atk38_bicword(void) { u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); u32 val = BS2ScriptRead32(gBattlescriptCurrInstr + 5); @@ -4163,7 +4204,7 @@ void atk38_bicword(void) gBattlescriptCurrInstr += 9; } -void atk39_pause(void) +static void atk39_pause(void) { if (gBattleExecBuffer == 0) { @@ -4176,15 +4217,15 @@ void atk39_pause(void) } } -void atk3A_waitstate(void) +static void atk3A_waitstate(void) { if (gBattleExecBuffer == 0) gBattlescriptCurrInstr++; } -void atk3B_healthbar_update(void) +static void atk3B_healthbar_update(void) { - if (BSScriptRead8(gBattlescriptCurrInstr + 1) == BS_GET_TARGET) + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) gActiveBank = gBankTarget; else gActiveBank = gBankAttacker; @@ -4194,12 +4235,12 @@ void atk3B_healthbar_update(void) gBattlescriptCurrInstr += 2; } -void atk3C_return(void) +static void atk3C_return(void) { BattleScriptPop(); } -void atk3D_end(void) +static void atk3D_end(void) { if (gBattleTypeFlags & BATTLE_TYPE_ARENA) sub_81A5718(gBankAttacker); @@ -4209,13 +4250,13 @@ void atk3D_end(void) gFightStateTracker = 0xB; } -void atk3E_end2(void) +static void atk3E_end2(void) { gActiveBank = 0; gFightStateTracker = 0xB; } -void atk3F_end3(void) // pops the main function stack +static void atk3F_end3(void) // pops the main function stack { BattleScriptPop(); if (BATTLE_CALLBACKS_STACK->size) @@ -4223,40 +4264,40 @@ void atk3F_end3(void) // pops the main function stack gBattleMainFunc = BATTLE_CALLBACKS_STACK->function[BATTLE_CALLBACKS_STACK->size]; } -void atk41_call(void) +static void atk41_call(void) { BattleScriptPush(gBattlescriptCurrInstr + 5); gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); } -void atk42_jumpiftype2(void) +static void atk42_jumpiftype2(void) { - u8 bank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); - if (BSScriptRead8(gBattlescriptCurrInstr + 2) == gBattleMons[bank].type1 || BSScriptRead8(gBattlescriptCurrInstr + 2) == gBattleMons[bank].type2) + if (gBattlescriptCurrInstr[2] == gBattleMons[bank].type1 || gBattlescriptCurrInstr[2] == gBattleMons[bank].type2) gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 3); else gBattlescriptCurrInstr += 7; } -void atk43_jumpifabilitypresent(void) +static void atk43_jumpifabilitypresent(void) { - if (AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, BSScriptRead8(gBattlescriptCurrInstr + 1), 0, 0)) + if (AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, gBattlescriptCurrInstr[1], 0, 0)) gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); else gBattlescriptCurrInstr += 6; } -void atk44(void) +static void atk44(void) { *(gBankAttacker + gBattleStruct->field_54) = 1; } -void atk45_playanimation(void) +static void atk45_playanimation(void) { const u16* argumentPtr; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE @@ -4293,12 +4334,12 @@ void atk45_playanimation(void) } } -void atk46_playanimation2(void) // animation Id is stored in the first pointer +static void atk46_playanimation2(void) // animation Id is stored in the first pointer { const u16* argumentPtr; const u8* animationIdPtr; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); animationIdPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); @@ -4335,7 +4376,7 @@ void atk46_playanimation2(void) // animation Id is stored in the first pointer } } -void atk47_setgraphicalstatchangevalues(void) +static void atk47_setgraphicalstatchangevalues(void) { u8 value = 0; switch (gBattleScripting.statChanger & 0xF0) @@ -4359,7 +4400,7 @@ void atk47_setgraphicalstatchangevalues(void) } #ifdef NONMATCHING -void atk48_playstatchangeanimation(void) +static void atk48_playstatchangeanimation(void) { u32 currStat = 0; s16 statAnimId = 0; @@ -4450,7 +4491,7 @@ void atk48_playstatchangeanimation(void) } #else __attribute__((naked)) -void atk48_playstatchangeanimation(void) +static void atk48_playstatchangeanimation(void) { asm("\n\ .syntax unified\n\ @@ -4706,7 +4747,7 @@ _0804BBBA:\n\ #define ATK49_LAST_CASE 17 -void atk49_moveend(void) +static void atk49_moveend(void) { s32 i; bool32 effect; @@ -4992,7 +5033,7 @@ void atk49_moveend(void) gBattlescriptCurrInstr += 3; } -void atk4A_typecalc2(void) +static void atk4A_typecalc2(void) { u8 flags = 0; s32 i = 0; @@ -5087,7 +5128,7 @@ void atk4A_typecalc2(void) gBattlescriptCurrInstr++; } -void atk4B_return_atk_to_ball(void) +static void atk4B_return_atk_to_ball(void) { gActiveBank = gBankAttacker; if (!(gHitMarker & HITMARKER_FAINTED(gActiveBank))) @@ -5098,12 +5139,12 @@ void atk4B_return_atk_to_ball(void) gBattlescriptCurrInstr++; } -void atk4C_copy_poke_data(void) +static void atk4C_copy_poke_data(void) { if (gBattleExecBuffer) return; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); gBattlePartyID[gActiveBank] = *(gBattleStruct->field_5C + gActiveBank); @@ -5113,7 +5154,7 @@ void atk4C_copy_poke_data(void) gBattlescriptCurrInstr += 2; } -void atk4D_switch_data_update(void) +static void atk4D_switch_data_update(void) { struct BattlePokemon oldData; s32 i; @@ -5122,7 +5163,7 @@ void atk4D_switch_data_update(void) if (gBattleExecBuffer) return; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); oldData = gBattleMons[gActiveBank]; monData = (u8*)(&gBattleMons[gActiveBank]); @@ -5169,12 +5210,12 @@ void atk4D_switch_data_update(void) gBattlescriptCurrInstr += 2; } -void atk4E_switchin_anim(void) +static void atk4E_switchin_anim(void) { if (gBattleExecBuffer) return; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (GetBankSide(gActiveBank) == SIDE_OPPONENT && !(gBattleTypeFlags & (BATTLE_TYPE_LINK @@ -5195,7 +5236,7 @@ void atk4E_switchin_anim(void) sub_81A56B4(); } -void atk4F_jump_if_cannot_switch(void) +static void atk4F_jump_if_cannot_switch(void) { s32 val = 0; s32 compareVar = 0; @@ -5349,7 +5390,7 @@ void atk4F_jump_if_cannot_switch(void) } } -void sub_804CF10(u8 arg0) +static void sub_804CF10(u8 arg0) { *(gBattleStruct->field_58 + gActiveBank) = gBattlePartyID[gActiveBank]; *(gBattleStruct->field_5C + gActiveBank) = 6; @@ -5359,7 +5400,7 @@ void sub_804CF10(u8 arg0) MarkBufferBankForExecution(gActiveBank); } -void atk50_openpartyscreen(void) +static void atk50_openpartyscreen(void) { u32 flags; u8 hitmarkerFaintBits; @@ -5649,15 +5690,15 @@ void atk50_openpartyscreen(void) } } -void atk51_switch_handle_order(void) +static void atk51_switch_handle_order(void) { s32 i; if (gBattleExecBuffer) return; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - switch (BSScriptRead8(gBattlescriptCurrInstr + 2)) + switch (gBattlescriptCurrInstr[2]) { case 0: for (i = 0; i < gNoOfAllBanks; i++) @@ -5716,11 +5757,11 @@ void atk51_switch_handle_order(void) gBattlescriptCurrInstr += 3; } -void atk52_switch_in_effects(void) +static void atk52_switch_in_effects(void) { s32 i; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); sub_803FA70(gActiveBank); gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); @@ -5747,9 +5788,9 @@ void atk52_switch_in_effects(void) gBattleScripting.bank = gActiveBank; BattleScriptPushCursor(); - if (BSScriptRead8(gBattlescriptCurrInstr + 1) == 0) + if (gBattlescriptCurrInstr[1] == 0) gBattlescriptCurrInstr = gUnknown_082DAE90; - else if (BSScriptRead8(gBattlescriptCurrInstr + 1) == 1) + else if (gBattlescriptCurrInstr[1] == 1) gBattlescriptCurrInstr = gUnknown_082DAE59; else gBattlescriptCurrInstr = gUnknown_082DAEC7; @@ -5778,7 +5819,7 @@ void atk52_switch_in_effects(void) *hpOnSwitchout = gBattleMons[i].hp; } - if (BSScriptRead8(gBattlescriptCurrInstr + 1) == 5) + if (gBattlescriptCurrInstr[1] == 5) { u32 hitmarkerFaintBits = gHitMarker >> 0x1C; @@ -5797,7 +5838,7 @@ void atk52_switch_in_effects(void) } } -void atk53_trainer_slide(void) +static void atk53_trainer_slide(void) { gActiveBank = GetBankByIdentity(gBattlescriptCurrInstr[1]); EmitTrainerSlide(0); @@ -5806,7 +5847,7 @@ void atk53_trainer_slide(void) gBattlescriptCurrInstr += 2; } -void atk54_effectiveness_sound(void) +static void atk54_effectiveness_sound(void) { gActiveBank = gBankAttacker; EmitEffectivenessSound(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1)); @@ -5815,7 +5856,7 @@ void atk54_effectiveness_sound(void) gBattlescriptCurrInstr += 3; } -void atk55_play_sound(void) +static void atk55_play_sound(void) { gActiveBank = gBankAttacker; EmitPlaySound(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1), 0); @@ -5824,16 +5865,16 @@ void atk55_play_sound(void) gBattlescriptCurrInstr += 3; } -void atk56_fainting_cry(void) +static void atk56_fainting_cry(void) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); EmitFaintingCry(0); MarkBufferBankForExecution(gActiveBank); gBattlescriptCurrInstr += 2; } -void atk57(void) +static void atk57(void) { gActiveBank = GetBankByIdentity(0); Emit_x37(0, gBattleOutcome); @@ -5842,21 +5883,21 @@ void atk57(void) gBattlescriptCurrInstr += 1; } -void atk58_return_to_ball(void) +static void atk58_return_to_ball(void) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); EmitReturnPokeToBall(0, 1); MarkBufferBankForExecution(gActiveBank); gBattlescriptCurrInstr += 2; } -void atk59_learnmove_inbattle(void) +static void atk59_learnmove_inbattle(void) { const u8* jumpPtr1 = BSScriptReadPtr(gBattlescriptCurrInstr + 1); const u8* jumpPtr2 = BSScriptReadPtr(gBattlescriptCurrInstr + 5); - u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], BSScriptRead8(gBattlescriptCurrInstr + 9)); + u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], gBattlescriptCurrInstr[9]); while (ret == 0xFFFE) ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], 0); @@ -5891,7 +5932,7 @@ void atk59_learnmove_inbattle(void) } } -void atk5A_yesnoboxlearnmove(void) +static void atk5A_yesnoboxlearnmove(void) { gActiveBank = 0; @@ -6010,7 +6051,7 @@ void atk5A_yesnoboxlearnmove(void) } } -void atk5B_yesnoboxstoplearningmove(void) +static void atk5B_yesnoboxstoplearningmove(void) { switch (gBattleScripting.learnMoveState) { @@ -6057,9 +6098,9 @@ void atk5B_yesnoboxstoplearningmove(void) } } -void atk5C_hitanimation(void) +static void atk5C_hitanimation(void) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) { @@ -6134,7 +6175,7 @@ static u32 GetTrainerMoneyToGive(u16 trainerId) return moneyReward; } -void atk5D_getmoneyreward(void) +static void atk5D_getmoneyreward(void) { u32 moneyReward = GetTrainerMoneyToGive(gTrainerBattleOpponent_A); if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) @@ -6147,9 +6188,9 @@ void atk5D_getmoneyreward(void) gBattlescriptCurrInstr++; } -void atk5E_8025A70(void) +static void atk5E_8025A70(void) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); switch (gBattleCommunication[0]) { @@ -6174,7 +6215,7 @@ void atk5E_8025A70(void) } } -void atk5F_8025B24(void) +static void atk5F_8025B24(void) { gActiveBank = gBankAttacker; gBankAttacker = gBankTarget; @@ -6188,15 +6229,15 @@ void atk5F_8025B24(void) gBattlescriptCurrInstr++; } -void atk60_increment_gamestat(void) +static void atk60_increment_gamestat(void) { if (GetBankSide(gBankAttacker) == SIDE_PLAYER) - IncrementGameStat(BSScriptRead8(gBattlescriptCurrInstr + 1)); + IncrementGameStat(gBattlescriptCurrInstr[1]); gBattlescriptCurrInstr += 2; } -void atk61_8025BA4(void) +static void atk61_8025BA4(void) { s32 i; struct Pokemon* party; @@ -6205,7 +6246,7 @@ void atk61_8025BA4(void) if (gBattleExecBuffer) return; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (GetBankSide(gActiveBank) == SIDE_PLAYER) party = gPlayerParty; @@ -6233,18 +6274,18 @@ void atk61_8025BA4(void) gBattlescriptCurrInstr += 2; } -void atk62_08025C6C(void) +static void atk62_08025C6C(void) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); EmitCmd49(0); MarkBufferBankForExecution(gActiveBank); gBattlescriptCurrInstr += 2; } -void atk63_jumptorandomattack(void) +static void atk63_jumptorandomattack(void) { - if (BSScriptRead8(gBattlescriptCurrInstr + 1) != 0) + if (gBattlescriptCurrInstr[1] != 0) gCurrentMove = gRandomMove; else gLastUsedMove = gCurrentMove = gRandomMove; @@ -6252,11 +6293,11 @@ void atk63_jumptorandomattack(void) gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; } -void atk64_statusanimation(void) +static void atk64_statusanimation(void) { if (gBattleExecBuffer == 0) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBank].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) @@ -6268,13 +6309,13 @@ void atk64_statusanimation(void) } } -void atk65_status2animation(void) +static void atk65_status2animation(void) { u32 wantedToAnimate; if (gBattleExecBuffer == 0) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); wantedToAnimate = BSScriptRead32(gBattlescriptCurrInstr + 2); if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBank].substituteHP == 0 @@ -6287,26 +6328,26 @@ void atk65_status2animation(void) } } -void atk66_chosenstatusanimation(void) +static void atk66_chosenstatusanimation(void) { u32 wantedStatus; if (gBattleExecBuffer == 0) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); wantedStatus = BSScriptRead32(gBattlescriptCurrInstr + 3); if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBank].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) { - EmitStatusAnimation(0, BSScriptRead8(gBattlescriptCurrInstr + 2), wantedStatus); + EmitStatusAnimation(0, gBattlescriptCurrInstr[2], wantedStatus); MarkBufferBankForExecution(gActiveBank); } gBattlescriptCurrInstr += 7; } } -void atk67_yesnobox(void) +static void atk67_yesnobox(void) { switch (gBattleCommunication[0]) { @@ -6349,7 +6390,7 @@ void atk67_yesnobox(void) } } -void atk68_80246A0(void) +static void atk68_80246A0(void) { s32 i; @@ -6359,7 +6400,7 @@ void atk68_80246A0(void) gBattlescriptCurrInstr++; } -void atk69_dmg_adjustment3(void) // The same as 0x7, except there's no random damage multiplier. +static void atk69_dmg_adjustment3(void) // The same as 0x7, except there's no random damage multiplier. { u8 holdEffect, quality; @@ -6405,11 +6446,11 @@ void atk69_dmg_adjustment3(void) // The same as 0x7, except there's no random da gBattlescriptCurrInstr++; } -void atk6A_removeitem(void) +static void atk6A_removeitem(void) { u16* usedHeldItem; - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBank]; *usedHeldItem = gBattleMons[gActiveBank].item; @@ -6421,19 +6462,14 @@ void atk6A_removeitem(void) gBattlescriptCurrInstr += 2; } -void atk6B_atknameinbuff1(void) +static void atk6B_atknameinbuff1(void) { PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBankAttacker, gBattlePartyID[gBankAttacker]) gBattlescriptCurrInstr++; } -extern u16 gBattle_BG1_X; -extern u16 gBattle_BG1_Y; -extern u16 gBattle_BG2_X; -extern u16 gBattle_BG2_Y; - -void atk6C_draw_lvlupbox(void) +static void atk6C_draw_lvlupbox(void) { if (gBattleScripting.atk6C_state == 0) { @@ -6525,7 +6561,7 @@ void atk6C_draw_lvlupbox(void) } } -void sub_804F100(void) +static void sub_804F100(void) { struct StatsArray currentStats; @@ -6533,7 +6569,7 @@ void sub_804F100(void) sub_81D3640(0xD, gBattleResources->statsBeforeLvlUp, ¤tStats, 0xE, 0xD, 0xF); } -void sub_804F144(void) +static void sub_804F144(void) { struct StatsArray currentStats; @@ -6541,10 +6577,7 @@ void sub_804F144(void) sub_81D3784(0xD, ¤tStats, 0xE, 0xD, 0xF); } -extern const u16 gUnknown_0831C2C8[]; -extern const u8 gUnknown_0831C2E8[]; - -void sub_804F17C(void) +static void sub_804F17C(void) { gBattle_BG2_Y = 0; gBattle_BG2_X = 0x1A0; @@ -6557,7 +6590,7 @@ void sub_804F17C(void) PutMonIconOnLvlUpBox(); } -bool8 sub_804F1CC(void) +static bool8 sub_804F1CC(void) { if (IsDma3ManagerBusyWithBgCopy()) return TRUE; @@ -6575,7 +6608,7 @@ bool8 sub_804F1CC(void) return (gBattle_BG2_X != 0x200); } -void PutLevelAndGenderOnLvlUpBox(void) +static void PutLevelAndGenderOnLvlUpBox(void) { u16 monLevel; u8 monGender; @@ -6638,7 +6671,7 @@ void PutLevelAndGenderOnLvlUpBox(void) CopyWindowToVram(14, 2); } -bool8 sub_804F344(void) +static bool8 sub_804F344(void) { if (gBattle_BG2_X == 0x1A0) return FALSE; @@ -6656,7 +6689,7 @@ bool8 sub_804F344(void) #define sDestroy data0 #define sSavedLvlUpBoxXPosition data1 -void PutMonIconOnLvlUpBox(void) +static void PutMonIconOnLvlUpBox(void) { u8 spriteId; const u16* iconPal; @@ -6702,7 +6735,7 @@ void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite) #undef sDestroy #undef sSavedLvlUpBoxXPosition -bool32 IsMonGettingExpSentOut(void) +static bool32 IsMonGettingExpSentOut(void) { if (gBattlePartyID[0] == gBattleStruct->expGetterId) return TRUE; @@ -6712,30 +6745,30 @@ bool32 IsMonGettingExpSentOut(void) return FALSE; } -void atk6D_reset_sentpokes_value(void) +static void atk6D_reset_sentpokes_value(void) { ResetSentPokesToOpponentValue(); gBattlescriptCurrInstr++; } -void atk6E_set_atk_to_player0(void) +static void atk6E_set_atk_to_player0(void) { gBankAttacker = GetBankByIdentity(0); gBattlescriptCurrInstr++; } -void atk6F_set_visible(void) +static void atk6F_set_visible(void) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); EmitSpriteInvisibility(0, FALSE); MarkBufferBankForExecution(gActiveBank); gBattlescriptCurrInstr += 2; } -void atk70_record_last_used_ability(void) +static void atk70_record_last_used_ability(void) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); RecordAbilityBattle(gActiveBank, gLastUsedAbility); gBattlescriptCurrInstr += 1; // UB: Should be + 2, one byte for command and one byte for bank argument. } @@ -6745,13 +6778,13 @@ void BufferMoveToLearnIntoBattleTextBuff2(void) PREPARE_MOVE_BUFFER(gBattleTextBuff2, gMoveToLearn); } -void atk71_buffer_move_to_learn(void) +static void atk71_buffer_move_to_learn(void) { BufferMoveToLearnIntoBattleTextBuff2(); gBattlescriptCurrInstr++; } -void atk72_jump_if_can_run_frombattle(void) +static void atk72_jump_if_can_run_frombattle(void) { if (CanRunFromBattle(gBank1)) gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); @@ -6759,14 +6792,14 @@ void atk72_jump_if_can_run_frombattle(void) gBattlescriptCurrInstr += 5; } -void atk73_hp_thresholds(void) +static void atk73_hp_thresholds(void) { u8 opposingBank; s32 result; if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); opposingBank = gActiveBank ^ BIT_SIDE; result = gBattleMons[opposingBank].hp * 100 / gBattleMons[opposingBank].maxHP; @@ -6786,7 +6819,7 @@ void atk73_hp_thresholds(void) gBattlescriptCurrInstr += 2; } -void atk74_hp_thresholds2(void) +static void atk74_hp_thresholds2(void) { u8 opposingBank; s32 result; @@ -6794,7 +6827,7 @@ void atk74_hp_thresholds2(void) if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); opposingBank = gActiveBank ^ BIT_SIDE; hpSwitchout = *(gBattleStruct->hpOnSwitchout + GetBankSide(opposingBank)); result = (hpSwitchout - gBattleMons[opposingBank].hp) * 100 / hpSwitchout; @@ -6812,7 +6845,7 @@ void atk74_hp_thresholds2(void) gBattlescriptCurrInstr += 2; } -void atk75_item_effect_on_opponent(void) +static void atk75_item_effect_on_opponent(void) { gBankInMenu = gBankAttacker; ExecuteTableBasedItemEffect(&gEnemyParty[gBattlePartyID[gBankAttacker]], gLastUsedItem, gBattlePartyID[gBankAttacker], 0, 1); @@ -6820,10 +6853,7 @@ void atk75_item_effect_on_opponent(void) gBattlescriptCurrInstr += 1; } -extern const u8 gUnknown_0831C4F8[]; -extern const u8* const gRefereeStringsTable[]; - -void atk76_various(void) +static void atk76_various(void) { u8 side; s32 i; @@ -7002,7 +7032,7 @@ void atk76_various(void) gBattlescriptCurrInstr += 3; } -void atk77_set_protect_like(void) // protect and endure +static void atk77_set_protect_like(void) // protect and endure { bool8 notLastTurn = TRUE; u16 lastMove = gUnknown_02024260[gBankAttacker]; @@ -7037,7 +7067,7 @@ void atk77_set_protect_like(void) // protect and endure gBattlescriptCurrInstr++; } -void atk78_faintifabilitynotdamp(void) +static void atk78_faintifabilitynotdamp(void) { if (gBattleExecBuffer) return; @@ -7072,7 +7102,7 @@ void atk78_faintifabilitynotdamp(void) } } -void atk79_setatkhptozero(void) +static void atk79_setatkhptozero(void) { if (gBattleExecBuffer) return; @@ -7085,7 +7115,7 @@ void atk79_setatkhptozero(void) gBattlescriptCurrInstr++; } -void atk7A_jumpwhiletargetvalid(void) // Used by intimidate to loop through all targets. +static void atk7A_jumpwhiletargetvalid(void) // Used by intimidate to loop through all targets. { const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); @@ -7108,11 +7138,11 @@ void atk7A_jumpwhiletargetvalid(void) // Used by intimidate to loop through all gBattlescriptCurrInstr += 5; } -void atk7B_healhalfHP_if_possible(void) +static void atk7B_healhalfHP_if_possible(void) { const u8* failPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - if (BSScriptRead8(gBattlescriptCurrInstr + 5) == BS_GET_ATTACKER) + if (gBattlescriptCurrInstr[5] == BS_GET_ATTACKER) gBankTarget = gBankAttacker; gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; @@ -7126,7 +7156,7 @@ void atk7B_healhalfHP_if_possible(void) gBattlescriptCurrInstr += 6; } -void atk7C_trymirrormove(void) +static void atk7C_trymirrormove(void) { s32 validMovesCount; s32 i; @@ -7176,7 +7206,7 @@ void atk7C_trymirrormove(void) } } -void atk7D_set_rain(void) +static void atk7D_set_rain(void) { if (gBattleWeather & WEATHER_RAIN_ANY) { @@ -7192,7 +7222,7 @@ void atk7D_set_rain(void) gBattlescriptCurrInstr++; } -void atk7E_setreflect(void) +static void atk7E_setreflect(void) { if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_REFLECT) { @@ -7213,7 +7243,7 @@ void atk7E_setreflect(void) gBattlescriptCurrInstr++; } -void atk7F_setseeded(void) +static void atk7F_setseeded(void) { if (gBattleMoveFlags & MOVESTATUS_NOEFFECT || gStatuses3[gBankTarget] & STATUS3_LEECHSEED) { @@ -7235,9 +7265,9 @@ void atk7F_setseeded(void) gBattlescriptCurrInstr++; } -void atk80_manipulatedamage(void) +static void atk80_manipulatedamage(void) { - switch (BSScriptRead8(gBattlescriptCurrInstr + 1)) + switch (gBattlescriptCurrInstr[1]) { case ATK80_DMG_CHANGE_SIGN: gBattleMoveDamage *= -1; @@ -7257,7 +7287,7 @@ void atk80_manipulatedamage(void) gBattlescriptCurrInstr += 2; } -void atk81_setrest(void) +static void atk81_setrest(void) { const u8* failJump = BSScriptReadPtr(gBattlescriptCurrInstr + 1); gActiveBank = gBankTarget = gBankAttacker; @@ -7281,7 +7311,7 @@ void atk81_setrest(void) } } -void atk82_jumpifnotfirstturn(void) +static void atk82_jumpifnotfirstturn(void) { const u8* failJump = BSScriptReadPtr(gBattlescriptCurrInstr + 1); @@ -7291,7 +7321,7 @@ void atk82_jumpifnotfirstturn(void) gBattlescriptCurrInstr = failJump; } -void atk83_nop(void) +static void atk83_nop(void) { gBattlescriptCurrInstr++; } @@ -7323,7 +7353,7 @@ bool8 UproarWakeUpCheck(u8 bank) return TRUE; } -void atk84_jump_if_cant_sleep(void) +static void atk84_jump_if_cant_sleep(void) { const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); @@ -7345,7 +7375,7 @@ void atk84_jump_if_cant_sleep(void) } } -void atk85_stockpile(void) +static void atk85_stockpile(void) { if (gDisableStructs[gBankAttacker].stockpileCounter == 3) { @@ -7363,7 +7393,7 @@ void atk85_stockpile(void) gBattlescriptCurrInstr++; } -void atk86_stockpiletobasedamage(void) +static void atk86_stockpiletobasedamage(void) { const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); if (gDisableStructs[gBankAttacker].stockpileCounter == 0) @@ -7389,7 +7419,7 @@ void atk86_stockpiletobasedamage(void) } } -void atk87_stockpiletohpheal(void) +static void atk87_stockpiletohpheal(void) { const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); @@ -7420,7 +7450,7 @@ void atk87_stockpiletohpheal(void) } } -void atk88_negativedamage(void) +static void atk88_negativedamage(void) { gBattleMoveDamage = -(gHpDealt / 2); if (gBattleMoveDamage == 0) @@ -7429,7 +7459,7 @@ void atk88_negativedamage(void) gBattlescriptCurrInstr++; } -u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8* BS_ptr) +static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8* BS_ptr) { bool8 certain = 0; bool8 notProtectAffected = FALSE; @@ -7599,14 +7629,14 @@ u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8* BS_ptr) return STAT_CHANGE_WORKED; } -void atk89_statbuffchange(void) +static void atk89_statbuffchange(void) { const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - if (ChangeStatBuffs(gBattleScripting.statChanger & 0xF0, GET_STAT_BUFF_ID(gBattleScripting.statChanger), BSScriptRead8(gBattlescriptCurrInstr + 1), jumpPtr) == STAT_CHANGE_WORKED) + if (ChangeStatBuffs(gBattleScripting.statChanger & 0xF0, GET_STAT_BUFF_ID(gBattleScripting.statChanger), gBattlescriptCurrInstr[1], jumpPtr) == STAT_CHANGE_WORKED) gBattlescriptCurrInstr += 6; } -void atk8A_normalisebuffs(void) // haze +static void atk8A_normalisebuffs(void) // haze { s32 i, j; @@ -7619,7 +7649,7 @@ void atk8A_normalisebuffs(void) // haze gBattlescriptCurrInstr++; } -void atk8B_setbide(void) +static void atk8B_setbide(void) { gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; gLockedMoves[gBankAttacker] = gCurrentMove; @@ -7629,7 +7659,7 @@ void atk8B_setbide(void) gBattlescriptCurrInstr++; } -void atk8C_confuseifrepeatingattackends(void) +static void atk8C_confuseifrepeatingattackends(void) { if (!(gBattleMons[gBankAttacker].status2 & STATUS2_LOCK_CONFUSE)) gBattleCommunication[MOVE_EFFECT_BYTE] = (MOVE_EFFECT_THRASH | MOVE_EFFECT_AFFECTS_USER); @@ -7637,11 +7667,11 @@ void atk8C_confuseifrepeatingattackends(void) gBattlescriptCurrInstr++; } -void atk8D_setmultihit_counter(void) +static void atk8D_setmultihit_counter(void) { - if (BSScriptRead8(gBattlescriptCurrInstr + 1)) + if (gBattlescriptCurrInstr[1]) { - gMultiHitCounter = BSScriptRead8(gBattlescriptCurrInstr + 1); + gMultiHitCounter = gBattlescriptCurrInstr[1]; } else { @@ -7655,14 +7685,14 @@ void atk8D_setmultihit_counter(void) gBattlescriptCurrInstr += 2; } -void atk8E_init_multihit_string(void) +static void atk8E_init_multihit_string(void) { PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) gBattlescriptCurrInstr++; } -bool8 sub_8051064(void) +static bool8 sub_8051064(void) { if (gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) { @@ -7683,7 +7713,7 @@ bool8 sub_8051064(void) return TRUE; } -void atk8F_forcerandomswitch(void) +static void atk8F_forcerandomswitch(void) { s32 i; s32 bank1PartyId = 0; @@ -7844,7 +7874,7 @@ void atk8F_forcerandomswitch(void) } } -void atk90_conversion_type_change(void) // randomly changes user's type to one of its moves' type +static void atk90_conversion_type_change(void) // randomly changes user's type to one of its moves' type { u8 validMoves = 0; u8 moveChecked; @@ -7908,7 +7938,7 @@ void atk90_conversion_type_change(void) // randomly changes user's type to one o } } -void atk91_givepaydaymoney(void) +static void atk91_givepaydaymoney(void) { if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) && gPaydayMoney != 0) { @@ -7926,7 +7956,7 @@ void atk91_givepaydaymoney(void) } } -void atk92_setlightscreen(void) +static void atk92_setlightscreen(void) { if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_LIGHTSCREEN) { @@ -7948,7 +7978,7 @@ void atk92_setlightscreen(void) gBattlescriptCurrInstr++; } -void atk93_ko_move(void) +static void atk93_ko_move(void) { u8 holdEffect, param; @@ -8034,7 +8064,7 @@ void atk93_ko_move(void) } } -void atk94_damagetohalftargethp(void) // super fang +static void atk94_damagetohalftargethp(void) // super fang { gBattleMoveDamage = gBattleMons[gBankTarget].hp / 2; if (gBattleMoveDamage == 0) @@ -8043,7 +8073,7 @@ void atk94_damagetohalftargethp(void) // super fang gBattlescriptCurrInstr++; } -void atk95_setsandstorm(void) +static void atk95_setsandstorm(void) { if (gBattleWeather & WEATHER_SANDSTORM_ANY) { @@ -8059,7 +8089,7 @@ void atk95_setsandstorm(void) gBattlescriptCurrInstr++; } -void atk96_weatherdamage(void) +static void atk96_weatherdamage(void) { if (WEATHER_HAS_EFFECT) { @@ -8112,7 +8142,7 @@ void atk96_weatherdamage(void) gBattlescriptCurrInstr++; } -void atk97_try_infatuation(void) +static void atk97_try_infatuation(void) { struct Pokemon *monAttacker, *monTarget; u16 speciesAttacker, speciesTarget; @@ -8157,14 +8187,14 @@ void atk97_try_infatuation(void) } } -void atk98_status_icon_update(void) +static void atk98_status_icon_update(void) { if (gBattleExecBuffer) return; - if (BSScriptRead8(gBattlescriptCurrInstr + 1) != BS_ATTACKER_WITH_PARTNER) + if (gBattlescriptCurrInstr[1] != BS_ATTACKER_WITH_PARTNER) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); EmitStatusIconUpdate(0, gBattleMons[gActiveBank].status1, gBattleMons[gActiveBank].status2); MarkBufferBankForExecution(gActiveBank); gBattlescriptCurrInstr += 2; @@ -8190,7 +8220,7 @@ void atk98_status_icon_update(void) } } -void atk99_setmist(void) +static void atk99_setmist(void) { if (gSideTimers[GET_BANK_SIDE(gBankAttacker)].mistTimer) { @@ -8207,7 +8237,7 @@ void atk99_setmist(void) gBattlescriptCurrInstr++; } -void atk9A_set_focusenergy(void) +static void atk9A_set_focusenergy(void) { if (gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) { @@ -8222,7 +8252,7 @@ void atk9A_set_focusenergy(void) gBattlescriptCurrInstr++; } -void atk9B_transformdataexecution(void) +static void atk9B_transformdataexecution(void) { gLastUsedMove = 0xFFFF; gBattlescriptCurrInstr++; @@ -8266,7 +8296,7 @@ void atk9B_transformdataexecution(void) } } -void atk9C_set_substitute(void) +static void atk9C_set_substitute(void) { u32 hp = gBattleMons[gBankAttacker].maxHP / 4; if (gBattleMons[gBankAttacker].maxHP / 4 == 0) @@ -8293,11 +8323,6 @@ void atk9C_set_substitute(void) gBattlescriptCurrInstr++; } -extern const u16 gMovesForbiddenToCopy[]; -#define MIMIC_FORBIDDEN_END 0xFFFE -#define METRONOME_FORBIDDEN_END 0xFFFF -#define ASSIST_FORBIDDEN_END 0xFFFF - static bool8 IsMoveUncopyableByMimic(u16 move) { s32 i; @@ -8307,7 +8332,7 @@ static bool8 IsMoveUncopyableByMimic(u16 move) return (gMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END); } -void atk9D_mimicattackcopy(void) +static void atk9D_mimicattackcopy(void) { gLastUsedMove = 0xFFFF; @@ -8350,7 +8375,7 @@ void atk9D_mimicattackcopy(void) } #ifdef NONMATCHING -void atk9E_metronome(void) +static void atk9E_metronome(void) { while (1) { @@ -8382,7 +8407,7 @@ void atk9E_metronome(void) #else __attribute__((naked)) -void atk9E_metronome(void) +static void atk9E_metronome(void) { asm( "\n\ @@ -8459,13 +8484,13 @@ _0805251C:\n\ #endif // NONMATCHING -void atk9F_dmgtolevel(void) +static void atk9F_dmgtolevel(void) { gBattleMoveDamage = gBattleMons[gBankAttacker].level; gBattlescriptCurrInstr++; } -void atkA0_psywavedamageeffect(void) +static void atkA0_psywavedamageeffect(void) { s32 randDamage; @@ -8476,7 +8501,7 @@ void atkA0_psywavedamageeffect(void) gBattlescriptCurrInstr++; } -void atkA1_counterdamagecalculator(void) +static void atkA1_counterdamagecalculator(void) { u8 sideAttacker = GetBankSide(gBankAttacker); u8 sideTarget = GetBankSide(gProtectStructs[gBankAttacker].physicalBank); @@ -8501,7 +8526,7 @@ void atkA1_counterdamagecalculator(void) } } -void atkA2_mirrorcoatdamagecalculator(void) // a copy of atkA1 with the physical -> special field changes +static void atkA2_mirrorcoatdamagecalculator(void) // a copy of atkA1 with the physical -> special field changes { u8 sideAttacker = GetBankSide(gBankAttacker); u8 sideTarget = GetBankSide(gProtectStructs[gBankAttacker].specialBank); @@ -8524,7 +8549,7 @@ void atkA2_mirrorcoatdamagecalculator(void) // a copy of atkA1 with the physical } } -void atkA3_disablelastusedattack(void) +static void atkA3_disablelastusedattack(void) { s32 i; @@ -8549,7 +8574,7 @@ void atkA3_disablelastusedattack(void) } } -void atkA4_setencore(void) +static void atkA4_setencore(void) { s32 i; @@ -8581,7 +8606,7 @@ void atkA4_setencore(void) } } -void atkA5_painsplitdmgcalc(void) +static void atkA5_painsplitdmgcalc(void) { if (!(gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE)) { @@ -8606,7 +8631,7 @@ void atkA5_painsplitdmgcalc(void) } #ifdef NONMATCHING -void atkA6_settypetorandomresistance(void) // conversion 2 +static void atkA6_settypetorandomresistance(void) // conversion 2 { if (gUnknown_02024250[gBankAttacker] == 0 || gUnknown_02024250[gBankAttacker] == 0xFFFF) @@ -8673,7 +8698,7 @@ void atkA6_settypetorandomresistance(void) // conversion 2 #else __attribute__((naked)) -void atkA6_settypetorandomresistance(void) // conversion 2 +static void atkA6_settypetorandomresistance(void) // conversion 2 { asm(".syntax unified\n\ push {r4-r7,lr}\n\ @@ -8912,7 +8937,7 @@ _08052D08:\n\ } #endif // NONMATCHING -void atkA7_setalwayshitflag(void) +static void atkA7_setalwayshitflag(void) { gStatuses3[gBankTarget] &= ~(STATUS3_ALWAYS_HITS); gStatuses3[gBankTarget] |= 0x10; @@ -8920,7 +8945,7 @@ void atkA7_setalwayshitflag(void) gBattlescriptCurrInstr++; } -void atkA8_copymovepermanently(void) // sketch +static void atkA8_copymovepermanently(void) // sketch { gLastUsedMove = 0xFFFF; @@ -8973,7 +8998,7 @@ void atkA8_copymovepermanently(void) // sketch } } -bool8 IsTwoTurnsMove(u16 move) +static bool8 IsTwoTurnsMove(u16 move) { if (gBattleMoves[move].effect == EFFECT_SKULL_BASH || gBattleMoves[move].effect == EFFECT_RAZOR_WIND @@ -8995,7 +9020,7 @@ static bool8 IsInvalidForSleepTalkOrAssist(u16 move) return FALSE; } -u8 AttacksThisTurn(u8 bank, u16 move) // Note: returns 1 if it's a charging turn, otherwise 2 +static u8 AttacksThisTurn(u8 bank, u16 move) // Note: returns 1 if it's a charging turn, otherwise 2 { // first argument is unused if (gBattleMoves[move].effect == EFFECT_SOLARBEAM @@ -9015,7 +9040,7 @@ u8 AttacksThisTurn(u8 bank, u16 move) // Note: returns 1 if it's a charging turn return 2; } -void atkA9_sleeptalk_choose_move(void) +static void atkA9_sleeptalk_choose_move(void) { s32 i; u8 unusableMovesBits = 0; @@ -9054,13 +9079,13 @@ void atkA9_sleeptalk_choose_move(void) } } -void atkAA_set_destinybond(void) +static void atkAA_set_destinybond(void) { gBattleMons[gBankAttacker].status2 |= STATUS2_DESTINY_BOND; gBattlescriptCurrInstr++; } -void DestinyBondFlagUpdate(void) +static void DestinyBondFlagUpdate(void) { u8 sideAttacker = GetBankSide(gBankAttacker); u8 sideTarget = GetBankSide(gBankTarget); @@ -9072,15 +9097,13 @@ void DestinyBondFlagUpdate(void) } } -void atkAB_DestinyBondFlagUpdate(void) +static void atkAB_DestinyBondFlagUpdate(void) { DestinyBondFlagUpdate(); gBattlescriptCurrInstr++; } -extern const u8 sFlailHpScaleToPowerTable[12]; - -void atkAC_remaininghptopower(void) +static void atkAC_remaininghptopower(void) { s32 i; s32 hpFraction = GetScaledHPFraction(gBattleMons[gBankAttacker].hp, gBattleMons[gBankAttacker].maxHP, 48); @@ -9095,7 +9118,7 @@ void atkAC_remaininghptopower(void) gBattlescriptCurrInstr++; } -void atkAD_spite_ppreduce(void) +static void atkAD_spite_ppreduce(void) { if (gLastUsedMovesByBanks[gBankTarget] != 0 && gLastUsedMovesByBanks[gBankTarget] != 0xFFFF) @@ -9146,7 +9169,7 @@ void atkAD_spite_ppreduce(void) } } -void atkAE_heal_party_status(void) +static void atkAE_heal_party_status(void) { u32 zero = 0; u8 toHeal = 0; @@ -9242,7 +9265,7 @@ void atkAE_heal_party_status(void) gBattlescriptCurrInstr++; } -void atkAF_cursetarget(void) +static void atkAF_cursetarget(void) { if (gBattleMons[gBankTarget].status2 & STATUS2_CURSED) { @@ -9259,7 +9282,7 @@ void atkAF_cursetarget(void) } } -void atkB0_set_spikes(void) +static void atkB0_set_spikes(void) { u8 targetSide = GetBankSide(gBankAttacker) ^ BIT_SIDE; @@ -9276,13 +9299,13 @@ void atkB0_set_spikes(void) } } -void atkB1_set_foresight(void) +static void atkB1_set_foresight(void) { gBattleMons[gBankTarget].status2 |= STATUS2_FORESIGHT; gBattlescriptCurrInstr++; } -void atkB2_setperishsong(void) +static void atkB2_setperishsong(void) { s32 i; s32 notAffectedCount = 0; @@ -9310,7 +9333,7 @@ void atkB2_setperishsong(void) gBattlescriptCurrInstr += 5; } -void atkB3_rolloutdamagecalculation(void) +static void atkB3_rolloutdamagecalculation(void) { if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) { @@ -9345,7 +9368,7 @@ void atkB3_rolloutdamagecalculation(void) } } -void atkB4_jumpifconfusedandstatmaxed(void) +static void atkB4_jumpifconfusedandstatmaxed(void) { if (gBattleMons[gBankTarget].status2 & STATUS2_CONFUSION && gBattleMons[gBankTarget].statStages[gBattlescriptCurrInstr[1]] == 0xC) @@ -9354,7 +9377,7 @@ void atkB4_jumpifconfusedandstatmaxed(void) gBattlescriptCurrInstr += 6; } -void atkB5_furycuttercalc(void) +static void atkB5_furycuttercalc(void) { if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) { @@ -9377,7 +9400,7 @@ void atkB5_furycuttercalc(void) } } -void atkB6_happinesstodamagecalculation(void) +static void atkB6_happinesstodamagecalculation(void) { if (gBattleMoves[gCurrentMove].effect == EFFECT_RETURN) gDynamicBasePower = 10 * (gBattleMons[gBankAttacker].friendship) / 25; @@ -9387,11 +9410,7 @@ void atkB6_happinesstodamagecalculation(void) gBattlescriptCurrInstr++; } -extern const u8 BattleScript_PresentDamageTarget[]; -extern const u8 BattleScript_AlreadyAtFullHp[]; -extern const u8 BattleScript_PresentHealTarget[]; - -void atkB7_presentdamagecalculation(void) +static void atkB7_presentdamagecalculation(void) { s32 rand = Random() & 0xFF; @@ -9419,7 +9438,7 @@ void atkB7_presentdamagecalculation(void) } } -void atkB8_set_safeguard(void) +static void atkB8_set_safeguard(void) { if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_SAFEGUARD) { @@ -9437,7 +9456,7 @@ void atkB8_set_safeguard(void) gBattlescriptCurrInstr++; } -void atkB9_magnitudedamagecalculation(void) +static void atkB9_magnitudedamagecalculation(void) { s32 magnitude = Random() % 100; @@ -9491,7 +9510,7 @@ void atkB9_magnitudedamagecalculation(void) gBattlescriptCurrInstr++; } -void atkBA_jumpifnopursuitswitchdmg(void) +static void atkBA_jumpifnopursuitswitchdmg(void) { if (gMultiHitCounter == 1) { @@ -9535,7 +9554,7 @@ void atkBA_jumpifnopursuitswitchdmg(void) } } -void atkBB_setsunny(void) +static void atkBB_setsunny(void) { if (gBattleWeather & WEATHER_SUN_ANY) { @@ -9552,7 +9571,7 @@ void atkBB_setsunny(void) gBattlescriptCurrInstr++; } -void atkBC_maxattackhalvehp(void) // belly drum +static void atkBC_maxattackhalvehp(void) // belly drum { u32 halfHp = gBattleMons[gBankAttacker].maxHP / 2; @@ -9575,7 +9594,7 @@ void atkBC_maxattackhalvehp(void) // belly drum } } -void atkBD_copyfoestats(void) // psych up +static void atkBD_copyfoestats(void) // psych up { s32 i; @@ -9587,11 +9606,7 @@ void atkBD_copyfoestats(void) // psych up gBattlescriptCurrInstr += 5; // Has an unused jump ptr(possibly for a failed attempt) parameter. } -extern const u8 BattleScript_WrapFree[]; -extern const u8 BattleScript_LeechSeedFree[]; -extern const u8 BattleScript_SpikesFree[]; - -void atkBE_rapidspinfree(void) +static void atkBE_rapidspinfree(void) { if (gBattleMons[gBankAttacker].status2 & STATUS2_WRAPPED) { @@ -9628,13 +9643,13 @@ void atkBE_rapidspinfree(void) } } -void atkBF_set_defense_curl(void) +static void atkBF_set_defense_curl(void) { gBattleMons[gBankAttacker].status2 |= STATUS2_DEFENSE_CURL; gBattlescriptCurrInstr++; } -void atkC0_recoverbasedonsunlight(void) +static void atkC0_recoverbasedonsunlight(void) { gBankTarget = gBankAttacker; @@ -9660,7 +9675,7 @@ void atkC0_recoverbasedonsunlight(void) } #ifdef NONMATCHING -void atkC1_hidden_power(void) +static void atkC1_hidden_power(void) { s32 powerBits; s32 typeBits; @@ -9691,7 +9706,7 @@ void atkC1_hidden_power(void) #else __attribute__((naked)) -void atkC1_hidden_power(void) +static void atkC1_hidden_power(void) { asm(".syntax unified\n\ push {r4-r7,lr}\n\ @@ -9834,7 +9849,7 @@ _080544F0:\n\ } #endif // NONMATCHING -void atkC2_selectnexttarget(void) +static void atkC2_selectnexttarget(void) { for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) { @@ -9846,7 +9861,7 @@ void atkC2_selectnexttarget(void) gBattlescriptCurrInstr++; } -void atkC3_setfutureattack(void) +static void atkC3_setfutureattack(void) { if (gWishFutureKnock.futureSightCounter[gBankTarget] != 0) { @@ -9874,7 +9889,7 @@ void atkC3_setfutureattack(void) } } -void atkC4_beat_up(void) +static void atkC4_beat_up(void) { struct Pokemon* party; @@ -9921,7 +9936,7 @@ void atkC4_beat_up(void) } } -void atkC5_setsemiinvulnerablebit(void) +static void atkC5_setsemiinvulnerablebit(void) { switch (gCurrentMove) { @@ -9940,7 +9955,7 @@ void atkC5_setsemiinvulnerablebit(void) gBattlescriptCurrInstr++; } -void atkC6_clearsemiinvulnerablebit(void) +static void atkC6_clearsemiinvulnerablebit(void) { switch (gCurrentMove) { @@ -9959,7 +9974,7 @@ void atkC6_clearsemiinvulnerablebit(void) gBattlescriptCurrInstr++; } -void atkC7_setminimize(void) +static void atkC7_setminimize(void) { if (gHitMarker & HITMARKER_OBEYS) gStatuses3[gBankAttacker] |= STATUS3_MINIMIZED; @@ -9967,7 +9982,7 @@ void atkC7_setminimize(void) gBattlescriptCurrInstr++; } -void atkC8_sethail(void) +static void atkC8_sethail(void) { if (gBattleWeather & WEATHER_HAIL_ANY) { @@ -9984,7 +9999,7 @@ void atkC8_sethail(void) gBattlescriptCurrInstr++; } -void atkC9_jumpifattackandspecialattackcannotfall(void) // memento +static void atkC9_jumpifattackandspecialattackcannotfall(void) // memento { if (gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] == 0 && gBattleMons[gBankTarget].statStages[STAT_STAGE_SPATK] == 0 @@ -10002,14 +10017,14 @@ void atkC9_jumpifattackandspecialattackcannotfall(void) // memento } } -void atkCA_setforcedtarget(void) // follow me +static void atkCA_setforcedtarget(void) // follow me { gSideTimers[GetBankSide(gBankAttacker)].followmeTimer = 1; gSideTimers[GetBankSide(gBankAttacker)].followmeTarget = gBankAttacker; gBattlescriptCurrInstr++; } -void atkCB_setcharge(void) +static void atkCB_setcharge(void) { gStatuses3[gBankAttacker] |= STATUS3_CHARGED_UP; gDisableStructs[gBankAttacker].chargeTimer1 = 2; @@ -10017,7 +10032,7 @@ void atkCB_setcharge(void) gBattlescriptCurrInstr++; } -void atkCC_callterrainattack(void) // nature power +static void atkCC_callterrainattack(void) // nature power { gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); gCurrentMove = sNaturePowerMoves[gBattleTerrain]; @@ -10026,7 +10041,7 @@ void atkCC_callterrainattack(void) // nature power gBattlescriptCurrInstr++; } -void atkCD_cureifburnedparalysedorpoisoned(void) // refresh +static void atkCD_cureifburnedparalysedorpoisoned(void) // refresh { if (gBattleMons[gBankAttacker].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON)) { @@ -10042,7 +10057,7 @@ void atkCD_cureifburnedparalysedorpoisoned(void) // refresh } } -void atkCE_settorment(void) +static void atkCE_settorment(void) { if (gBattleMons[gBankTarget].status2 & STATUS2_TORMENT) { @@ -10055,7 +10070,7 @@ void atkCE_settorment(void) } } -void atkCF_jumpifnodamage(void) +static void atkCF_jumpifnodamage(void) { if (gProtectStructs[gBankAttacker].physicalDmg || gProtectStructs[gBankAttacker].specialDmg) gBattlescriptCurrInstr += 5; @@ -10063,7 +10078,7 @@ void atkCF_jumpifnodamage(void) gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); } -void atkD0_settaunt(void) +static void atkD0_settaunt(void) { if (gDisableStructs[gBankTarget].tauntTimer1 == 0) { @@ -10077,7 +10092,7 @@ void atkD0_settaunt(void) } } -void atkD1_set_helpinghand(void) +static void atkD1_set_helpinghand(void) { gBankTarget = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); @@ -10095,7 +10110,7 @@ void atkD1_set_helpinghand(void) } } -void atkD2_swap_items(void) // trick +static void atkD2_swap_items(void) // trick { // opponent can't swap items with player in regular battles if (gBattleTypeFlags & BATTLE_TYPE_x4000000 @@ -10182,7 +10197,7 @@ void atkD2_swap_items(void) // trick } } -void atkD3_copy_ability(void) // role play +static void atkD3_copy_ability(void) // role play { if (gBattleMons[gBankTarget].ability != 0 && gBattleMons[gBankTarget].ability != ABILITY_WONDER_GUARD) @@ -10197,9 +10212,9 @@ void atkD3_copy_ability(void) // role play } } -void atkD4_wish_effect(void) +static void atkD4_wish_effect(void) { - switch (BSScriptRead8(gBattlescriptCurrInstr + 1)) + switch (gBattlescriptCurrInstr[1]) { case 0: // use wish if (gWishFutureKnock.wishCounter[gBankAttacker] == 0) @@ -10230,7 +10245,7 @@ void atkD4_wish_effect(void) } } -void atkD5_setroots(void) // ingrain +static void atkD5_setroots(void) // ingrain { if (gStatuses3[gBankAttacker] & STATUS3_ROOTED) { @@ -10243,7 +10258,7 @@ void atkD5_setroots(void) // ingrain } } -void atkD6_doubledamagedealtifdamaged(void) +static void atkD6_doubledamagedealtifdamaged(void) { if ((gProtectStructs[gBankAttacker].physicalDmg && gProtectStructs[gBankAttacker].physicalBank == gBankTarget) @@ -10256,7 +10271,7 @@ void atkD6_doubledamagedealtifdamaged(void) gBattlescriptCurrInstr++; } -void atkD7_setyawn(void) +static void atkD7_setyawn(void) { if (gStatuses3[gBankTarget] & STATUS3_YAWN || gBattleMons[gBankTarget].status1 & STATUS_ANY) @@ -10270,7 +10285,7 @@ void atkD7_setyawn(void) } } -void atkD8_setdamagetohealthdifference(void) +static void atkD8_setdamagetohealthdifference(void) { if (gBattleMons[gBankTarget].hp <= gBattleMons[gBankAttacker].hp) { @@ -10283,7 +10298,7 @@ void atkD8_setdamagetohealthdifference(void) } } -void atkD9_scaledamagebyhealthratio(void) +static void atkD9_scaledamagebyhealthratio(void) { if (gDynamicBasePower == 0) { @@ -10295,7 +10310,7 @@ void atkD9_scaledamagebyhealthratio(void) gBattlescriptCurrInstr++; } -void atkDA_abilityswap(void) // skill swap +static void atkDA_abilityswap(void) // skill swap { if ((gBattleMons[gBankAttacker].ability == 0 && gBattleMons[gBankTarget].ability == 0) @@ -10315,7 +10330,7 @@ void atkDA_abilityswap(void) // skill swap } } -void atkDB_imprisoneffect(void) +static void atkDB_imprisoneffect(void) { if ((gStatuses3[gBankAttacker] & STATUS3_IMPRISONED_OTHERS)) { @@ -10357,7 +10372,7 @@ void atkDB_imprisoneffect(void) } } -void atkDC_setgrudge(void) +static void atkDC_setgrudge(void) { if (gStatuses3[gBankAttacker] & STATUS3_GRUDGE) { @@ -10370,7 +10385,7 @@ void atkDC_setgrudge(void) } } -void atkDD_weightdamagecalculation(void) +static void atkDD_weightdamagecalculation(void) { s32 i; for (i = 0; sWeightToDamageTable[i] != 0xFFFF; i += 2) @@ -10387,7 +10402,7 @@ void atkDD_weightdamagecalculation(void) gBattlescriptCurrInstr++; } -void atkDE_asistattackselect(void) +static void atkDE_asistattackselect(void) { s32 chooseableMovesNo = 0; struct Pokemon* party; @@ -10440,7 +10455,7 @@ void atkDE_asistattackselect(void) } } -void atkDF_setmagiccoat(void) +static void atkDF_setmagiccoat(void) { gBankTarget = gBankAttacker; gSpecialStatuses[gBankAttacker].flag20 = 1; @@ -10455,7 +10470,7 @@ void atkDF_setmagiccoat(void) } } -void atkE0_setstealstatchange(void) // snatch +static void atkE0_setstealstatchange(void) // snatch { gSpecialStatuses[gBankAttacker].flag20 = 1; if (gCurrentMoveTurn == gNoOfAllBanks - 1) // moves last turn @@ -10469,7 +10484,7 @@ void atkE0_setstealstatchange(void) // snatch } } -void atkE1_intimidate_string_loader(void) +static void atkE1_intimidate_string_loader(void) { u8 side; @@ -10492,9 +10507,9 @@ void atkE1_intimidate_string_loader(void) gBattlescriptCurrInstr += 5; } -void atkE2_switchout_abilities(void) +static void atkE2_switchout_abilities(void) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); switch (gBattleMons[gActiveBank].ability) { @@ -10508,9 +10523,9 @@ void atkE2_switchout_abilities(void) gBattlescriptCurrInstr += 2; } -void atkE3_jumpifhasnohp(void) +static void atkE3_jumpifhasnohp(void) { - gActiveBank = GetBattleBank(BSScriptRead8(gBattlescriptCurrInstr + 1)); + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (gBattleMons[gActiveBank].hp == 0) gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); @@ -10518,7 +10533,7 @@ void atkE3_jumpifhasnohp(void) gBattlescriptCurrInstr += 6; } -void atkE4_getsecretpowereffect(void) +static void atkE4_getsecretpowereffect(void) { switch (gBattleTerrain) { @@ -10553,15 +10568,7 @@ void atkE4_getsecretpowereffect(void) gBattlescriptCurrInstr++; } -extern bool8 InBattlePike(void); -extern bool8 InBattlePyramid(void); -extern u16 GetBattlePyramidPickupItemId(void); - -extern const u16 gRarePickupItems[]; -extern const u16 gPickupItems[]; -extern const u8 gPickupProbabilities[]; - -void atkE5_pickup(void) +static void atkE5_pickup(void) { if (!InBattlePike()) { @@ -10636,3 +10643,600 @@ void atkE5_pickup(void) gBattlescriptCurrInstr++; } + +static void atkE6_castform_change_animation(void) +{ + gActiveBank = gBattleScripting.bank; + + if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE) + *(&gBattleStruct->formToChangeInto) |= 0x80; + + EmitBattleAnimation(0, B_ANIM_CASTFORM_CHANGE, gBattleStruct->formToChangeInto); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr++; +} + +static void atkE7_castform_data_change(void) +{ + u8 form; + + gBattlescriptCurrInstr++; + form = CastformDataTypeChange(gBattleScripting.bank); + if (form) + { + BattleScriptPushCursorAndCallback(BattleScript_CastformChange); + *(&gBattleStruct->formToChangeInto) = form - 1; + } +} + +static void atkE8_settypebasedhalvers(void) // water and mud sport +{ + bool8 worked = FALSE; + + if (gBattleMoves[gCurrentMove].effect == EFFECT_MUD_SPORT) + { + if (!(gStatuses3[gBankAttacker] & STATUS3_MUDSPORT)) + { + gStatuses3[gBankAttacker] |= STATUS3_MUDSPORT; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + worked = TRUE; + } + } + else // water sport + { + if (!(gStatuses3[gBankAttacker] & STATUS3_WATERSPORT)) + { + gStatuses3[gBankAttacker] |= STATUS3_WATERSPORT; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + worked = TRUE; + } + } + + if (worked) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); +} + +static void atkE9_setweatherballtype(void) +{ + if (WEATHER_HAS_EFFECT) + { + if (gBattleWeather & WEATHER_ANY) + gBattleScripting.dmgMultiplier = 2; + if (gBattleWeather & WEATHER_RAIN_ANY) + *(&gBattleStruct->dynamicMoveType) = TYPE_WATER | 0x80; + else if (gBattleWeather & WEATHER_SANDSTORM_ANY) + *(&gBattleStruct->dynamicMoveType) = TYPE_ROCK | 0x80; + else if (gBattleWeather & WEATHER_SUN_ANY) + *(&gBattleStruct->dynamicMoveType) = TYPE_FIRE | 0x80; + else if (gBattleWeather & WEATHER_HAIL_ANY) + *(&gBattleStruct->dynamicMoveType) = TYPE_ICE | 0x80; + else + *(&gBattleStruct->dynamicMoveType) = TYPE_NORMAL | 0x80; + } + + gBattlescriptCurrInstr++; +} + +static void atkEA_recycleitem(void) +{ + u16 *usedHeldItem; + + gActiveBank = gBankAttacker; + usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBank]; + if (*usedHeldItem != 0 && gBattleMons[gActiveBank].item == 0) + { + gLastUsedItem = *usedHeldItem; + *usedHeldItem = 0; + gBattleMons[gActiveBank].item = gLastUsedItem; + + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBank].item); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkEB_settypetoterrain(void) +{ + if (gBattleMons[gBankAttacker].type1 != sTerrainToType[gBattleTerrain] + && gBattleMons[gBankAttacker].type2 != sTerrainToType[gBattleTerrain]) + { + gBattleMons[gBankAttacker].type1 = sTerrainToType[gBattleTerrain]; + gBattleMons[gBankAttacker].type2 = sTerrainToType[gBattleTerrain]; + + PREPARE_TYPE_BUFFER(gBattleTextBuff1, sTerrainToType[gBattleTerrain]) + + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkEC_pursuit_sth(void) +{ + gActiveBank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !(gAbsentBankFlags & gBitTable[gActiveBank]) + && gActionForBanks[gActiveBank] == 0 + && gChosenMovesByBanks[gActiveBank] == MOVE_PURSUIT) + { + gUnknown_0202407A[gActiveBank] = 11; + gCurrentMove = MOVE_PURSUIT; + gBattlescriptCurrInstr += 5; + gBattleScripting.animTurn = 1; + gBattleScripting.field_20 = gBankAttacker; + gBankAttacker = gActiveBank; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkED_802B4B4(void) +{ + gEffectBank = gBankAttacker; + + if (gBankAttacker == gBankTarget) + gBankAttacker = gBankTarget = gBattleScripting.bank; + else + gBankTarget = gBattleScripting.bank; + + gBattleScripting.bank = gEffectBank; + gBattlescriptCurrInstr++; +} + +static void atkEE_removelightscreenreflect(void) // brick break +{ + u8 opposingSide = GetBankSide(gBankAttacker) ^ BIT_SIDE; + + if (gSideTimers[opposingSide].reflectTimer || gSideTimers[opposingSide].lightscreenTimer) + { + gSideAffecting[opposingSide] &= ~(SIDE_STATUS_REFLECT); + gSideAffecting[opposingSide] &= ~(SIDE_STATUS_LIGHTSCREEN); + gSideTimers[opposingSide].reflectTimer = 0; + gSideTimers[opposingSide].lightscreenTimer = 0; + gBattleScripting.animTurn = 1; + gBattleScripting.animTargetsHit = 1; + } + else + { + gBattleScripting.animTurn = 0; + gBattleScripting.animTargetsHit = 0; + } + + gBattlescriptCurrInstr++; +} + +static void atkEF_pokeball_catch_calculation(void) +{ + u8 ballMultiplier = 0; + + if (gBattleExecBuffer) + return; + + gActiveBank = gBankAttacker; + gBankTarget = gBankAttacker ^ BIT_SIDE; + + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + EmitBallThrow(0, BALL_TRAINER_BLOCK); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr = BattleScript_TrainerBallBlock; + } + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) + { + EmitBallThrow(0, BALL_3_SHAKES_SUCCESS); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr = BattleScript_WallyBallThrow; + } + else + { + u32 odds; + u8 catchRate; + + if (gLastUsedItem == ITEM_SAFARI_BALL) + catchRate = gBattleStruct->field_7C * 1275 / 100; + else + catchRate = gBaseStats[gBattleMons[gBankTarget].species].catchRate; + + if (gLastUsedItem > ITEM_SAFARI_BALL) + { + switch (gLastUsedItem) + { + case ITEM_NET_BALL: + if (gBattleMons[gBankTarget].type1 == TYPE_WATER + || gBattleMons[gBankTarget].type2 == TYPE_WATER + || gBattleMons[gBankTarget].type1 == TYPE_BUG + || gBattleMons[gBankTarget].type2 == TYPE_BUG) + ballMultiplier = 30; + else + ballMultiplier = 10; + break; + case ITEM_DIVE_BALL: + if (sav1_map_get_light_level() == 5) + ballMultiplier = 35; + else + ballMultiplier = 10; + break; + case ITEM_NEST_BALL: + if (gBattleMons[gBankTarget].level <= 39) + { + ballMultiplier = 40 - gBattleMons[gBankTarget].level; + if (ballMultiplier <= 9) + ballMultiplier = 10; + } + else + { + ballMultiplier = 10; + } + break; + case ITEM_REPEAT_BALL: + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), FLAG_GET_CAUGHT)) + ballMultiplier = 30; + else + ballMultiplier = 10; + break; + case ITEM_TIMER_BALL: + ballMultiplier = gBattleResults.battleTurnCounter + 10; + if (ballMultiplier > 40) + ballMultiplier = 40; + break; + case ITEM_LUXURY_BALL: + case ITEM_PREMIER_BALL: + ballMultiplier = 10; + break; + } + } + else + ballMultiplier = sBallCatchBonuses[gLastUsedItem - 2]; + + odds = (catchRate * ballMultiplier / 10) + * (gBattleMons[gBankTarget].maxHP * 3 - gBattleMons[gBankTarget].hp * 2) + / (3 * gBattleMons[gBankTarget].maxHP); + + if (gBattleMons[gBankTarget].status1 & (STATUS_SLEEP | STATUS_FREEZE)) + odds *= 2; + if (gBattleMons[gBankTarget].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON)) + odds = (odds * 15) / 10; + + if (gLastUsedItem != ITEM_SAFARI_BALL) + { + if (gLastUsedItem == ITEM_MASTER_BALL) + { + gBattleResults.unk5_1 = 1; + } + else + { + if (gBattleResults.catchAttempts[gLastUsedItem - ITEM_ULTRA_BALL] < 0xFF) + gBattleResults.catchAttempts[gLastUsedItem - ITEM_ULTRA_BALL]++; + } + } + + if (odds > 254) // mon caught + { + EmitBallThrow(0, BALL_3_SHAKES_SUCCESS); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; + SetMonData(&gEnemyParty[gBattlePartyID[gBankTarget]], MON_DATA_POKEBALL, &gLastUsedItem); + + if (CalculatePlayerPartyCount() == 6) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else // mon may be caught, calculate shakes + { + u8 shakes; + + odds = Sqrt(Sqrt(16711680 / odds)); + odds = 1048560 / odds; + + for (shakes = 0; shakes < 4 && Random() < odds; shakes++); + + if (gLastUsedItem == ITEM_MASTER_BALL) + shakes = BALL_3_SHAKES_SUCCESS; // why calculate the shakes before that check? + + EmitBallThrow(0, shakes); + MarkBufferBankForExecution(gActiveBank); + + if (shakes == BALL_3_SHAKES_SUCCESS) // mon caught, copy of the code above + { + gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; + SetMonData(&gEnemyParty[gBattlePartyID[gBankTarget]], MON_DATA_POKEBALL, &gLastUsedItem); + + if (CalculatePlayerPartyCount() == 6) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else // not caught + { + gBattleCommunication[MULTISTRING_CHOOSER] = shakes; + gBattlescriptCurrInstr = BattleScript_ShakeBallThrow; + } + } + } +} + +static void atkF0_give_caught_mon(void) +{ + if (GiveMonToPlayer(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]]) != MON_GIVEN_TO_PARTY) + { + if (!sub_813B21C()) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + StringCopy(gStringVar1, GetBoxNamePtr(VarGet(VAR_STORAGE_UNKNOWN))); + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gStringVar2); + } + else + { + StringCopy(gStringVar1, GetBoxNamePtr(VarGet(VAR_STORAGE_UNKNOWN))); + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gStringVar2); + StringCopy(gStringVar3, GetBoxNamePtr(get_unknown_box_id())); + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + + if (FlagGet(SYS_PC_LANETTE)) + gBattleCommunication[MULTISTRING_CHOOSER]++; + } + + gBattleResults.caughtMonSpecies = GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_SPECIES, NULL); + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleResults.caughtMonNick); + gBattleResults.caughtMonBall = GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_POKEBALL, NULL); + + gBattlescriptCurrInstr++; +} + +static void atkF1_set_caught_mon_dex_flags(void) +{ + u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL); + u32 personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY, NULL); + + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + HandleSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_SET_CAUGHT, personality); + gBattlescriptCurrInstr += 5; + } +} + +static void atkF2_display_dex_info(void) +{ + u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL); + + switch (gBattleCommunication[0]) + { + case 0: + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + gBattleCommunication[0]++; + break; + case 1: + if (!gPaletteFade.active) + { + FreeAllWindowBuffers(); + gBattleCommunication[TASK_ID] = CreateDexDisplayMonDataTask(SpeciesToNationalPokedexNum(species), + gBattleMons[gBankTarget].otId, + gBattleMons[gBankTarget].personality); + gBattleCommunication[0]++; + } + break; + case 2: + if (!gPaletteFade.active + && gMain.callback2 == BattleMainCB2 + && !gTasks[gBattleCommunication[TASK_ID]].isActive) + { + SetVBlankCallback(VBlankCB_Battle); + gBattleCommunication[0]++; + } + break; + case 3: + c2_berry_program_update_menu(); + sub_8035AA4(); + gBattle_BG3_X = 0x100; + gBattleCommunication[0]++; + break; + case 4: + if (!IsDma3ManagerBusyWithBgCopy()) + { + BeginNormalPaletteFade(0xFFFF, 0, 0x10, 0, 0); + ShowBg(0); + ShowBg(3); + gBattleCommunication[0]++; + } + break; + case 5: + if (!gPaletteFade.active) + gBattlescriptCurrInstr++; + break; + } +} + +void sub_8056A3C(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags) +{ + s32 destY, destX; + u16 var = 0; + + for (destY = yStart; destY <= yEnd; destY++) + { + for (destX = xStart; destX <= xEnd; destX++) + { + if (destY == yStart) + { + if (destX == xStart) + var = 0x1022; + else if (destX == xEnd) + var = 0x1024; + else + var = 0x1023; + } + else if (destY == yEnd) + { + if (destX == xStart) + var = 0x1028; + else if (destX == xEnd) + var = 0x102A; + else + var = 0x1029; + } + else + { + if (destX == xStart) + var = 0x1025; + else if (destX == xEnd) + var = 0x1027; + else + var = 0x1026; + } + + if (flags & 1) + var = 0; + + if (flags & 0x80) + CopyToBgTilemapBufferRect_ChangePalette(1, &var, destX, destY, 1, 1, 0x11); + else + CopyToBgTilemapBufferRect_ChangePalette(0, &var, destX, destY, 1, 1, 0x11); + } + } +} + +void BattleCreateCursorAt(u8 cursorPosition) +{ + u16 src[2]; + src[0] = 1; + src[1] = 2; + + CopyToBgTilemapBufferRect_ChangePalette(0, src, 0x19, 9 + (2 * cursorPosition), 1, 2, 0x11); + CopyBgTilemapBufferToVram(0); +} + +void BattleDestroyCursorAt(u8 cursorPosition) +{ + u16 src[2]; + src[0] = 0x1016; + src[1] = 0x1016; + + CopyToBgTilemapBufferRect_ChangePalette(0, src, 0x19, 9 + (2 * cursorPosition), 1, 2, 0x11); + CopyBgTilemapBufferToVram(0); +} + +static void atkF3_nickname_caught_poke(void) +{ + switch (gBattleCommunication[MULTIUSE_STATE]) + { + case 0: + sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); + sub_814F9EC(gText_BattleYesNoChoice, 0xC); + gBattleCommunication[MULTIUSE_STATE]++; + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 1; + BattleCreateCursorAt(1); + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (gBattleCommunication[CURSOR_POSITION] == 0) + { + gBattleCommunication[MULTIUSE_STATE]++; + BeginFastPaletteFade(3); + } + else + { + gBattleCommunication[MULTIUSE_STATE] = 4; + } + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gBattleCommunication[MULTIUSE_STATE] = 4; + } + break; + case 2: + if (!gPaletteFade.active) + { + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleStruct->caughtMonNick); + FreeAllWindowBuffers(); + + DoNamingScreen(NAMING_SCREEN_CAUGHT_MON, gBattleStruct->caughtMonNick, + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_SPECIES), + GetMonGender(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]]), + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_PERSONALITY, NULL), + BattleMainCB2); + + gBattleCommunication[MULTIUSE_STATE]++; + } + break; + case 3: + if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active ) + { + SetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleStruct->caughtMonNick); + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + break; + case 4: + if (CalculatePlayerPartyCount() == 6) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + break; + } +} + +static void atkF4_subattackerhpbydmg(void) +{ + gBattleMons[gBankAttacker].hp -= gBattleMoveDamage; + gBattlescriptCurrInstr++; +} + +static void atkF5_removeattackerstatus1(void) +{ + gBattleMons[gBankAttacker].status1 = 0; + gBattlescriptCurrInstr++; +} + +static void atkF6_802BF48(void) +{ + gFightStateTracker = 0xC; +} + +static void atkF7_802BF54(void) +{ + gFightStateTracker = 0xC; + gCurrentMoveTurn = gNoOfAllBanks; +} + +static void atkF8_trainer_slide_back(void) +{ + gActiveBank = GetBankByIdentity(gBattlescriptCurrInstr[1]); + EmitTrainerSlideBack(0); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} -- cgit v1.2.3 From 7273b8f26277e3f9a1b562454e2e7f88e5523731 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 28 Sep 2017 16:51:24 +0200 Subject: battle 4 is all done --- src/battle_4.c | 120 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/battle_4.c b/src/battle_4.c index 414025695..e82f78570 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -773,7 +773,7 @@ struct StatFractions u8 divisor; }; -const struct StatFractions gAccuracyStageRatios[] = +static const struct StatFractions sAccuracyStageRatios[] = { { 33, 100}, // -6 { 36, 100}, // -5 @@ -791,9 +791,9 @@ const struct StatFractions gAccuracyStageRatios[] = }; // The chance is 1/N for each stage. -const u16 gCriticalHitChance[] = {16, 8, 4, 3, 2}; +static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2}; -const u32 gStatusFlagsForMoveEffects[] = +static const u32 sStatusFlagsForMoveEffects[] = { 0x00000000, STATUS_SLEEP, @@ -857,7 +857,7 @@ const u32 gStatusFlagsForMoveEffects[] = 0x00000000 }; -const u8* const gMoveEffectBS_Ptrs[] = +static const u8* const sMoveEffectBS_Ptrs[] = { BattleScript_MoveEffectSleep, // 0 BattleScript_MoveEffectSleep, // MOVE_EFFECT_SLEEP @@ -902,8 +902,8 @@ const u8* const gMoveEffectBS_Ptrs[] = static const struct WindowTemplate sUnusedWinTemplate = {0, 1, 3, 7, 0xF, 0x1F, 0x3F}; -const u16 gUnknown_0831C2C8[] = INCBIN_U16("graphics/battle_interface/unk_battlebox.gbapal"); -const u8 gUnknown_0831C2E8[] = INCBIN_U8("graphics/battle_interface/unk_battlebox.4bpp.lz"); +static const u16 sUnknown_0831C2C8[] = INCBIN_U16("graphics/battle_interface/unk_battlebox.gbapal"); +static const u8 sUnknown_0831C2E8[] = INCBIN_U8("graphics/battle_interface/unk_battlebox.4bpp.lz"); // unused static const u8 sRubyLevelUpStatBoxStats[] = @@ -914,7 +914,7 @@ static const u8 sRubyLevelUpStatBoxStats[] = #define MON_ICON_LVLUP_BOX_TAG 0xD75A -const struct OamData gUnknown_0831C3B8 = +static const struct OamData sOamData_MonIconOnLvlUpBox = { .y = 0, .affineMode = 0, @@ -931,24 +931,24 @@ const struct OamData gUnknown_0831C3B8 = .affineParam = 0, }; -const struct SpriteTemplate SpriteTemplate_MonIconOnLvlUpBox = +static const struct SpriteTemplate sSpriteTemplate_MonIconOnLvlUpBox = { .tileTag = MON_ICON_LVLUP_BOX_TAG, .paletteTag = MON_ICON_LVLUP_BOX_TAG, - .oam = &gUnknown_0831C3B8, + .oam = &sOamData_MonIconOnLvlUpBox, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCB_MonIconOnLvlUpBox }; -const u16 sProtectSuccessRates[] = {0xFFFF, 0x7FFF, 0x3FFF, 0x1FFF}; +static const u16 sProtectSuccessRates[] = {USHRT_MAX, USHRT_MAX / 2, USHRT_MAX / 4, USHRT_MAX / 8}; #define MIMIC_FORBIDDEN_END 0xFFFE #define METRONOME_FORBIDDEN_END 0xFFFF #define ASSIST_FORBIDDEN_END 0xFFFF -static const u16 gMovesForbiddenToCopy[] = +static const u16 sMovesForbiddenToCopy[] = { MOVE_METRONOME, MOVE_STRUGGLE, @@ -1007,7 +1007,7 @@ static const u16 sWeightToDamageTable[] = 0xFFFF, 0xFFFF }; -static const u16 gPickupItems[] = +static const u16 sPickupItems[] = { ITEM_POTION, ITEM_ANTIDOTE, @@ -1029,7 +1029,7 @@ static const u16 gPickupItems[] = ITEM_MAX_ELIXIR, }; -static const u16 gRarePickupItems[] = +static const u16 sRarePickupItems[] = { ITEM_HYPER_POTION, ITEM_NUGGET, @@ -1044,7 +1044,7 @@ static const u16 gRarePickupItems[] = ITEM_TM26, }; -static const u8 gPickupProbabilities[] = +static const u8 sPickupProbabilities[] = { 30, 40, 50, 60, 70, 80, 90, 94, 98 }; @@ -1057,8 +1057,8 @@ static const u8 sTerrainToType[] = TYPE_WATER, // underwater TYPE_WATER, // water TYPE_WATER, // pond water - TYPE_ROCK , // rock - TYPE_ROCK , // cave + TYPE_ROCK, // rock + TYPE_ROCK, // cave TYPE_NORMAL, // building TYPE_NORMAL, // plain }; @@ -1068,7 +1068,31 @@ static const u8 sBallCatchBonuses[] = 20, 15, 10, 15 // Ultra, Great, Poke, Safari }; -extern const u8 gUnknown_0831C4F8[]; +// could be a 2d array or a struct +const ALIGNED(4) u8 gUnknown_0831C494[] = +{ + 0x3d, 0x44, 0x3d, 0x44, 0x14, 0x2d, 0x54, 0x5c, + 0x46, 0x55, 0x20, 0x5c, 0x26, 0x45, 0x46, 0x55, + 0x14, 0x5a, 0x46, 0x5c, 0x1e, 0x32, 0x20, 0x5a, + 0x38, 0x4e, 0x38, 0x4e, 0x19, 0x28, 0x4b, 0x5a, + 0x45, 0x4b, 0x1c, 0x53, 0x23, 0x2d, 0x1d, 0x23, + 0x3e, 0x48, 0x1e, 0x32, 0x3a, 0x5f, 0x58, 0x5e, + 0x22, 0x2d, 0x1d, 0x28, 0x23, 0x28, 0x23, 0x5f, + 0x38, 0x4e, 0x38, 0x4e, 0x23, 0x50, 0x22, 0x5e, + 0x2c, 0x5e, 0x22, 0x28, 0x38, 0x4e, 0x38, 0x4e, + 0x1e, 0x58, 0x1e, 0x58, 0x1e, 0x2b, 0x1b, 0x21, + 0x28, 0x5a, 0x19, 0x57, 0x12, 0x58, 0x5a, 0x5f, + 0x58, 0x5e, 0x16, 0x2a, 0x2a, 0x5c, 0x2a, 0x2f, + 0x38, 0x4e, 0x38, 0x4e +}; + +static const u8 sUnknown_0831C4F8[] = +{ + 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x00, + 0x01, 0x02, 0x02, 0x00, 0x03, 0x01, 0x03, 0x01, + 0x02, 0x03, 0x03, 0x02, 0x01, 0x00, 0x02, 0x02, + 0x03, 0x00, 0x00, 0x00 +}; static void atk00_attackcanceler(void) { @@ -1304,8 +1328,8 @@ static void atk01_accuracycheck(void) if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY && gBattleMoves[move].effect == EFFECT_THUNDER) moveAcc = 50; - calc = gAccuracyStageRatios[buff].dividend * moveAcc; - calc /= gAccuracyStageRatios[buff].divisor; + calc = sAccuracyStageRatios[buff].dividend * moveAcc; + calc /= sAccuracyStageRatios[buff].divisor; if (gBattleMons[gBankAttacker].ability == ABILITY_COMPOUND_EYES) calc = (calc * 130) / 100; // 1.3 compound eyes boost @@ -1435,7 +1459,7 @@ static void atk04_critcalc(void) if ((gBattleMons[gBankTarget].ability != ABILITY_BATTLE_ARMOR && gBattleMons[gBankTarget].ability != ABILITY_SHELL_ARMOR) && !(gStatuses3[gBankAttacker] & STATUS3_CANT_SCORE_A_CRIT) && !(gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE)) - && !(Random() % gCriticalHitChance[critChance])) + && !(Random() % sCriticalHitChance[critChance])) gCritMultiplier = 2; else gCritMultiplier = 1; @@ -2411,7 +2435,7 @@ void SetMoveEffect(bool8 primary, u8 certain) if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) // status change { - switch (gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + switch (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) { case STATUS_SLEEP: // check active uproar @@ -2630,12 +2654,12 @@ void SetMoveEffect(bool8 primary, u8 certain) { BattleScriptPush(gBattlescriptCurrInstr + 1); - if (gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS_SLEEP) + if (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS_SLEEP) gBattleMons[gEffectBank].status1 |= ((Random() & 3) + 2); else - gBattleMons[gEffectBank].status1 |= gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattleMons[gEffectBank].status1 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; gActiveBank = gEffectBank; EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBank].status1); @@ -2674,7 +2698,7 @@ void SetMoveEffect(bool8 primary, u8 certain) } else { - if (gBattleMons[gEffectBank].status2 & gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + if (gBattleMons[gEffectBank].status2 & sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) { gBattlescriptCurrInstr++; } @@ -2694,7 +2718,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleMons[gEffectBank].status2 |= (((Random()) % 0x4)) + 2; BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; } break; case MOVE_EFFECT_FLINCH: @@ -2714,7 +2738,7 @@ void SetMoveEffect(bool8 primary, u8 certain) else { if (BankGetTurnOrder(gEffectBank) > gCurrentMoveTurn) - gBattleMons[gEffectBank].status2 |= gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattleMons[gEffectBank].status2 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; gBattlescriptCurrInstr++; } break; @@ -2727,7 +2751,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 4; BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; } else { @@ -2743,7 +2767,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gPaydayMoney = 0xFFFF; } BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; break; case MOVE_EFFECT_TRI_ATTACK: if (gBattleMons[gEffectBank].status1) @@ -2776,7 +2800,7 @@ void SetMoveEffect(bool8 primary, u8 certain) *(gBattleStruct->wrappedBy + gEffectBank) = gBankAttacker; BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; for (gBattleCommunication[MULTISTRING_CHOOSER] = 0; ; gBattleCommunication[MULTISTRING_CHOOSER]++) { @@ -2793,7 +2817,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleMoveDamage = 1; BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; break; case MOVE_EFFECT_ATK_PLUS_1: case MOVE_EFFECT_DEF_PLUS_1: @@ -3001,7 +3025,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleMoveDamage = 1; BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; break; case MOVE_EFFECT_THRASH: if (gBattleMons[gEffectBank].status2 & STATUS2_LOCK_CONFUSE) @@ -3108,9 +3132,9 @@ static void atk18_status_effect_clear(void) gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); if (gBattleCommunication[MOVE_EFFECT_BYTE] <= MOVE_EFFECT_TOXIC) - gBattleMons[gActiveBank].status1 &= (~gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); + gBattleMons[gActiveBank].status1 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); else - gBattleMons[gActiveBank].status2 &= (~gStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); + gBattleMons[gActiveBank].status2 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); gBattleCommunication[MOVE_EFFECT_BYTE] = 0; gBattlescriptCurrInstr += 2; @@ -6733,8 +6757,8 @@ static void sub_804F17C(void) gBattle_BG2_Y = 0; gBattle_BG2_X = 0x1A0; - LoadPalette(gUnknown_0831C2C8, 0x60, 0x20); - CopyToWindowPixelBuffer(14, gUnknown_0831C2E8, 0, 0); + LoadPalette(sUnknown_0831C2C8, 0x60, 0x20); + CopyToWindowPixelBuffer(14, sUnknown_0831C2E8, 0, 0); PutWindowTilemap(14); CopyWindowToVram(14, 3); @@ -6860,7 +6884,7 @@ static void PutMonIconOnLvlUpBox(void) LoadSpriteSheet(&iconSheet); LoadSpritePalette(&iconPalSheet); - spriteId = CreateSprite(&SpriteTemplate_MonIconOnLvlUpBox, 256, 10, 0); + spriteId = CreateSprite(&sSpriteTemplate_MonIconOnLvlUpBox, 256, 10, 0); gSprites[spriteId].sDestroy = FALSE; gSprites[spriteId].sSavedLvlUpBoxXPosition = gBattle_BG2_X; } @@ -7078,7 +7102,7 @@ static void atk76_various(void) { gBattleStruct->field_92 |= gBitTable[gActiveBank]; gBattleCommunication[0] = 1; - gBattleCommunication[MULTISTRING_CHOOSER] = gUnknown_0831C4F8[GetNatureFromPersonality(gBattleMons[gActiveBank].personality)]; + gBattleCommunication[MULTISTRING_CHOOSER] = sUnknown_0831C4F8[GetNatureFromPersonality(gBattleMons[gActiveBank].personality)]; } break; case 9: @@ -8475,10 +8499,10 @@ static void atk9C_set_substitute(void) static bool8 IsMoveUncopyableByMimic(u16 move) { s32 i; - for (i = 0; gMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END - && gMovesForbiddenToCopy[i] != move; i++); + for (i = 0; sMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END + && sMovesForbiddenToCopy[i] != move; i++); - return (gMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END); + return (sMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END); } static void atk9D_mimicattackcopy(void) @@ -8537,7 +8561,7 @@ static void atk9E_metronome(void) for (i = 0; i < 4; i++); // ? - for (move = gMovesForbiddenToCopy; ; move++) + for (move = sMovesForbiddenToCopy; ; move++) { if (*move == gCurrentMove) break; @@ -8567,7 +8591,7 @@ static void atk9E_metronome(void) ldr r7, =gCurrentMove\n\ movs r6, 0xB1\n\ lsls r6, 1\n\ - ldr r5, =gMovesForbiddenToCopy\n\ + ldr r5, =sMovesForbiddenToCopy\n\ ldr r0, =gBattlescriptCurrInstr\n\ mov r8, r0\n\ _080524EE:\n\ @@ -10580,9 +10604,9 @@ static void atkDE_asistattackselect(void) if (IsInvalidForSleepTalkOrAssist(move)) continue; - for (; gMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END && move != gMovesForbiddenToCopy[i]; i++); + for (; sMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END && move != sMovesForbiddenToCopy[i]; i++); - if (gMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END) + if (sMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END) continue; if (move == MOVE_NONE) continue; @@ -10774,14 +10798,14 @@ static void atkE5_pickup(void) for (j = 0; j < 9; j++) { - if (gPickupProbabilities[j] > rand) + if (sPickupProbabilities[j] > rand) { - SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &gPickupItems[lvlDivBy10 + j]); + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sPickupItems[lvlDivBy10 + j]); break; } else if (rand == 99 || rand == 98) { - SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &gRarePickupItems[lvlDivBy10 + (99 - rand)]); + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sRarePickupItems[lvlDivBy10 + (99 - rand)]); break; } } -- cgit v1.2.3 From 6d4d58a8a7759517b327a4017e05332888662e84 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 28 Sep 2017 17:38:07 +0200 Subject: rename battle4 and battleai --- src/battle_3.c | 3 +- src/battle_4.c | 11415 -------------------------------------- src/battle_ai.c | 2922 ---------- src/battle_ai_script_commands.c | 2922 ++++++++++ src/battle_script_commands.c | 11415 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 14338 insertions(+), 14339 deletions(-) delete mode 100644 src/battle_4.c delete mode 100644 src/battle_ai.c create mode 100644 src/battle_ai_script_commands.c create mode 100644 src/battle_script_commands.c (limited to 'src') diff --git a/src/battle_3.c b/src/battle_3.c index e81d527d0..e42d9317d 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -13,7 +13,7 @@ #include "text.h" #include "string_util.h" #include "battle_message.h" -#include "battle_ai.h" +#include "battle_ai_script_commands.h" #include "battle_controllers.h" #include "event_data.h" #include "calculate_base_damage.h" @@ -57,7 +57,6 @@ extern u8 gCurrMovePos; extern u8 gUnknown_020241E9; extern const struct BattleMove gBattleMoves[]; -extern void (* const gBattleScriptingCommandsTable[])(void); // scripts extern const u8 gUnknown_082DAE2A[]; diff --git a/src/battle_4.c b/src/battle_4.c deleted file mode 100644 index e82f78570..000000000 --- a/src/battle_4.c +++ /dev/null @@ -1,11415 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_move_effects.h" -#include "battle_message.h" -#include "battle_ai.h" -#include "moves.h" -#include "abilities.h" -#include "item.h" -#include "items.h" -#include "hold_effects.h" -#include "util.h" -#include "pokemon.h" -#include "calculate_base_damage.h" -#include "rng.h" -#include "battle_controllers.h" -#include "species.h" -#include "songs.h" -#include "text.h" -#include "sound.h" -#include "pokedex.h" -#include "recorded_battle.h" -#include "window.h" -#include "reshow_battle_screen.h" -#include "main.h" -#include "palette.h" -#include "money.h" -#include "bg.h" -#include "string_util.h" -#include "pokemon_icon.h" -#include "pokemon_item_effects.h" -#include "m4a.h" -#include "mail.h" -#include "event_data.h" -#include "pokemon_storage_system.h" -#include "task.h" -#include "naming_screen.h" - -// variables - -extern u8 gCritMultiplier; -extern s32 gBattleMoveDamage; -extern u32 gStatuses3[BATTLE_BANKS_COUNT]; -extern u32 gBattleTypeFlags; -extern struct BattleEnigmaBerry gEnigmaBerries[BATTLE_BANKS_COUNT]; -extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT]; -extern u8 gActiveBank; -extern u32 gBattleExecBuffer; -extern u8 gNoOfAllBanks; -extern u16 gBattlePartyID[BATTLE_BANKS_COUNT]; -extern u8 gTurnOrder[BATTLE_BANKS_COUNT]; -extern u8 gUnknown_0202407A[BATTLE_BANKS_COUNT]; -extern u16 gCurrentMove; -extern u8 gLastUsedAbility; -extern u16 gBattleWeather; -extern u8 gStringBank; -extern u8 gEffectBank; -extern u8 gAbsentBankFlags; -extern u8 gMultiHitCounter; -extern u16 gChosenMovesByBanks[BATTLE_BANKS_COUNT]; -extern u16 gSideAffecting[2]; -extern u16 gPauseCounterBattle; -extern u16 gPaydayMoney; -extern u16 gRandomTurnNumber; -extern u8 gBattleOutcome; -extern u8 gBattleTerrain; -extern u8 gBankAttacker; -extern u8 gBankTarget; -extern const u8* gBattlescriptCurrInstr; -extern u8 gCurrMovePos; -extern u8 gFightStateTracker; -extern u32 gHitMarker; -extern u8 gBattleMoveFlags; -extern u8 gBattleCommunication[]; -extern u16 gUnknown_02024250[4]; -extern u16 gUnknown_02024258[4]; -extern u16 gUnknown_02024260[4]; -extern u8 gUnknown_02024270[4]; -extern u8 gStringBank; -extern u16 gDynamicBasePower; -extern u16 gLastUsedItem; -extern u16 gBattleMovePower; -extern s32 gHpDealt; -extern s32 gTakenDmg[BATTLE_BANKS_COUNT]; -extern u8 gTakenDmgBanks[BATTLE_BANKS_COUNT]; -extern u8 gSentPokesToOpponent[2]; -extern u8 gBank1; -extern u16 gExpShareExp; -extern u8 gLeveledUpInBattle; -extern void (*gBattleMainFunc)(void); -extern u8 gPlayerPartyCount; -extern u16 gMoveToLearn; -extern u16 gRandomMove; -extern u8 gBankInMenu; -extern u8 gActionForBanks[BATTLE_BANKS_COUNT]; -extern u8 gCurrentMoveTurn; -extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200]; -extern u16 gLockedMoves[BATTLE_BANKS_COUNT]; -extern u16 gPartnerTrainerId; -extern u16 gLastUsedMove; -extern u16 gUnknownMovesUsedByBanks[BATTLE_BANKS_COUNT]; -extern u16 gLastUsedMovesByBanks[BATTLE_BANKS_COUNT]; -extern u16 gTrainerBattleOpponent_A; -extern u16 gTrainerBattleOpponent_B; -extern u8 gUnknown_020241E9; -extern u16 gBattle_BG1_X; -extern u16 gBattle_BG1_Y; -extern u16 gBattle_BG2_X; -extern u16 gBattle_BG2_Y; -extern u16 gBattle_BG3_X; -extern struct MusicPlayerInfo gMPlay_BGM; - -struct TrainerMoney -{ - u8 classId; - u8 value; -}; - -extern const struct BattleMove gBattleMoves[]; -extern const struct BaseStats gBaseStats[]; -extern const u8 gTypeEffectiveness[]; -extern const u16 gMissStringIds[]; -extern const u16 gTrappingMoves[]; -extern const struct TrainerMoney gTrainerMoneyTable[]; -extern const u8* const gBattleScriptsForMoveEffects[]; - -// functions -extern void sub_81A5718(u8 bank); // battle frontier 2 -extern void sub_81A56B4(void); // battle frontier 2 -extern void sub_81BFA38(struct Pokemon* party, u8 monPartyId, u8 monCount, void (*callback)(void), u16 move); // pokemon summary screen -extern u8 sub_81C1B94(void); // pokemon summary screen -extern void IncrementGameStat(u8 statId); // rom_4 -extern void sub_81D388C(struct Pokemon* mon, void* statStoreLocation); // pokenav.s -extern void sub_81D3640(u8 arg0, void* statStoreLocation1, void* statStoreLocation2, u8 arg3, u8 arg4, u8 arg5); // pokenav.s -extern void sub_81D3784(u8 arg0, void* statStoreLocation1, u8 arg2, u8 arg3, u8 arg4); // pokenav.s -extern u8* GetMonNickname(struct Pokemon* mon, u8* dst); // party_menu -extern u8 sub_81A5258(u8* arg0); // battle frontier 2 -extern void sub_81A5BF8(void); // battle frontier 2 -extern void sub_81A5D44(void); // battle frontier 2 -extern void sub_81B8E80(u8 bank, u8, u8); // party menu -extern bool8 sub_81B1250(void); // ? -extern u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale); // battle interface -extern bool8 InBattlePike(void); -extern bool8 InBattlePyramid(void); -extern u16 GetBattlePyramidPickupItemId(void); -extern u8 sav1_map_get_light_level(void); -extern u8 sub_813B21C(void); -extern u16 get_unknown_box_id(void); -extern void c2_berry_program_update_menu(void); -extern void sub_8035AA4(void); - -// BattleScripts -extern const u8 BattleScript_MoveEnd[]; -extern const u8 BattleScript_NoPPForMove[]; -extern const u8 BattleScript_MagicCoatBounce[]; -extern const u8 BattleScript_TookAttack[]; -extern const u8 BattleScript_SnatchedMove[]; -extern const u8 BattleScript_Pausex20[]; -extern const u8 BattleScript_SubstituteFade[]; -extern const u8 BattleScript_HangedOnMsg[]; -extern const u8 BattleScript_OneHitKOMsg[]; -extern const u8 BattleScript_EnduredMsg[]; -extern const u8 BattleScript_PSNPrevention[]; -extern const u8 BattleScript_BRNPrevention[]; -extern const u8 BattleScript_PRLZPrevention[]; -extern const u8 BattleScript_FlinchPrevention[]; -extern const u8 BattleScript_StatUp[]; -extern const u8 BattleScript_StatDown[]; -extern const u8 BattleScript_NoItemSteal[]; -extern const u8 BattleScript_ItemSteal[]; -extern const u8 BattleScript_RapidSpinAway[]; -extern const u8 BattleScript_TargetPRLZHeal[]; -extern const u8 BattleScript_KnockedOff[]; -extern const u8 BattleScript_StickyHoldActivates[]; -extern const u8 BattleScript_AllStatsUp[]; -extern const u8 BattleScript_AtkDefDown[]; -extern const u8 BattleScript_SAtkDown2[]; -extern const u8 BattleScript_LevelUp[]; -extern const u8 BattleScript_WrapFree[]; -extern const u8 BattleScript_LeechSeedFree[]; -extern const u8 BattleScript_SpikesFree[]; -extern const u8 BattleScript_ButItFailed[]; -extern const u8 BattleScript_ObliviousPreventsAttraction[]; -extern const u8 BattleScript_MistProtected[]; -extern const u8 BattleScript_AbilityNoStatLoss[]; -extern const u8 BattleScript_AbilityNoSpecificStatLoss[]; -extern const u8 BattleScript_TrainerBallBlock[]; -extern const u8 BattleScript_WallyBallThrow[]; -extern const u8 BattleScript_SuccessBallThrow[]; -extern const u8 BattleScript_ShakeBallThrow[]; -extern const u8 BattleScript_FaintAttacker[]; -extern const u8 BattleScript_FaintTarget[]; -extern const u8 BattleScript_DestinyBondTakesLife[]; -extern const u8 BattleScript_GrudgeTakesPp[]; -extern const u8 BattleScript_RageIsBuilding[]; -extern const u8 BattleScript_DefrostedViaFireMove[]; -extern const u8 gUnknown_082DB87D[]; -extern const u8 gUnknown_082DAE90[]; -extern const u8 gUnknown_082DAE59[]; -extern const u8 gUnknown_082DAEC7[]; -extern const u8 BattleScript_MoveEffectSleep[]; -extern const u8 BattleScript_MoveEffectPoison[]; -extern const u8 BattleScript_MoveEffectBurn[]; -extern const u8 BattleScript_MoveEffectFreeze[]; -extern const u8 BattleScript_MoveEffectParalysis[]; -extern const u8 BattleScript_MoveEffectToxic[]; -extern const u8 BattleScript_MoveEffectConfusion[]; -extern const u8 BattleScript_MoveEffectUproar[]; -extern const u8 BattleScript_MoveEffectPayDay[]; -extern const u8 BattleScript_MoveEffectWrap[]; -extern const u8 BattleScript_MoveEffectRecoil33[]; -extern const u8 BattleScript_DampStopsExplosion[]; -extern const u8 BattleScript_MistProtected[]; -extern const u8 BattleScript_AbilityNoStatLoss[]; -extern const u8 BattleScript_AbilityNoSpecificStatLoss[]; -extern const u8 BattleScript_ButItFailed[]; -extern const u8 gUnknown_082DADD8[]; -extern const u8 BattleScript_PrintPayDayMoneyString[]; -extern const u8 BattleScript_SturdyPreventsOHKO[]; -extern const u8 BattleScript_ObliviousPreventsAttraction[]; -extern const u8 BattleScript_PauseEffectivenessSoundResultMsgEndMove[]; -extern const u8 BattleScript_CastformChange[]; -extern const u8 BattleScript_TrainerBallBlock[]; -extern const u8 BattleScript_WallyBallThrow[]; -extern const u8 BattleScript_SuccessBallThrow[]; -extern const u8 BattleScript_ShakeBallThrow[]; -extern const u8 BattleScript_PresentDamageTarget[]; -extern const u8 BattleScript_AlreadyAtFullHp[]; -extern const u8 BattleScript_PresentHealTarget[]; -extern const u8 BattleScript_WrapFree[]; -extern const u8 BattleScript_LeechSeedFree[]; -extern const u8 BattleScript_SpikesFree[]; - -// strings -extern const u8 gText_BattleYesNoChoice[]; - -// read via orr -#define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) -#define BSScriptRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8)) -#define BSScriptReadPtr(ptr) ((void *)BSScriptRead32(ptr)) - -// read via add -#define BS2ScriptRead32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24)) -#define BS2ScriptRead16(ptr) ((ptr)[0] + ((ptr)[1] << 8)) -#define BS2ScriptReadPtr(ptr) ((void *)BS2ScriptRead32(ptr)) - -#define TARGET_PROTECT_AFFECTED ((gProtectStructs[gBankTarget].protected && gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED)) - -#define TARGET_TURN_DAMAGED (((gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special))) - -// this file's functions -static bool8 IsTwoTurnsMove(u16 move); -static void DestinyBondFlagUpdate(void); -static u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. -static void CheckWonderGuardAndLevitate(void); -static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8, const u8* BS_ptr); -static bool32 IsMonGettingExpSentOut(void); -static void sub_804F17C(void); -static bool8 sub_804F1CC(void); -static void sub_804F100(void); -static void sub_804F144(void); -static bool8 sub_804F344(void); -static void PutMonIconOnLvlUpBox(void); -static void PutLevelAndGenderOnLvlUpBox(void); - -static void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite); - -static void atk00_attackcanceler(void); -static void atk01_accuracycheck(void); -static void atk02_attackstring(void); -static void atk03_ppreduce(void); -static void atk04_critcalc(void); -static void atk05_damagecalc1(void); -static void atk06_typecalc(void); -static void atk07_dmg_adjustment(void); -static void atk08_dmg_adjustment2(void); -static void atk09_attackanimation(void); -static void atk0A_waitanimation(void); -static void atk0B_healthbarupdate(void); -static void atk0C_datahpupdate(void); -static void atk0D_critmessage(void); -static void atk0E_effectiveness_sound(void); -static void atk0F_resultmessage(void); -static void atk10_printstring(void); -static void atk11_printstring_playeronly(void); -static void atk12_waitmessage(void); -static void atk13_printfromtable(void); -static void atk14_printfromtable_playeronly(void); -static void atk15_seteffectwithchance(void); -static void atk16_seteffectprimary(void); -static void atk17_seteffectsecondary(void); -static void atk18_status_effect_clear(void); -static void atk19_faint_pokemon(void); -static void atk1A_faint_animation(void); -static void atk1B_faint_effects_clear(void); -static void atk1C_jumpifstatus(void); -static void atk1D_jumpifstatus2(void); -static void atk1E_jumpifability(void); -static void atk1F_jumpifsideaffecting(void); -static void atk20_jumpifstat(void); -static void atk21_jumpifstatus3(void); -static void atk22_jumpiftype(void); -static void atk23_getexp(void); -static void atk24(void); -static void atk25_move_values_cleanup(void); -static void atk26_set_multihit(void); -static void atk27_decrement_multihit(void); -static void atk28_goto(void); -static void atk29_jumpifbyte(void); -static void atk2A_jumpifhalfword(void); -static void atk2B_jumpifword(void); -static void atk2C_jumpifarrayequal(void); -static void atk2D_jumpifarraynotequal(void); -static void atk2E_setbyte(void); -static void atk2F_addbyte(void); -static void atk30_subbyte(void); -static void atk31_copyarray(void); -static void atk32_copyarray_withindex(void); -static void atk33_orbyte(void); -static void atk34_orhalfword(void); -static void atk35_orword(void); -static void atk36_bicbyte(void); -static void atk37_bichalfword(void); -static void atk38_bicword(void); -static void atk39_pause(void); -static void atk3A_waitstate(void); -static void atk3B_healthbar_update(void); -static void atk3C_return(void); -static void atk3D_end(void); -static void atk3E_end2(void); -static void atk3F_end3(void); -static void atk40_jump_if_move_affected_by_protect(void); -static void atk41_call(void); -static void atk42_jumpiftype2(void); -static void atk43_jumpifabilitypresent(void); -static void atk44(void); -static void atk45_playanimation(void); -static void atk46_playanimation2(void); -static void atk47_setgraphicalstatchangevalues(void); -static void atk48_playstatchangeanimation(void); -static void atk49_moveend(void); -static void atk4A_typecalc2(void); -static void atk4B_return_atk_to_ball(void); -static void atk4C_copy_poke_data(void); -static void atk4D_switch_data_update(void); -static void atk4E_switchin_anim(void); -static void atk4F_jump_if_cannot_switch(void); -static void atk50_openpartyscreen(void); -static void atk51_switch_handle_order(void); -static void atk52_switch_in_effects(void); -static void atk53_trainer_slide(void); -static void atk54_effectiveness_sound(void); -static void atk55_play_sound(void); -static void atk56_fainting_cry(void); -static void atk57(void); -static void atk58_return_to_ball(void); -static void atk59_learnmove_inbattle(void); -static void atk5A_yesnoboxlearnmove(void); -static void atk5B_yesnoboxstoplearningmove(void); -static void atk5C_hitanimation(void); -static void atk5D_getmoneyreward(void); -static void atk5E_8025A70(void); -static void atk5F_8025B24(void); -static void atk60_increment_gamestat(void); -static void atk61_8025BA4(void); -static void atk62_08025C6C(void); -static void atk63_jumptorandomattack(void); -static void atk64_statusanimation(void); -static void atk65_status2animation(void); -static void atk66_chosenstatusanimation(void); -static void atk67_yesnobox(void); -static void atk68_80246A0(void); -static void atk69_dmg_adjustment3(void); -static void atk6A_removeitem(void); -static void atk6B_atknameinbuff1(void); -static void atk6C_draw_lvlupbox(void); -static void atk6D_reset_sentpokes_value(void); -static void atk6E_set_atk_to_player0(void); -static void atk6F_set_visible(void); -static void atk70_record_last_used_ability(void); -static void atk71_buffer_move_to_learn(void); -static void atk72_jump_if_can_run_frombattle(void); -static void atk73_hp_thresholds(void); -static void atk74_hp_thresholds2(void); -static void atk75_item_effect_on_opponent(void); -static void atk76_various(void); -static void atk77_set_protect_like(void); -static void atk78_faintifabilitynotdamp(void); -static void atk79_setatkhptozero(void); -static void atk7A_jumpwhiletargetvalid(void); -static void atk7B_healhalfHP_if_possible(void); -static void atk7C_trymirrormove(void); -static void atk7D_set_rain(void); -static void atk7E_setreflect(void); -static void atk7F_setseeded(void); -static void atk80_manipulatedamage(void); -static void atk81_setrest(void); -static void atk82_jumpifnotfirstturn(void); -static void atk83_nop(void); -static void atk84_jump_if_cant_sleep(void); -static void atk85_stockpile(void); -static void atk86_stockpiletobasedamage(void); -static void atk87_stockpiletohpheal(void); -static void atk88_negativedamage(void); -static void atk89_statbuffchange(void); -static void atk8A_normalisebuffs(void); -static void atk8B_setbide(void); -static void atk8C_confuseifrepeatingattackends(void); -static void atk8D_setmultihit_counter(void); -static void atk8E_init_multihit_string(void); -static void atk8F_forcerandomswitch(void); -static void atk90_conversion_type_change(void); -static void atk91_givepaydaymoney(void); -static void atk92_setlightscreen(void); -static void atk93_ko_move(void); -static void atk94_damagetohalftargethp(void); -static void atk95_setsandstorm(void); -static void atk96_weatherdamage(void); -static void atk97_try_infatuation(void); -static void atk98_status_icon_update(void); -static void atk99_setmist(void); -static void atk9A_set_focusenergy(void); -static void atk9B_transformdataexecution(void); -static void atk9C_set_substitute(void); -static void atk9D_mimicattackcopy(void); -static void atk9E_metronome(void); -static void atk9F_dmgtolevel(void); -static void atkA0_psywavedamageeffect(void); -static void atkA1_counterdamagecalculator(void); -static void atkA2_mirrorcoatdamagecalculator(void); -static void atkA3_disablelastusedattack(void); -static void atkA4_setencore(void); -static void atkA5_painsplitdmgcalc(void); -static void atkA6_settypetorandomresistance(void); -static void atkA7_setalwayshitflag(void); -static void atkA8_copymovepermanently(void); -static void atkA9_sleeptalk_choose_move(void); -static void atkAA_set_destinybond(void); -static void atkAB_DestinyBondFlagUpdate(void); -static void atkAC_remaininghptopower(void); -static void atkAD_spite_ppreduce(void); -static void atkAE_heal_party_status(void); -static void atkAF_cursetarget(void); -static void atkB0_set_spikes(void); -static void atkB1_set_foresight(void); -static void atkB2_setperishsong(void); -static void atkB3_rolloutdamagecalculation(void); -static void atkB4_jumpifconfusedandstatmaxed(void); -static void atkB5_furycuttercalc(void); -static void atkB6_happinesstodamagecalculation(void); -static void atkB7_presentdamagecalculation(void); -static void atkB8_set_safeguard(void); -static void atkB9_magnitudedamagecalculation(void); -static void atkBA_jumpifnopursuitswitchdmg(void); -static void atkBB_setsunny(void); -static void atkBC_maxattackhalvehp(void); -static void atkBD_copyfoestats(void); -static void atkBE_rapidspinfree(void); -static void atkBF_set_defense_curl(void); -static void atkC0_recoverbasedonsunlight(void); -static void atkC1_hidden_power(void); -static void atkC2_selectnexttarget(void); -static void atkC3_setfutureattack(void); -static void atkC4_beat_up(void); -static void atkC5_setsemiinvulnerablebit(void); -static void atkC6_clearsemiinvulnerablebit(void); -static void atkC7_setminimize(void); -static void atkC8_sethail(void); -static void atkC9_jumpifattackandspecialattackcannotfall(void); -static void atkCA_setforcedtarget(void); -static void atkCB_setcharge(void); -static void atkCC_callterrainattack(void); -static void atkCD_cureifburnedparalysedorpoisoned(void); -static void atkCE_settorment(void); -static void atkCF_jumpifnodamage(void); -static void atkD0_settaunt(void); -static void atkD1_set_helpinghand(void); -static void atkD2_swap_items(void); -static void atkD3_copy_ability(void); -static void atkD4_wish_effect(void); -static void atkD5_setroots(void); -static void atkD6_doubledamagedealtifdamaged(void); -static void atkD7_setyawn(void); -static void atkD8_setdamagetohealthdifference(void); -static void atkD9_scaledamagebyhealthratio(void); -static void atkDA_abilityswap(void); -static void atkDB_imprisoneffect(void); -static void atkDC_setgrudge(void); -static void atkDD_weightdamagecalculation(void); -static void atkDE_asistattackselect(void); -static void atkDF_setmagiccoat(void); -static void atkE0_setstealstatchange(void); -static void atkE1_intimidate_string_loader(void); -static void atkE2_switchout_abilities(void); -static void atkE3_jumpifhasnohp(void); -static void atkE4_getsecretpowereffect(void); -static void atkE5_pickup(void); -static void atkE6_castform_change_animation(void); -static void atkE7_castform_data_change(void); -static void atkE8_settypebasedhalvers(void); -static void atkE9_setweatherballtype(void); -static void atkEA_recycleitem(void); -static void atkEB_settypetoterrain(void); -static void atkEC_pursuit_sth(void); -static void atkED_802B4B4(void); -static void atkEE_removelightscreenreflect(void); -static void atkEF_pokeball_catch_calculation(void); -static void atkF0_give_caught_mon(void); -static void atkF1_set_caught_mon_dex_flags(void); -static void atkF2_display_dex_info(void); -static void atkF3_nickname_caught_poke(void); -static void atkF4_subattackerhpbydmg(void); -static void atkF5_removeattackerstatus1(void); -static void atkF6_802BF48(void); -static void atkF7_802BF54(void); -static void atkF8_trainer_slide_back(void); - -void (* const gBattleScriptingCommandsTable[])(void) = -{ - atk00_attackcanceler, - atk01_accuracycheck, - atk02_attackstring, - atk03_ppreduce, - atk04_critcalc, - atk05_damagecalc1, - atk06_typecalc, - atk07_dmg_adjustment, - atk08_dmg_adjustment2, - atk09_attackanimation, - atk0A_waitanimation, - atk0B_healthbarupdate, - atk0C_datahpupdate, - atk0D_critmessage, - atk0E_effectiveness_sound, - atk0F_resultmessage, - atk10_printstring, - atk11_printstring_playeronly, - atk12_waitmessage, - atk13_printfromtable, - atk14_printfromtable_playeronly, - atk15_seteffectwithchance, - atk16_seteffectprimary, - atk17_seteffectsecondary, - atk18_status_effect_clear, - atk19_faint_pokemon, - atk1A_faint_animation, - atk1B_faint_effects_clear, - atk1C_jumpifstatus, - atk1D_jumpifstatus2, - atk1E_jumpifability, - atk1F_jumpifsideaffecting, - atk20_jumpifstat, - atk21_jumpifstatus3, - atk22_jumpiftype, - atk23_getexp, - atk24, - atk25_move_values_cleanup, - atk26_set_multihit, - atk27_decrement_multihit, - atk28_goto, - atk29_jumpifbyte, - atk2A_jumpifhalfword, - atk2B_jumpifword, - atk2C_jumpifarrayequal, - atk2D_jumpifarraynotequal, - atk2E_setbyte, - atk2F_addbyte, - atk30_subbyte, - atk31_copyarray, - atk32_copyarray_withindex, - atk33_orbyte, - atk34_orhalfword, - atk35_orword, - atk36_bicbyte, - atk37_bichalfword, - atk38_bicword, - atk39_pause, - atk3A_waitstate, - atk3B_healthbar_update, - atk3C_return, - atk3D_end, - atk3E_end2, - atk3F_end3, - atk40_jump_if_move_affected_by_protect, - atk41_call, - atk42_jumpiftype2, - atk43_jumpifabilitypresent, - atk44, - atk45_playanimation, - atk46_playanimation2, - atk47_setgraphicalstatchangevalues, - atk48_playstatchangeanimation, - atk49_moveend, - atk4A_typecalc2, - atk4B_return_atk_to_ball, - atk4C_copy_poke_data, - atk4D_switch_data_update, - atk4E_switchin_anim, - atk4F_jump_if_cannot_switch, - atk50_openpartyscreen, - atk51_switch_handle_order, - atk52_switch_in_effects, - atk53_trainer_slide, - atk54_effectiveness_sound, - atk55_play_sound, - atk56_fainting_cry, - atk57, - atk58_return_to_ball, - atk59_learnmove_inbattle, - atk5A_yesnoboxlearnmove, - atk5B_yesnoboxstoplearningmove, - atk5C_hitanimation, - atk5D_getmoneyreward, - atk5E_8025A70, - atk5F_8025B24, - atk60_increment_gamestat, - atk61_8025BA4, - atk62_08025C6C, - atk63_jumptorandomattack, - atk64_statusanimation, - atk65_status2animation, - atk66_chosenstatusanimation, - atk67_yesnobox, - atk68_80246A0, - atk69_dmg_adjustment3, - atk6A_removeitem, - atk6B_atknameinbuff1, - atk6C_draw_lvlupbox, - atk6D_reset_sentpokes_value, - atk6E_set_atk_to_player0, - atk6F_set_visible, - atk70_record_last_used_ability, - atk71_buffer_move_to_learn, - atk72_jump_if_can_run_frombattle, - atk73_hp_thresholds, - atk74_hp_thresholds2, - atk75_item_effect_on_opponent, - atk76_various, - atk77_set_protect_like, - atk78_faintifabilitynotdamp, - atk79_setatkhptozero, - atk7A_jumpwhiletargetvalid, - atk7B_healhalfHP_if_possible, - atk7C_trymirrormove, - atk7D_set_rain, - atk7E_setreflect, - atk7F_setseeded, - atk80_manipulatedamage, - atk81_setrest, - atk82_jumpifnotfirstturn, - atk83_nop, - atk84_jump_if_cant_sleep, - atk85_stockpile, - atk86_stockpiletobasedamage, - atk87_stockpiletohpheal, - atk88_negativedamage, - atk89_statbuffchange, - atk8A_normalisebuffs, - atk8B_setbide, - atk8C_confuseifrepeatingattackends, - atk8D_setmultihit_counter, - atk8E_init_multihit_string, - atk8F_forcerandomswitch, - atk90_conversion_type_change, - atk91_givepaydaymoney, - atk92_setlightscreen, - atk93_ko_move, - atk94_damagetohalftargethp, - atk95_setsandstorm, - atk96_weatherdamage, - atk97_try_infatuation, - atk98_status_icon_update, - atk99_setmist, - atk9A_set_focusenergy, - atk9B_transformdataexecution, - atk9C_set_substitute, - atk9D_mimicattackcopy, - atk9E_metronome, - atk9F_dmgtolevel, - atkA0_psywavedamageeffect, - atkA1_counterdamagecalculator, - atkA2_mirrorcoatdamagecalculator, - atkA3_disablelastusedattack, - atkA4_setencore, - atkA5_painsplitdmgcalc, - atkA6_settypetorandomresistance, - atkA7_setalwayshitflag, - atkA8_copymovepermanently, - atkA9_sleeptalk_choose_move, - atkAA_set_destinybond, - atkAB_DestinyBondFlagUpdate, - atkAC_remaininghptopower, - atkAD_spite_ppreduce, - atkAE_heal_party_status, - atkAF_cursetarget, - atkB0_set_spikes, - atkB1_set_foresight, - atkB2_setperishsong, - atkB3_rolloutdamagecalculation, - atkB4_jumpifconfusedandstatmaxed, - atkB5_furycuttercalc, - atkB6_happinesstodamagecalculation, - atkB7_presentdamagecalculation, - atkB8_set_safeguard, - atkB9_magnitudedamagecalculation, - atkBA_jumpifnopursuitswitchdmg, - atkBB_setsunny, - atkBC_maxattackhalvehp, - atkBD_copyfoestats, - atkBE_rapidspinfree, - atkBF_set_defense_curl, - atkC0_recoverbasedonsunlight, - atkC1_hidden_power, - atkC2_selectnexttarget, - atkC3_setfutureattack, - atkC4_beat_up, - atkC5_setsemiinvulnerablebit, - atkC6_clearsemiinvulnerablebit, - atkC7_setminimize, - atkC8_sethail, - atkC9_jumpifattackandspecialattackcannotfall, - atkCA_setforcedtarget, - atkCB_setcharge, - atkCC_callterrainattack, - atkCD_cureifburnedparalysedorpoisoned, - atkCE_settorment, - atkCF_jumpifnodamage, - atkD0_settaunt, - atkD1_set_helpinghand, - atkD2_swap_items, - atkD3_copy_ability, - atkD4_wish_effect, - atkD5_setroots, - atkD6_doubledamagedealtifdamaged, - atkD7_setyawn, - atkD8_setdamagetohealthdifference, - atkD9_scaledamagebyhealthratio, - atkDA_abilityswap, - atkDB_imprisoneffect, - atkDC_setgrudge, - atkDD_weightdamagecalculation, - atkDE_asistattackselect, - atkDF_setmagiccoat, - atkE0_setstealstatchange, - atkE1_intimidate_string_loader, - atkE2_switchout_abilities, - atkE3_jumpifhasnohp, - atkE4_getsecretpowereffect, - atkE5_pickup, - atkE6_castform_change_animation, - atkE7_castform_data_change, - atkE8_settypebasedhalvers, - atkE9_setweatherballtype, - atkEA_recycleitem, - atkEB_settypetoterrain, - atkEC_pursuit_sth, - atkED_802B4B4, - atkEE_removelightscreenreflect, - atkEF_pokeball_catch_calculation, - atkF0_give_caught_mon, - atkF1_set_caught_mon_dex_flags, - atkF2_display_dex_info, - atkF3_nickname_caught_poke, - atkF4_subattackerhpbydmg, - atkF5_removeattackerstatus1, - atkF6_802BF48, - atkF7_802BF54, - atkF8_trainer_slide_back -}; - -struct StatFractions -{ - u8 dividend; - u8 divisor; -}; - -static const struct StatFractions sAccuracyStageRatios[] = -{ - { 33, 100}, // -6 - { 36, 100}, // -5 - { 43, 100}, // -4 - { 50, 100}, // -3 - { 60, 100}, // -2 - { 75, 100}, // -1 - { 1, 1}, // 0 - {133, 100}, // +1 - {166, 100}, // +2 - { 2, 1}, // +3 - {233, 100}, // +4 - {133, 50}, // +5 - { 3, 1}, // +6 -}; - -// The chance is 1/N for each stage. -static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2}; - -static const u32 sStatusFlagsForMoveEffects[] = -{ - 0x00000000, - STATUS_SLEEP, - STATUS_POISON, - STATUS_BURN, - STATUS_FREEZE, - STATUS_PARALYSIS, - STATUS_TOXIC_POISON, - STATUS2_CONFUSION, - STATUS2_FLINCHED, - 0x00000000, - STATUS2_UPROAR, - 0x00000000, - STATUS2_MULTIPLETURNS, - STATUS2_WRAPPED, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - STATUS2_RECHARGE, - 0x00000000, - 0x00000000, - STATUS2_ESCAPE_PREVENTION, - 0x08000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - STATUS2_LOCK_CONFUSE, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000 -}; - -static const u8* const sMoveEffectBS_Ptrs[] = -{ - BattleScript_MoveEffectSleep, // 0 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_SLEEP - BattleScript_MoveEffectPoison, // MOVE_EFFECT_POISON - BattleScript_MoveEffectBurn, // MOVE_EFFECT_BURN - BattleScript_MoveEffectFreeze, // MOVE_EFFECT_FREEZE - BattleScript_MoveEffectParalysis, // MOVE_EFFECT_PARALYSIS - BattleScript_MoveEffectToxic, // MOVE_EFFECT_TOXIC - BattleScript_MoveEffectConfusion, // MOVE_EFFECT_CONFUSION - BattleScript_MoveEffectSleep, // MOVE_EFFECT_FLINCH - BattleScript_MoveEffectSleep, // MOVE_EFFECT_TRI_ATTACK - BattleScript_MoveEffectUproar, // MOVE_EFFECT_UPROAR - BattleScript_MoveEffectPayDay, // MOVE_EFFECT_PAYDAY - BattleScript_MoveEffectSleep, // MOVE_EFFECT_CHARGING - BattleScript_MoveEffectWrap, // MOVE_EFFECT_WRAP - BattleScript_MoveEffectRecoil33, // MOVE_EFFECT_RECOIL_25 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_PLUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_DEF_PLUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_SPD_PLUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_ATK_PLUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_DEF_PLUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_ACC_PLUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_EVS_PLUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_MINUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_DEF_MINUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_SPD_MINUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_ATK_MINUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_DEF_MINUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_ACC_MINUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_EVS_MINUS_1 - BattleScript_MoveEffectSleep, // MOVE_EFFECT_RECHARGE - BattleScript_MoveEffectSleep, // MOVE_EFFECT_RAGE - BattleScript_MoveEffectSleep, // MOVE_EFFECT_STEAL_ITEM - BattleScript_MoveEffectSleep, // MOVE_EFFECT_PREVENT_ESCAPE - BattleScript_MoveEffectSleep, // MOVE_EFFECT_NIGHTMARE - BattleScript_MoveEffectSleep, // MOVE_EFFECT_ALL_STATS_UP - BattleScript_MoveEffectSleep, // MOVE_EFFECT_RAPIDSPIN - BattleScript_MoveEffectSleep, // MOVE_EFFECT_REMOVE_PARALYSIS - BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_DEF_DOWN - BattleScript_MoveEffectRecoil33, // MOVE_EFFECT_RECOIL_33_PARALYSIS -}; - -static const struct WindowTemplate sUnusedWinTemplate = {0, 1, 3, 7, 0xF, 0x1F, 0x3F}; - -static const u16 sUnknown_0831C2C8[] = INCBIN_U16("graphics/battle_interface/unk_battlebox.gbapal"); -static const u8 sUnknown_0831C2E8[] = INCBIN_U8("graphics/battle_interface/unk_battlebox.4bpp.lz"); - -// unused -static const u8 sRubyLevelUpStatBoxStats[] = -{ - MON_DATA_MAX_HP, MON_DATA_SPATK, MON_DATA_ATK, - MON_DATA_SPDEF, MON_DATA_DEF, MON_DATA_SPD -}; - -#define MON_ICON_LVLUP_BOX_TAG 0xD75A - -static const struct OamData sOamData_MonIconOnLvlUpBox = -{ - .y = 0, - .affineMode = 0, - .objMode = 0, - .mosaic = 0, - .bpp = 0, - .shape = 0, - .x = 0, - .matrixNum = 0, - .size = 2, - .tileNum = 0, - .priority = 0, - .paletteNum = 0, - .affineParam = 0, -}; - -static const struct SpriteTemplate sSpriteTemplate_MonIconOnLvlUpBox = -{ - .tileTag = MON_ICON_LVLUP_BOX_TAG, - .paletteTag = MON_ICON_LVLUP_BOX_TAG, - .oam = &sOamData_MonIconOnLvlUpBox, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_MonIconOnLvlUpBox -}; - -static const u16 sProtectSuccessRates[] = {USHRT_MAX, USHRT_MAX / 2, USHRT_MAX / 4, USHRT_MAX / 8}; - -#define MIMIC_FORBIDDEN_END 0xFFFE -#define METRONOME_FORBIDDEN_END 0xFFFF -#define ASSIST_FORBIDDEN_END 0xFFFF - -static const u16 sMovesForbiddenToCopy[] = -{ - MOVE_METRONOME, - MOVE_STRUGGLE, - MOVE_SKETCH, - MOVE_MIMIC, - MIMIC_FORBIDDEN_END, - MOVE_COUNTER, - MOVE_MIRROR_COAT, - MOVE_PROTECT, - MOVE_DETECT, - MOVE_ENDURE, - MOVE_DESTINY_BOND, - MOVE_SLEEP_TALK, - MOVE_THIEF, - MOVE_FOLLOW_ME, - MOVE_SNATCH, - MOVE_HELPING_HAND, - MOVE_COVET, - MOVE_TRICK, - MOVE_FOCUS_PUNCH, - METRONOME_FORBIDDEN_END -}; - -static const u8 sFlailHpScaleToPowerTable[] = -{ - 1, 200, - 4, 150, - 9, 100, - 16, 80, - 32, 40, - 48, 20 -}; - -static const u16 sNaturePowerMoves[] = -{ - MOVE_STUN_SPORE, - MOVE_RAZOR_LEAF, - MOVE_EARTHQUAKE, - MOVE_HYDRO_PUMP, - MOVE_SURF, - MOVE_BUBBLE_BEAM, - MOVE_ROCK_SLIDE, - MOVE_SHADOW_BALL, - MOVE_SWIFT, - MOVE_SWIFT -}; - -// format: min. weight (hectograms), base power -static const u16 sWeightToDamageTable[] = -{ - 100, 20, - 250, 40, - 500, 60, - 1000, 80, - 2000, 100, - 0xFFFF, 0xFFFF -}; - -static const u16 sPickupItems[] = -{ - ITEM_POTION, - ITEM_ANTIDOTE, - ITEM_SUPER_POTION, - ITEM_GREAT_BALL, - ITEM_REPEL, - ITEM_ESCAPE_ROPE, - ITEM_X_ATTACK, - ITEM_FULL_HEAL, - ITEM_ULTRA_BALL, - ITEM_HYPER_POTION, - ITEM_RARE_CANDY, - ITEM_PROTEIN, - ITEM_REVIVE, - ITEM_HP_UP, - ITEM_FULL_RESTORE, - ITEM_MAX_REVIVE, - ITEM_PP_UP, - ITEM_MAX_ELIXIR, -}; - -static const u16 sRarePickupItems[] = -{ - ITEM_HYPER_POTION, - ITEM_NUGGET, - ITEM_KINGS_ROCK, - ITEM_FULL_RESTORE, - ITEM_ETHER, - ITEM_WHITE_HERB, - ITEM_TM44, - ITEM_ELIXIR, - ITEM_TM01, - ITEM_LEFTOVERS, - ITEM_TM26, -}; - -static const u8 sPickupProbabilities[] = -{ - 30, 40, 50, 60, 70, 80, 90, 94, 98 -}; - -static const u8 sTerrainToType[] = -{ - TYPE_GRASS, // tall grass - TYPE_GRASS, // long grass - TYPE_GROUND, // sand - TYPE_WATER, // underwater - TYPE_WATER, // water - TYPE_WATER, // pond water - TYPE_ROCK, // rock - TYPE_ROCK, // cave - TYPE_NORMAL, // building - TYPE_NORMAL, // plain -}; - -static const u8 sBallCatchBonuses[] = -{ - 20, 15, 10, 15 // Ultra, Great, Poke, Safari -}; - -// could be a 2d array or a struct -const ALIGNED(4) u8 gUnknown_0831C494[] = -{ - 0x3d, 0x44, 0x3d, 0x44, 0x14, 0x2d, 0x54, 0x5c, - 0x46, 0x55, 0x20, 0x5c, 0x26, 0x45, 0x46, 0x55, - 0x14, 0x5a, 0x46, 0x5c, 0x1e, 0x32, 0x20, 0x5a, - 0x38, 0x4e, 0x38, 0x4e, 0x19, 0x28, 0x4b, 0x5a, - 0x45, 0x4b, 0x1c, 0x53, 0x23, 0x2d, 0x1d, 0x23, - 0x3e, 0x48, 0x1e, 0x32, 0x3a, 0x5f, 0x58, 0x5e, - 0x22, 0x2d, 0x1d, 0x28, 0x23, 0x28, 0x23, 0x5f, - 0x38, 0x4e, 0x38, 0x4e, 0x23, 0x50, 0x22, 0x5e, - 0x2c, 0x5e, 0x22, 0x28, 0x38, 0x4e, 0x38, 0x4e, - 0x1e, 0x58, 0x1e, 0x58, 0x1e, 0x2b, 0x1b, 0x21, - 0x28, 0x5a, 0x19, 0x57, 0x12, 0x58, 0x5a, 0x5f, - 0x58, 0x5e, 0x16, 0x2a, 0x2a, 0x5c, 0x2a, 0x2f, - 0x38, 0x4e, 0x38, 0x4e -}; - -static const u8 sUnknown_0831C4F8[] = -{ - 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x00, - 0x01, 0x02, 0x02, 0x00, 0x03, 0x01, 0x03, 0x01, - 0x02, 0x03, 0x03, 0x02, 0x01, 0x00, 0x02, 0x02, - 0x03, 0x00, 0x00, 0x00 -}; - -static void atk00_attackcanceler(void) -{ - s32 i; - - if (gBattleOutcome) - { - gFightStateTracker = 0xC; - return; - } - if (gBattleMons[gBankAttacker].hp == 0 && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) - { - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - gBattlescriptCurrInstr = BattleScript_MoveEnd; - return; - } - if (AtkCanceller_UnableToUseMove()) - return; - if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBankTarget, 0, 0, 0)) - return; - if (!gBattleMons[gBankAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE && !(gHitMarker & 0x800200) - && !(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) - { - gBattlescriptCurrInstr = BattleScript_NoPPForMove; - gBattleMoveFlags |= MOVESTATUS_MISSED; - return; - } - - gHitMarker &= ~(HITMARKER_x800000); - - if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) - { - i = IsPokeDisobedient(); // why use the 'i' variable...? - switch (i) - { - case 0: - break; - case 2: - gHitMarker |= HITMARKER_OBEYS; - return; - default: - gBattleMoveFlags |= MOVESTATUS_MISSED; - return; - } - } - - gHitMarker |= HITMARKER_OBEYS; - - if (gProtectStructs[gBankTarget].bounceMove && gBattleMoves[gCurrentMove].flags & FLAG_MAGICCOAT_AFFECTED) - { - PressurePPLose(gBankAttacker, gBankTarget, MOVE_MAGIC_COAT); - gProtectStructs[gBankTarget].bounceMove = 0; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MagicCoatBounce; - return; - } - - for (i = 0; i < gNoOfAllBanks; i++) - { - if ((gProtectStructs[gTurnOrder[i]].stealMove) && gBattleMoves[gCurrentMove].flags & FLAG_SNATCH_AFFECTED) - { - PressurePPLose(gBankAttacker, gTurnOrder[i], MOVE_SNATCH); - gProtectStructs[gTurnOrder[i]].stealMove = 0; - gBattleScripting.bank = gTurnOrder[i]; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_SnatchedMove; - return; - } - } - - if (gSpecialStatuses[gBankTarget].lightningRodRedirected) - { - gSpecialStatuses[gBankTarget].lightningRodRedirected = 0; - gLastUsedAbility = ABILITY_LIGHTNING_ROD; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_TookAttack; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - else if (TARGET_PROTECT_AFFECTED - && (gCurrentMove != MOVE_CURSE || (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST)) - && ((!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)))) - { - CancelMultiTurnMoves(gBankAttacker); - gBattleMoveFlags |= MOVESTATUS_MISSED; - gUnknown_02024250[gBankTarget] = 0; - gUnknown_02024258[gBankTarget] = 0; - gBattleCommunication[6] = 1; - gBattlescriptCurrInstr++; - } - else - { - gBattlescriptCurrInstr++; - } -} - -static void JumpIfMoveFailed(u8 adder, u16 move) -{ - const void* BS_ptr = gBattlescriptCurrInstr + adder; - if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) - { - gUnknown_02024250[gBankTarget] = 0; - gUnknown_02024258[gBankTarget] = 0; - BS_ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - DestinyBondFlagUpdate(); - if (AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBankTarget, 0, 0, move)) - return; - } - gBattlescriptCurrInstr = BS_ptr; -} - -static void atk40_jump_if_move_affected_by_protect(void) -{ - if (TARGET_PROTECT_AFFECTED) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - JumpIfMoveFailed(5, 0); - gBattleCommunication[6] = 1; - } - else - { - gBattlescriptCurrInstr += 5; - } -} - -bool8 JumpIfMoveAffectedByProtect(u16 move) -{ - bool8 affected = FALSE; - if (TARGET_PROTECT_AFFECTED) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - JumpIfMoveFailed(7, move); - gBattleCommunication[6] = 1; - affected = TRUE; - } - return affected; -} - -bool8 AccuracyCalcHelper(u16 move) -{ - if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker) - { - JumpIfMoveFailed(7, move); - return TRUE; - } - - if (!(gHitMarker & HITMARKER_IGNORE_ON_AIR) && gStatuses3[gBankTarget] & STATUS3_ON_AIR) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - JumpIfMoveFailed(7, move); - return TRUE; - } - - gHitMarker &= ~HITMARKER_IGNORE_ON_AIR; - - if (!(gHitMarker & HITMARKER_IGNORE_UNDERGROUND) && gStatuses3[gBankTarget] & STATUS3_UNDERGROUND) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - JumpIfMoveFailed(7, move); - return TRUE; - } - - gHitMarker &= ~HITMARKER_IGNORE_UNDERGROUND; - - if (!(gHitMarker & HITMARKER_IGNORE_UNDERWATER) && gStatuses3[gBankTarget] & STATUS3_UNDERWATER) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - JumpIfMoveFailed(7, move); - return TRUE; - } - - gHitMarker &= ~HITMARKER_IGNORE_UNDERWATER; - - if ((WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY) && gBattleMoves[move].effect == EFFECT_THUNDER) - || (gBattleMoves[move].effect == EFFECT_ALWAYS_HIT || gBattleMoves[move].effect == EFFECT_VITAL_THROW)) - { - JumpIfMoveFailed(7, move); - return TRUE; - } - - return FALSE; -} - -static void atk01_accuracycheck(void) -{ - u16 move = BS2ScriptRead16(gBattlescriptCurrInstr + 5); - - if (move == 0xFFFE || move == 0xFFFF) - { - if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && move == 0xFFFF && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker) - gBattlescriptCurrInstr += 7; - else if (gStatuses3[gBankTarget] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - else if (!JumpIfMoveAffectedByProtect(0)) - gBattlescriptCurrInstr += 7; - } - else - { - u8 type, moveAcc, holdEffect, quality; - s8 buff; - u16 calc; - - if (move == 0) - move = gCurrentMove; - - GET_MOVE_TYPE(move, type); - - if (JumpIfMoveAffectedByProtect(move)) - return; - if (AccuracyCalcHelper(move)) - return; - - if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) - { - u8 acc = gBattleMons[gBankAttacker].statStages[STAT_STAGE_ACC]; - buff = acc; - } - else - { - u8 acc = gBattleMons[gBankAttacker].statStages[STAT_STAGE_ACC]; - buff = acc + 6 - gBattleMons[gBankTarget].statStages[STAT_STAGE_EVASION]; - } - - if (buff < 0) - buff = 0; - if (buff > 0xC) - buff = 0xC; - - moveAcc = gBattleMoves[move].accuracy; - // check Thunder on sunny weather - if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY && gBattleMoves[move].effect == EFFECT_THUNDER) - moveAcc = 50; - - calc = sAccuracyStageRatios[buff].dividend * moveAcc; - calc /= sAccuracyStageRatios[buff].divisor; - - if (gBattleMons[gBankAttacker].ability == ABILITY_COMPOUND_EYES) - calc = (calc * 130) / 100; // 1.3 compound eyes boost - if (WEATHER_HAS_EFFECT && gBattleMons[gBankTarget].ability == ABILITY_SAND_VEIL && gBattleWeather & WEATHER_SANDSTORM_ANY) - calc = (calc * 80) / 100; // 1.2 sand veil loss - if (gBattleMons[gBankAttacker].ability == ABILITY_HUSTLE && type < 9) - calc = (calc * 80) / 100; // 1.2 hustle loss - - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - { - holdEffect = gEnigmaBerries[gBankTarget].holdEffect; - quality = gEnigmaBerries[gBankTarget].holdEffectParam; - } - else - { - holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); - } - - gStringBank = gBankTarget; - - if (holdEffect == HOLD_EFFECT_EVASION_UP) - calc = (calc * (100 - quality)) / 100; - - // final calculation - if ((Random() % 100 + 1) > calc) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && - (gBattleMoves[move].target == MOVE_TARGET_BOTH || gBattleMoves[move].target == MOVE_TARGET_FOES_AND_ALLY)) - gBattleCommunication[6] = 2; - else - gBattleCommunication[6] = 0; - - CheckWonderGuardAndLevitate(); - } - JumpIfMoveFailed(7, move); - } -} - -static void atk02_attackstring(void) -{ - if (gBattleExecBuffer) - return; - if (!(gHitMarker & (HITMARKER_NO_ATTACKSTRING | HITMARKER_ATTACKSTRING_PRINTED))) - { - PrepareStringBattle(4, gBankAttacker); - gHitMarker |= HITMARKER_ATTACKSTRING_PRINTED; - } - gBattlescriptCurrInstr++; - gBattleCommunication[MSG_DISPLAY] = 0; -} - -static void atk03_ppreduce(void) -{ - s32 ppToDeduct = 1; - - if (gBattleExecBuffer) - return; - - if (!gSpecialStatuses[gBankAttacker].flag20) - { - switch (gBattleMoves[gCurrentMove].target) - { - case MOVE_TARGET_FOES_AND_ALLY: - ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_ON_FIELD, gBankAttacker, ABILITY_PRESSURE, 0, 0); - break; - case MOVE_TARGET_BOTH: - case MOVE_TARGET_OPPONENTS_FIELD: - ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIDE, gBankAttacker, ABILITY_PRESSURE, 0, 0); - break; - default: - if (gBankAttacker != gBankTarget && gBattleMons[gBankTarget].ability == ABILITY_PRESSURE) - ppToDeduct++; - break; - } - } - - if (!(gHitMarker & (HITMARKER_NO_PPDEDUCT | HITMARKER_NO_ATTACKSTRING)) && gBattleMons[gBankAttacker].pp[gCurrMovePos]) - { - gProtectStructs[gBankAttacker].notFirstStrike = 1; - - if (gBattleMons[gBankAttacker].pp[gCurrMovePos] > ppToDeduct) - gBattleMons[gBankAttacker].pp[gCurrMovePos] -= ppToDeduct; - else - gBattleMons[gBankAttacker].pp[gCurrMovePos] = 0; - - if (!(gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED) - && !((gDisableStructs[gBankAttacker].unk18_b) & gBitTable[gCurrMovePos])) - { - gActiveBank = gBankAttacker; - EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + gCurrMovePos, 0, 1, &gBattleMons[gBankAttacker].pp[gCurrMovePos]); - MarkBufferBankForExecution(gBankAttacker); - } - } - - gHitMarker &= ~(HITMARKER_NO_PPDEDUCT); - gBattlescriptCurrInstr++; -} - -static void atk04_critcalc(void) -{ - u8 holdEffect; - u16 item, critChance; - - item = gBattleMons[gBankAttacker].item; - - if (item == ITEM_ENIGMA_BERRY) - holdEffect = gEnigmaBerries[gBankAttacker].holdEffect; - else - holdEffect = ItemId_GetHoldEffect(item); - - gStringBank = gBankAttacker; - - critChance = 2 * ((gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0) - + (gBattleMoves[gCurrentMove].effect == EFFECT_HIGH_CRITICAL) - + (gBattleMoves[gCurrentMove].effect == EFFECT_SKY_ATTACK) - + (gBattleMoves[gCurrentMove].effect == EFFECT_BLAZE_KICK) - + (gBattleMoves[gCurrentMove].effect == EFFECT_POISON_TAIL) - + (holdEffect == HOLD_EFFECT_SCOPE_LENS) - + 2 * (holdEffect == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBankAttacker].species == SPECIES_CHANSEY) - + 2 * (holdEffect == HOLD_EFFECT_STICK && gBattleMons[gBankAttacker].species == SPECIES_FARFETCHD); - - if (critChance > 4) - critChance = 4; - - if ((gBattleMons[gBankTarget].ability != ABILITY_BATTLE_ARMOR && gBattleMons[gBankTarget].ability != ABILITY_SHELL_ARMOR) - && !(gStatuses3[gBankAttacker] & STATUS3_CANT_SCORE_A_CRIT) - && !(gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE)) - && !(Random() % sCriticalHitChance[critChance])) - gCritMultiplier = 2; - else - gCritMultiplier = 1; - - gBattlescriptCurrInstr++; -} - -static void atk05_damagecalc1(void) -{ - u16 sideStatus = gSideAffecting[GET_BANK_SIDE(gBankTarget)]; - gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, - sideStatus, gDynamicBasePower, - gBattleStruct->dynamicMoveType, gBankAttacker, gBankTarget); - gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting.dmgMultiplier; - - if (gStatuses3[gBankAttacker] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) - gBattleMoveDamage *= 2; - if (gProtectStructs[gBankAttacker].helpingHand) - gBattleMoveDamage = gBattleMoveDamage * 15 / 10; - - gBattlescriptCurrInstr++; -} - -void AI_CalcDmg(u8 bankAtk, u8 bankDef) -{ - u16 sideStatus = gSideAffecting[GET_BANK_SIDE(bankDef)]; - gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[bankAtk], &gBattleMons[bankDef], gCurrentMove, - sideStatus, gDynamicBasePower, - gBattleStruct->dynamicMoveType, bankAtk, bankDef); - gDynamicBasePower = 0; - gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting.dmgMultiplier; - - if (gStatuses3[bankAtk] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) - gBattleMoveDamage *= 2; - if (gProtectStructs[bankAtk].helpingHand) - gBattleMoveDamage = gBattleMoveDamage * 15 / 10; -} - -static void ModulateDmgByType(u8 multiplier) -{ - gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; - if (gBattleMoveDamage == 0 && multiplier != 0) - gBattleMoveDamage = 1; - - switch (multiplier) - { - case TYPE_MUL_NO_EFFECT: - gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; - gBattleMoveFlags &= ~MOVESTATUS_NOTVERYEFFECTIVE; - gBattleMoveFlags &= ~MOVESTATUS_SUPEREFFECTIVE; - break; - case TYPE_MUL_NOT_EFFECTIVE: - if (gBattleMoves[gCurrentMove].power && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) - { - if (gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE) - gBattleMoveFlags &= ~MOVESTATUS_SUPEREFFECTIVE; - else - gBattleMoveFlags |= MOVESTATUS_NOTVERYEFFECTIVE; - } - break; - case TYPE_MUL_SUPER_EFFECTIVE: - if (gBattleMoves[gCurrentMove].power && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) - { - if (gBattleMoveFlags & MOVESTATUS_NOTVERYEFFECTIVE) - gBattleMoveFlags &= ~MOVESTATUS_NOTVERYEFFECTIVE; - else - gBattleMoveFlags |= MOVESTATUS_SUPEREFFECTIVE; - } - break; - } -} - -#define TYPE_FORESIGHT 0xFE -#define TYPE_ENDTABLE 0xFF - -static void atk06_typecalc(void) -{ - s32 i = 0; - u8 moveType; - - if (gCurrentMove == MOVE_STRUGGLE) - { - gBattlescriptCurrInstr++; - return; - } - - GET_MOVE_TYPE(gCurrentMove, moveType); - - // check stab - if (gBattleMons[gBankAttacker].type1 == moveType || gBattleMons[gBankAttacker].type2 == moveType) - { - gBattleMoveDamage = gBattleMoveDamage * 15; - gBattleMoveDamage = gBattleMoveDamage / 10; - } - - if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) - { - gLastUsedAbility = gBattleMons[gBankTarget].ability; - gBattleMoveFlags |= (MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED); - gUnknown_02024250[gBankTarget] = 0; - gUnknown_02024258[gBankTarget] = 0; - gBattleCommunication[6] = moveType; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - else - { - while (gTypeEffectiveness[i] != TYPE_ENDTABLE) - { - if (gTypeEffectiveness[i] == TYPE_FORESIGHT) - { - if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) - break; - i += 3; - continue; - } - else if (gTypeEffectiveness[i] == moveType) - { - // check type1 - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1) - ModulateDmgByType(gTypeEffectiveness[i + 2]); - // check type2 - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && - gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2) - ModulateDmgByType(gTypeEffectiveness[i + 2]); - } - i += 3; - } - } - - if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2 - && (!(gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE) || ((gBattleMoveFlags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) - && gBattleMoves[gCurrentMove].power) - { - gLastUsedAbility = ABILITY_WONDER_GUARD; - gBattleMoveFlags |= MOVESTATUS_MISSED; - gUnknown_02024250[gBankTarget] = 0; - gUnknown_02024258[gBankTarget] = 0; - gBattleCommunication[6] = 3; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) - gProtectStructs[gBankAttacker].notEffective = 1; - - gBattlescriptCurrInstr++; -} - -static void CheckWonderGuardAndLevitate(void) -{ - u8 flags = 0; - s32 i = 0; - u8 moveType; - - if (gCurrentMove == MOVE_STRUGGLE || !gBattleMoves[gCurrentMove].power) - return; - - GET_MOVE_TYPE(gCurrentMove, moveType); - - if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) - { - gLastUsedAbility = ABILITY_LEVITATE; - gBattleCommunication[6] = moveType; - RecordAbilityBattle(gBankTarget, ABILITY_LEVITATE); - return; - } - - while (gTypeEffectiveness[i] != TYPE_ENDTABLE) - { - if (gTypeEffectiveness[i] == TYPE_FORESIGHT) - { - if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) - break; - i += 3; - continue; - } - if (gTypeEffectiveness[i] == moveType) - { - // check no effect - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 0) - { - gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; - gProtectStructs[gBankAttacker].notEffective = 1; - } - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && - gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 && - gTypeEffectiveness[i + 2] == TYPE_MUL_NO_EFFECT) - { - gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; - gProtectStructs[gBankAttacker].notEffective = 1; - } - - // check super effective - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 20) - flags |= 1; - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 - && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 - && gTypeEffectiveness[i + 2] == TYPE_MUL_SUPER_EFFECTIVE) - flags |= 1; - - // check not very effective - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 5) - flags |= 2; - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 - && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 - && gTypeEffectiveness[i + 2] == TYPE_MUL_NOT_EFFECTIVE) - flags |= 2; - } - i += 3; - } - - if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2) - { - if (((flags & 2) || !(flags & 1)) && gBattleMoves[gCurrentMove].power) - { - gLastUsedAbility = ABILITY_WONDER_GUARD; - gBattleCommunication[6] = 3; - RecordAbilityBattle(gBankTarget, ABILITY_WONDER_GUARD); - } - } -} - -static void ModulateDmgByType2(u8 multiplier, u16 move, u8* flags) // same as ModulateDmgByType except different arguments -{ - gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; - if (gBattleMoveDamage == 0 && multiplier != 0) - gBattleMoveDamage = 1; - - switch (multiplier) - { - case TYPE_MUL_NO_EFFECT: - *flags |= MOVESTATUS_NOTAFFECTED; - *flags &= ~MOVESTATUS_NOTVERYEFFECTIVE; - *flags &= ~MOVESTATUS_SUPEREFFECTIVE; - break; - case TYPE_MUL_NOT_EFFECTIVE: - if (gBattleMoves[move].power && !(*flags & MOVESTATUS_NOEFFECT)) - { - if (*flags & MOVESTATUS_SUPEREFFECTIVE) - *flags &= ~MOVESTATUS_SUPEREFFECTIVE; - else - *flags |= MOVESTATUS_NOTVERYEFFECTIVE; - } - break; - case TYPE_MUL_SUPER_EFFECTIVE: - if (gBattleMoves[move].power && !(*flags & MOVESTATUS_NOEFFECT)) - { - if (*flags & MOVESTATUS_NOTVERYEFFECTIVE) - *flags &= ~MOVESTATUS_NOTVERYEFFECTIVE; - else - *flags |= MOVESTATUS_SUPEREFFECTIVE; - } - break; - } -} - -u8 TypeCalc(u16 move, u8 bankAtk, u8 bankDef) -{ - s32 i = 0; - u8 flags = 0; - u8 moveType; - - if (move == MOVE_STRUGGLE) - return 0; - - moveType = gBattleMoves[move].type; - - // check stab - if (gBattleMons[bankAtk].type1 == moveType || gBattleMons[bankAtk].type2 == moveType) - { - gBattleMoveDamage = gBattleMoveDamage * 15; - gBattleMoveDamage = gBattleMoveDamage / 10; - } - - if (gBattleMons[bankDef].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) - { - flags |= (MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED); - } - else - { - while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) - { - if (gTypeEffectiveness[i] == TYPE_FORESIGHT) - { - if (gBattleMons[bankDef].status2 & STATUS2_FORESIGHT) - break; - i += 3; - continue; - } - - else if (gTypeEffectiveness[i] == moveType) - { - // check type1 - if (gTypeEffectiveness[i + 1] == gBattleMons[bankDef].type1) - ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); - // check type2 - if (gTypeEffectiveness[i + 1] == gBattleMons[bankDef].type2 && - gBattleMons[bankDef].type1 != gBattleMons[bankDef].type2) - ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); - } - i += 3; - } - } - - if (gBattleMons[bankDef].ability == ABILITY_WONDER_GUARD && !(flags & MOVESTATUS_MISSED) - && AttacksThisTurn(bankAtk, move) == 2 - && (!(flags & MOVESTATUS_SUPEREFFECTIVE) || ((flags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) - && gBattleMoves[move].power) - { - flags |= MOVESTATUS_MISSED; - } - return flags; -} - -u8 AI_TypeCalc(u16 move, u16 species, u8 ability) -{ - s32 i = 0; - u8 flags = 0; - u8 type1 = gBaseStats[species].type1, type2 = gBaseStats[species].type2; - u8 moveType; - - if (move == MOVE_STRUGGLE) - return 0; - - moveType = gBattleMoves[move].type; - - if (ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) - { - flags = MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED; - } - else - { - while (gTypeEffectiveness[i] != TYPE_ENDTABLE) - { - if (gTypeEffectiveness[i] == TYPE_FORESIGHT) - { - i += 3; - continue; - } - if (gTypeEffectiveness[i] == moveType) - { - // check type1 - if (gTypeEffectiveness[i + 1] == type1) - ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); - // check type2 - if (gTypeEffectiveness[i + 1] == type2 && type1 != type2) - ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); - } - i += 3; - } - } - if (ability == ABILITY_WONDER_GUARD - && (!(flags & MOVESTATUS_SUPEREFFECTIVE) || ((flags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) - && gBattleMoves[move].power) - flags |= MOVESTATUS_NOTAFFECTED; - return flags; -} - -// Multiplies the damage by a random factor between 85% to 100% inclusive -static inline void ApplyRandomDmgMultiplier(void) -{ - u16 rand = Random(); - u16 randPercent = 100 - (rand % 16); - - if (gBattleMoveDamage != 0) - { - gBattleMoveDamage *= randPercent; - gBattleMoveDamage /= 100; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - } -} - -static void Unused_ApplyRandomDmgMultiplier(void) -{ - ApplyRandomDmgMultiplier(); -} - -static void atk07_dmg_adjustment(void) -{ - u8 holdEffect, quality; - - ApplyRandomDmgMultiplier(); - - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - { - holdEffect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; - } - else - { - holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); - } - - gStringBank = gBankTarget; - - if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) - { - RecordItemEffectBattle(gBankTarget, holdEffect); - gSpecialStatuses[gBankTarget].focusBanded = 1; - } - if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) - goto END; - if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE && !gProtectStructs[gBankTarget].endured - && !gSpecialStatuses[gBankTarget].focusBanded) - goto END; - - if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) - goto END; - - gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; - - if (gProtectStructs[gBankTarget].endured) - { - gBattleMoveFlags |= MOVESTATUS_ENDURED; - } - else if (gSpecialStatuses[gBankTarget].focusBanded) - { - gBattleMoveFlags |= MOVESTATUS_HUNGON; - gLastUsedItem = gBattleMons[gBankTarget].item; - } - - END: - gBattlescriptCurrInstr++; -} - -static void atk08_dmg_adjustment2(void) // The same as 0x7 except it doesn't check for false swipe move effect. -{ - u8 holdEffect, quality; - - ApplyRandomDmgMultiplier(); - - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - { - holdEffect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; - } - else - { - holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); - } - - gStringBank = gBankTarget; - - if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) - { - RecordItemEffectBattle(gBankTarget, holdEffect); - gSpecialStatuses[gBankTarget].focusBanded = 1; - } - if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) - goto END; - if (!gProtectStructs[gBankTarget].endured && !gSpecialStatuses[gBankTarget].focusBanded) - goto END; - if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) - goto END; - - gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; - - if (gProtectStructs[gBankTarget].endured) - { - gBattleMoveFlags |= MOVESTATUS_ENDURED; - } - else if (gSpecialStatuses[gBankTarget].focusBanded) - { - gBattleMoveFlags |= MOVESTATUS_HUNGON; - gLastUsedItem = gBattleMons[gBankTarget].item; - } - - END: - gBattlescriptCurrInstr++; -} - -static void atk09_attackanimation(void) -{ - if (gBattleExecBuffer) - return; - - if ((gHitMarker & HITMARKER_NO_ANIMATIONS) && (gCurrentMove != MOVE_TRANSFORM && gCurrentMove != MOVE_SUBSTITUTE)) - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_Pausex20; - gBattleScripting.animTurn++; - gBattleScripting.animTargetsHit++; - } - else - { - if ((gBattleMoves[gCurrentMove].target & MOVE_TARGET_BOTH - || gBattleMoves[gCurrentMove].target & MOVE_TARGET_FOES_AND_ALLY - || gBattleMoves[gCurrentMove].target & MOVE_TARGET_DEPENDS) - && gBattleScripting.animTargetsHit) - { - gBattlescriptCurrInstr++; - return; - } - if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) - { - u8 multihit; - - gActiveBank = gBankAttacker; - - if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) - multihit = gMultiHitCounter; - else if (gMultiHitCounter != 0 && gMultiHitCounter != 1) - { - if (gBattleMons[gBankTarget].hp <= gBattleMoveDamage) - multihit = 1; - else - multihit = gMultiHitCounter; - } - else - multihit = gMultiHitCounter; - - EmitMoveAnimation(0, gCurrentMove, gBattleScripting.animTurn, gBattleMovePower, gBattleMoveDamage, gBattleMons[gBankAttacker].friendship, &gDisableStructs[gBankAttacker], multihit); - gBattleScripting.animTurn += 1; - gBattleScripting.animTargetsHit += 1; - MarkBufferBankForExecution(gBankAttacker); - gBattlescriptCurrInstr++; - } - else - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_Pausex20; - } - } -} - -static void atk0A_waitanimation(void) -{ - if (gBattleExecBuffer == 0) - gBattlescriptCurrInstr++; -} - -static void atk0B_healthbarupdate(void) -{ - if (gBattleExecBuffer) - return; - - if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) - { - PrepareStringBattle(0x80, gActiveBank); - } - else - { - s16 healthValue; - - s32 currDmg = gBattleMoveDamage; - s32 maxPossibleDmgValue = 10000; // not present in R/S, ensures that huge damage values don't change sign - - if (currDmg <= maxPossibleDmgValue) - healthValue = currDmg; - else - healthValue = maxPossibleDmgValue; - - EmitHealthBarUpdate(0, healthValue); - MarkBufferBankForExecution(gActiveBank); - - if (GetBankSide(gActiveBank) == SIDE_PLAYER && gBattleMoveDamage > 0) - gBattleResults.unk5_0 = 1; - } - } - - gBattlescriptCurrInstr += 2; -} - -static void atk0C_datahpupdate(void) -{ - u32 moveType; - - if (gBattleExecBuffer) - return; - - if (gBattleStruct->dynamicMoveType == 0) - moveType = gBattleMoves[gCurrentMove].type; - else if (!(gBattleStruct->dynamicMoveType & 0x40)) - moveType = gBattleStruct->dynamicMoveType & 0x3F; - else - moveType = gBattleMoves[gCurrentMove].type; - - if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) - { - if (gDisableStructs[gActiveBank].substituteHP >= gBattleMoveDamage) - { - if (gSpecialStatuses[gActiveBank].moveturnLostHP == 0) - gSpecialStatuses[gActiveBank].moveturnLostHP = gBattleMoveDamage; - gDisableStructs[gActiveBank].substituteHP -= gBattleMoveDamage; - gHpDealt = gBattleMoveDamage; - } - else - { - if (gSpecialStatuses[gActiveBank].moveturnLostHP == 0) - gSpecialStatuses[gActiveBank].moveturnLostHP = gDisableStructs[gActiveBank].substituteHP; - gHpDealt = gDisableStructs[gActiveBank].substituteHP; - gDisableStructs[gActiveBank].substituteHP = 0; - } - // check substitute fading - if (gDisableStructs[gActiveBank].substituteHP == 0) - { - gBattlescriptCurrInstr += 2; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_SubstituteFade; - return; - } - } - else - { - gHitMarker &= ~(HITMARKER_IGNORE_SUBSTITUTE); - if (gBattleMoveDamage < 0) // hp goes up - { - gBattleMons[gActiveBank].hp -= gBattleMoveDamage; - if (gBattleMons[gActiveBank].hp > gBattleMons[gActiveBank].maxHP) - gBattleMons[gActiveBank].hp = gBattleMons[gActiveBank].maxHP; - - } - else // hp goes down - { - if (gHitMarker & HITMARKER_x20) - { - gHitMarker &= ~(HITMARKER_x20); - } - else - { - gTakenDmg[gActiveBank] += gBattleMoveDamage; - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) - gTakenDmgBanks[gActiveBank] = gBankAttacker; - else - gTakenDmgBanks[gActiveBank] = gBankTarget; - } - - if (gBattleMons[gActiveBank].hp > gBattleMoveDamage) - { - gBattleMons[gActiveBank].hp -= gBattleMoveDamage; - gHpDealt = gBattleMoveDamage; - } - else - { - gHpDealt = gBattleMons[gActiveBank].hp; - gBattleMons[gActiveBank].hp = 0; - } - - if (!gSpecialStatuses[gActiveBank].moveturnLostHP && !(gHitMarker & HITMARKER_x100000)) - gSpecialStatuses[gActiveBank].moveturnLostHP = gHpDealt; - - if (moveType <= 8 && !(gHitMarker & HITMARKER_x100000) && gCurrentMove != MOVE_PAIN_SPLIT) - { - gProtectStructs[gActiveBank].physicalDmg = gHpDealt; - gSpecialStatuses[gActiveBank].moveturnLostHP_physical = gHpDealt; - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) - { - gProtectStructs[gActiveBank].physicalBank = gBankAttacker; - gSpecialStatuses[gActiveBank].moveturnPhysicalBank = gBankAttacker; - } - else - { - gProtectStructs[gActiveBank].physicalBank = gBankTarget; - gSpecialStatuses[gActiveBank].moveturnPhysicalBank = gBankTarget; - } - } - else if (moveType > 8 && !(gHitMarker & HITMARKER_x100000)) - { - gProtectStructs[gActiveBank].specialDmg = gHpDealt; - gSpecialStatuses[gActiveBank].moveturnLostHP_special = gHpDealt; - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) - { - gProtectStructs[gActiveBank].specialBank = gBankAttacker; - gSpecialStatuses[gActiveBank].moveturnSpecialBank = gBankAttacker; - } - else - { - gProtectStructs[gActiveBank].specialBank = gBankTarget; - gSpecialStatuses[gActiveBank].moveturnSpecialBank = gBankTarget; - } - } - } - gHitMarker &= ~(HITMARKER_x100000); - EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBank].hp); - MarkBufferBankForExecution(gActiveBank); - } - } - else - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - if (gSpecialStatuses[gActiveBank].moveturnLostHP == 0) - gSpecialStatuses[gActiveBank].moveturnLostHP = 0xFFFF; - } - gBattlescriptCurrInstr += 2; -} - -static void atk0D_critmessage(void) -{ - if (gBattleExecBuffer == 0) - { - if (gCritMultiplier == 2 && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) - { - PrepareStringBattle(0xD9, gBankAttacker); - gBattleCommunication[MSG_DISPLAY] = 1; - } - gBattlescriptCurrInstr++; - } -} - -static void atk0E_effectiveness_sound(void) -{ - if (gBattleExecBuffer) - return; - - gActiveBank = gBankTarget; - if (!(gBattleMoveFlags & MOVESTATUS_MISSED)) - { - switch (gBattleMoveFlags & (u8)(~(MOVESTATUS_MISSED))) - { - case MOVESTATUS_SUPEREFFECTIVE: - EmitEffectivenessSound(0, SE_KOUKA_H); - MarkBufferBankForExecution(gActiveBank); - break; - case MOVESTATUS_NOTVERYEFFECTIVE: - EmitEffectivenessSound(0, SE_KOUKA_L); - MarkBufferBankForExecution(gActiveBank); - break; - case MOVESTATUS_NOTAFFECTED: - case MOVESTATUS_FAILED: - // no sound - break; - case MOVESTATUS_ENDURED: - case MOVESTATUS_ONEHITKO: - case MOVESTATUS_HUNGON: - default: - if (gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE) - { - EmitEffectivenessSound(0, SE_KOUKA_H); - MarkBufferBankForExecution(gActiveBank); - } - else if (gBattleMoveFlags & MOVESTATUS_NOTVERYEFFECTIVE) - { - EmitEffectivenessSound(0, SE_KOUKA_L); - MarkBufferBankForExecution(gActiveBank); - } - else if (!(gBattleMoveFlags & (MOVESTATUS_NOTAFFECTED | MOVESTATUS_FAILED))) - { - EmitEffectivenessSound(0, SE_KOUKA_M); - MarkBufferBankForExecution(gActiveBank); - } - break; - } - } - gBattlescriptCurrInstr++; -} - -static void atk0F_resultmessage(void) -{ - u32 stringId = 0; - - if (gBattleExecBuffer) - return; - - if (gBattleMoveFlags & MOVESTATUS_MISSED && (!(gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) || gBattleCommunication[6] > 2)) - { - stringId = gMissStringIds[gBattleCommunication[6]]; - gBattleCommunication[MSG_DISPLAY] = 1; - } - else - { - gBattleCommunication[MSG_DISPLAY] = 1; - switch (gBattleMoveFlags & (u8)(~(MOVESTATUS_MISSED))) - { - case MOVESTATUS_SUPEREFFECTIVE: - stringId = 0xDE; - break; - case MOVESTATUS_NOTVERYEFFECTIVE: - stringId = 0xDD; - break; - case MOVESTATUS_ONEHITKO: - stringId = 0xDA; - break; - case MOVESTATUS_ENDURED: - stringId = 0x99; - break; - case MOVESTATUS_FAILED: - stringId = 0xE5; - break; - case MOVESTATUS_NOTAFFECTED: - stringId = 0x1B; - break; - case MOVESTATUS_HUNGON: - gLastUsedItem = gBattleMons[gBankTarget].item; - gStringBank = gBankTarget; - gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_HangedOnMsg; - return; - default: - if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) - { - stringId = 0x1B; - } - else if (gBattleMoveFlags & MOVESTATUS_ONEHITKO) - { - gBattleMoveFlags &= ~(MOVESTATUS_ONEHITKO); - gBattleMoveFlags &= ~(MOVESTATUS_SUPEREFFECTIVE); - gBattleMoveFlags &= ~(MOVESTATUS_NOTVERYEFFECTIVE); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_OneHitKOMsg; - return; - } - else if (gBattleMoveFlags & MOVESTATUS_ENDURED) - { - gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_EnduredMsg; - return; - } - else if (gBattleMoveFlags & MOVESTATUS_HUNGON) - { - gLastUsedItem = gBattleMons[gBankTarget].item; - gStringBank = gBankTarget; - gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_HangedOnMsg; - return; - } - else if (gBattleMoveFlags & MOVESTATUS_FAILED) - { - stringId = 0xE5; - } - else - { - gBattleCommunication[MSG_DISPLAY] = 0; - } - } - } - - if (stringId) - PrepareStringBattle(stringId, gBankAttacker); - - gBattlescriptCurrInstr++; -} - -static void atk10_printstring(void) -{ - if (gBattleExecBuffer == 0) - { - u16 var = BS2ScriptRead16(gBattlescriptCurrInstr + 1); - PrepareStringBattle(var, gBankAttacker); - gBattlescriptCurrInstr += 3; - gBattleCommunication[MSG_DISPLAY] = 1; - } -} - -static void atk11_printstring_playeronly(void) -{ - gActiveBank = gBankAttacker; - - EmitPrintStringPlayerOnly(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1)); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 3; - gBattleCommunication[MSG_DISPLAY] = 1; -} - -static void atk12_waitmessage(void) -{ - if (gBattleExecBuffer == 0) - { - if (!gBattleCommunication[MSG_DISPLAY]) - { - gBattlescriptCurrInstr += 3; - } - else - { - u16 toWait = BS2ScriptRead16(gBattlescriptCurrInstr + 1); - if (++gPauseCounterBattle >= toWait) - { - gPauseCounterBattle = 0; - gBattlescriptCurrInstr += 3; - gBattleCommunication[MSG_DISPLAY] = 0; - } - } - } -} - -static void atk13_printfromtable(void) -{ - if (gBattleExecBuffer == 0) - { - const u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - ptr += gBattleCommunication[MULTISTRING_CHOOSER]; - - PrepareStringBattle(*ptr, gBankAttacker); - - gBattlescriptCurrInstr += 5; - gBattleCommunication[MSG_DISPLAY] = 1; - } -} - -static void atk14_printfromtable_playeronly(void) -{ - if (gBattleExecBuffer == 0) - { - const u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - ptr += gBattleCommunication[MULTISTRING_CHOOSER]; - - gActiveBank = gBankAttacker; - EmitPrintStringPlayerOnly(0, *ptr); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 5; - gBattleCommunication[MSG_DISPLAY] = 1; - } -} - -u8 BankGetTurnOrder(u8 bank) -{ - s32 i; - for (i = 0; i < gNoOfAllBanks; i++) - { - if (gTurnOrder[i] == bank) - break; - } - return i; -} - -#define INCREMENT_RESET_RETURN \ -{ \ - gBattlescriptCurrInstr++; \ - gBattleCommunication[MOVE_EFFECT_BYTE] = 0; \ - return; \ -} - -#define RESET_RETURN \ -{ \ - gBattleCommunication[MOVE_EFFECT_BYTE] = 0; \ - return; \ -} - -void SetMoveEffect(bool8 primary, u8 certain) -{ - bool32 statusChanged = FALSE; - u8 affectsUser = 0; // 0x40 otherwise - bool32 noSunCanFreeze = TRUE; - - if (gBattleCommunication[MOVE_EFFECT_BYTE] & MOVE_EFFECT_AFFECTS_USER) - { - gEffectBank = gBankAttacker; // bank that effects get applied on - gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(MOVE_EFFECT_AFFECTS_USER); - affectsUser = MOVE_EFFECT_AFFECTS_USER; - gBattleScripting.bank = gBankTarget; // theoretically the attacker - } - else - { - gEffectBank = gBankTarget; - gBattleScripting.bank = gBankAttacker; - } - - if (gBattleMons[gEffectBank].ability == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - && !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 9) - INCREMENT_RESET_RETURN - - if (gSideAffecting[GET_BANK_SIDE(gEffectBank)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - && !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 7) - INCREMENT_RESET_RETURN - - if (gBattleMons[gEffectBank].hp == 0 - && gBattleCommunication[MOVE_EFFECT_BYTE] != MOVE_EFFECT_PAYDAY - && gBattleCommunication[MOVE_EFFECT_BYTE] != MOVE_EFFECT_STEAL_ITEM) - INCREMENT_RESET_RETURN - - if (gBattleMons[gEffectBank].status2 & STATUS2_SUBSTITUTE && affectsUser != MOVE_EFFECT_AFFECTS_USER) - INCREMENT_RESET_RETURN - - if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) // status change - { - switch (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) - { - case STATUS_SLEEP: - // check active uproar - if (gBattleMons[gEffectBank].ability != ABILITY_SOUNDPROOF) - { - for (gActiveBank = 0; - gActiveBank < gNoOfAllBanks && !(gBattleMons[gActiveBank].status2 & STATUS2_UPROAR); - gActiveBank++) - {} - } - else - gActiveBank = gNoOfAllBanks; - - if (gBattleMons[gEffectBank].status1) - break; - if (gActiveBank != gNoOfAllBanks) - break; - if (gBattleMons[gEffectBank].ability == ABILITY_VITAL_SPIRIT) - break; - if (gBattleMons[gEffectBank].ability == ABILITY_INSOMNIA) - break; - - CancelMultiTurnMoves(gEffectBank); - statusChanged = TRUE; - break; - case STATUS_POISON: - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY - && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) - { - gLastUsedAbility = ABILITY_IMMUNITY; - RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_PSNPrevention; - - if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - RESET_RETURN - } - if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON - || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) - && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_PSNPrevention; - - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - RESET_RETURN - } - if (gBattleMons[gEffectBank].type1 == TYPE_POISON) - break; - if (gBattleMons[gEffectBank].type2 == TYPE_POISON) - break; - if (gBattleMons[gEffectBank].type1 == TYPE_STEEL) - break; - if (gBattleMons[gEffectBank].type2 == TYPE_STEEL) - break; - if (gBattleMons[gEffectBank].status1) - break; - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) - break; - - statusChanged = TRUE; - break; - case STATUS_BURN: - if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL - && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) - { - gLastUsedAbility = ABILITY_WATER_VEIL; - RecordAbilityBattle(gEffectBank, ABILITY_WATER_VEIL); - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_BRNPrevention; - if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - RESET_RETURN - } - if ((gBattleMons[gEffectBank].type1 == TYPE_FIRE - || gBattleMons[gEffectBank].type2 == TYPE_FIRE) - && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_BRNPrevention; - - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - RESET_RETURN - } - if (gBattleMons[gEffectBank].type1 == TYPE_FIRE) - break; - if (gBattleMons[gEffectBank].type2 == TYPE_FIRE) - break; - if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL) - break; - if (gBattleMons[gEffectBank].status1) - break; - - statusChanged = TRUE; - break; - case STATUS_FREEZE: - if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY) - noSunCanFreeze = FALSE; - if (gBattleMons[gEffectBank].type1 == TYPE_ICE) - break; - if (gBattleMons[gEffectBank].type2 == TYPE_ICE) - break; - if (gBattleMons[gEffectBank].status1) - break; - if (noSunCanFreeze == 0) - break; - if (gBattleMons[gEffectBank].ability == ABILITY_MAGMA_ARMOR) - break; - - CancelMultiTurnMoves(gEffectBank); - statusChanged = TRUE; - break; - case STATUS_PARALYSIS: - if (gBattleMons[gEffectBank].ability == ABILITY_LIMBER) - { - if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN) - { - gLastUsedAbility = ABILITY_LIMBER; - RecordAbilityBattle(gEffectBank, ABILITY_LIMBER); - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_PRLZPrevention; - - if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - RESET_RETURN - } - else - break; - } - if (gBattleMons[gEffectBank].status1) - break; - - statusChanged = TRUE; - break; - case STATUS_TOXIC_POISON: - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) - { - gLastUsedAbility = ABILITY_IMMUNITY; - RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_PSNPrevention; - - if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - RESET_RETURN - } - if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON - || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) - && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_PSNPrevention; - - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - RESET_RETURN - } - if (gBattleMons[gEffectBank].status1) - break; - if (gBattleMons[gEffectBank].type1 != TYPE_POISON - && gBattleMons[gEffectBank].type2 != TYPE_POISON - && gBattleMons[gEffectBank].type1 != TYPE_STEEL - && gBattleMons[gEffectBank].type2 != TYPE_STEEL) - { - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) - break; - - // It's redundant, because at this point we know the status1 value is 0. - gBattleMons[gEffectBank].status1 &= ~(STATUS_TOXIC_POISON); - gBattleMons[gEffectBank].status1 &= ~(STATUS_POISON); - statusChanged = TRUE; - break; - } - else - { - gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; - } - break; - } - if (statusChanged == TRUE) - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - - if (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS_SLEEP) - gBattleMons[gEffectBank].status1 |= ((Random() & 3) + 2); - else - gBattleMons[gEffectBank].status1 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; - - gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - - gActiveBank = gEffectBank; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBank].status1); - MarkBufferBankForExecution(gActiveBank); - - if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - - // for synchronize - - if (gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_POISON - || gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_TOXIC - || gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_PARALYSIS - || gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_BURN) - { - u8* synchronizeEffect = &gBattleStruct->synchronizeMoveEffect; - *synchronizeEffect = gBattleCommunication[MOVE_EFFECT_BYTE]; - gHitMarker |= HITMARKER_SYNCHRONISE_EFFECT; - } - return; - } - else if (statusChanged == FALSE) - { - gBattleCommunication[MOVE_EFFECT_BYTE] = 0; - gBattlescriptCurrInstr++; - return; - } - return; - } - else - { - if (gBattleMons[gEffectBank].status2 & sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) - { - gBattlescriptCurrInstr++; - } - else - { - u8 side; - switch (gBattleCommunication[MOVE_EFFECT_BYTE]) - { - case MOVE_EFFECT_CONFUSION: - if (gBattleMons[gEffectBank].ability == ABILITY_OWN_TEMPO - || gBattleMons[gEffectBank].status2 & STATUS2_CONFUSION) - { - gBattlescriptCurrInstr++; - } - else - { - gBattleMons[gEffectBank].status2 |= (((Random()) % 0x4)) + 2; - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - } - break; - case MOVE_EFFECT_FLINCH: - if (gBattleMons[gEffectBank].ability == ABILITY_INNER_FOCUS) - { - if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN) - { - gLastUsedAbility = ABILITY_INNER_FOCUS; - RecordAbilityBattle(gEffectBank, ABILITY_INNER_FOCUS); - gBattlescriptCurrInstr = BattleScript_FlinchPrevention; - } - else - { - gBattlescriptCurrInstr++; - } - } - else - { - if (BankGetTurnOrder(gEffectBank) > gCurrentMoveTurn) - gBattleMons[gEffectBank].status2 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; - gBattlescriptCurrInstr++; - } - break; - case MOVE_EFFECT_UPROAR: - if (!(gBattleMons[gEffectBank].status2 & STATUS2_UPROAR)) - { - - gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gEffectBank] = gCurrentMove; - gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 4; - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - } - else - { - gBattlescriptCurrInstr++; - } - break; - case MOVE_EFFECT_PAYDAY: - if (GET_BANK_SIDE(gBankAttacker) == SIDE_PLAYER) - { - u16 PayDay = gPaydayMoney; - gPaydayMoney += (gBattleMons[gBankAttacker].level * 5); - if (PayDay > gPaydayMoney) - gPaydayMoney = 0xFFFF; - } - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - break; - case MOVE_EFFECT_TRI_ATTACK: - if (gBattleMons[gEffectBank].status1) - { - gBattlescriptCurrInstr++; - } - else - { - gBattleCommunication[MOVE_EFFECT_BYTE] = Random() % 3 + 3; - SetMoveEffect(FALSE, 0); - } - break; - case MOVE_EFFECT_CHARGING: - gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gEffectBank] = gCurrentMove; - gProtectStructs[gEffectBank].chargingTurn = 1; - gBattlescriptCurrInstr++; - break; - case MOVE_EFFECT_WRAP: - if (gBattleMons[gEffectBank].status2 & STATUS2_WRAPPED) - { - gBattlescriptCurrInstr++; - } - else - { - gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 3) << 0xD; - - *(gBattleStruct->wrappedMove + gEffectBank * 2 + 0) = gCurrentMove; - *(gBattleStruct->wrappedMove + gEffectBank * 2 + 1) = gCurrentMove >> 8; - *(gBattleStruct->wrappedBy + gEffectBank) = gBankAttacker; - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - - for (gBattleCommunication[MULTISTRING_CHOOSER] = 0; ; gBattleCommunication[MULTISTRING_CHOOSER]++) - { - if (gBattleCommunication[MULTISTRING_CHOOSER] > 4) - break; - if (gTrappingMoves[gBattleCommunication[MULTISTRING_CHOOSER]] == gCurrentMove) - break; - } - } - break; - case MOVE_EFFECT_RECOIL_25: // 25% recoil - gBattleMoveDamage = (gHpDealt) / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - break; - case MOVE_EFFECT_ATK_PLUS_1: - case MOVE_EFFECT_DEF_PLUS_1: - case MOVE_EFFECT_SPD_PLUS_1: - case MOVE_EFFECT_SP_ATK_PLUS_1: - case MOVE_EFFECT_SP_DEF_PLUS_1: - case MOVE_EFFECT_ACC_PLUS_1: - case MOVE_EFFECT_EVS_PLUS_1: - if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1), - gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_PLUS_1 + 1, - affectsUser, 0)) - { - gBattlescriptCurrInstr++; - } - else - { - gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); - gBattleScripting.animArg2 = 0; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_StatUp; - } - break; - case MOVE_EFFECT_ATK_MINUS_1: - case MOVE_EFFECT_DEF_MINUS_1: - case MOVE_EFFECT_SPD_MINUS_1: - case MOVE_EFFECT_SP_ATK_MINUS_1: - case MOVE_EFFECT_SP_DEF_MINUS_1: - case MOVE_EFFECT_ACC_MINUS_1: - case MOVE_EFFECT_EVS_MINUS_1: - if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE, - gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_MINUS_1 + 1, - affectsUser, 0)) - { - gBattlescriptCurrInstr++; - } - else - { - gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); - gBattleScripting.animArg2 = 0; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_StatDown; - } - break; - case MOVE_EFFECT_ATK_PLUS_2: - case MOVE_EFFECT_DEF_PLUS_2: - case MOVE_EFFECT_SPD_PLUS_2: - case MOVE_EFFECT_SP_ATK_PLUS_2: - case MOVE_EFFECT_SP_DEF_PLUS_2: - case MOVE_EFFECT_ACC_PLUS_2: - case MOVE_EFFECT_EVS_PLUS_2: - if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2), - gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_PLUS_2 + 1, - affectsUser, 0)) - { - gBattlescriptCurrInstr++; - } - else - { - gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); - gBattleScripting.animArg2 = 0; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_StatUp; - } - break; - case MOVE_EFFECT_ATK_MINUS_2: - case MOVE_EFFECT_DEF_MINUS_2: - case MOVE_EFFECT_SPD_MINUS_2: - case MOVE_EFFECT_SP_ATK_MINUS_2: - case MOVE_EFFECT_SP_DEF_MINUS_2: - case MOVE_EFFECT_ACC_MINUS_2: - case MOVE_EFFECT_EVS_MINUS_2: - if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE, - gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_MINUS_2 + 1, - affectsUser, 0)) - { - gBattlescriptCurrInstr++; - } - else - { - gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); - gBattleScripting.animArg2 = 0; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_StatDown; - } - break; - case MOVE_EFFECT_RECHARGE: - gBattleMons[gEffectBank].status2 |= STATUS2_RECHARGE; - gDisableStructs[gEffectBank].rechargeCounter = 2; - gLockedMoves[gEffectBank] = gCurrentMove; - gBattlescriptCurrInstr++; - break; - case MOVE_EFFECT_RAGE: - gBattleMons[gBankAttacker].status2 |= STATUS2_RAGE; - gBattlescriptCurrInstr++; - break; - case MOVE_EFFECT_STEAL_ITEM: - { - if (gBattleTypeFlags & BATTLE_TYPE_x4000000) - { - gBattlescriptCurrInstr++; - break; - } - - side = GetBankSide(gBankAttacker); - if (GetBankSide(gBankAttacker) == SIDE_OPPONENT - && !(gBattleTypeFlags & - (BATTLE_TYPE_EREADER_TRAINER - | BATTLE_TYPE_FRONTIER - | BATTLE_TYPE_LINK - | BATTLE_TYPE_x2000000 - | BATTLE_TYPE_SECRET_BASE))) - { - gBattlescriptCurrInstr++; - } - else if (!(gBattleTypeFlags & - (BATTLE_TYPE_EREADER_TRAINER - | BATTLE_TYPE_FRONTIER - | BATTLE_TYPE_LINK - | BATTLE_TYPE_x2000000 - | BATTLE_TYPE_SECRET_BASE)) - && (gWishFutureKnock.knockedOffPokes[side] & gBitTable[gBattlePartyID[gBankAttacker]])) - { - gBattlescriptCurrInstr++; - } - else if (gBattleMons[gBankTarget].item - && gBattleMons[gBankTarget].ability == ABILITY_STICKY_HOLD) - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_NoItemSteal; - - gLastUsedAbility = gBattleMons[gBankTarget].ability; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - else if (gBattleMons[gBankAttacker].item != 0 - || gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY - || IS_ITEM_MAIL(gBattleMons[gBankTarget].item) - || gBattleMons[gBankTarget].item == 0) - { - gBattlescriptCurrInstr++; - } - else - { - u16* changedItem = &gBattleStruct->changedItems[gBankAttacker]; - gLastUsedItem = *changedItem = gBattleMons[gBankTarget].item; - gBattleMons[gBankTarget].item = 0; - - gActiveBank = gBankAttacker; - EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedItem); - MarkBufferBankForExecution(gBankAttacker); - - gActiveBank = gBankTarget; - EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); - MarkBufferBankForExecution(gBankTarget); - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_ItemSteal; - - *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 0) = 0; - *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 1) = 0; - } - - } - break; - case MOVE_EFFECT_PREVENT_ESCAPE: - gBattleMons[gBankTarget].status2 |= STATUS2_ESCAPE_PREVENTION; - gDisableStructs[gBankTarget].bankPreventingEscape = gBankAttacker; - gBattlescriptCurrInstr++; - break; - case MOVE_EFFECT_NIGHTMARE: - gBattleMons[gBankTarget].status2 |= STATUS2_NIGHTMARE; - gBattlescriptCurrInstr++; - break; - case MOVE_EFFECT_ALL_STATS_UP: - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_AllStatsUp; - break; - case MOVE_EFFECT_RAPIDSPIN: - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_RapidSpinAway; - break; - case MOVE_EFFECT_REMOVE_PARALYSIS: // Smelling salts - if (!(gBattleMons[gBankTarget].status1 & STATUS_PARALYSIS)) - { - gBattlescriptCurrInstr++; - } - else - { - gBattleMons[gBankTarget].status1 &= ~(STATUS_PARALYSIS); - - gActiveBank = gBankTarget; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); - MarkBufferBankForExecution(gActiveBank); - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal; - } - break; - case MOVE_EFFECT_ATK_DEF_DOWN: // SuperPower - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_AtkDefDown; - break; - case MOVE_EFFECT_RECOIL_33_PARALYSIS: // Volt Tackle - gBattleMoveDamage = gHpDealt / 3; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - break; - case MOVE_EFFECT_THRASH: - if (gBattleMons[gEffectBank].status2 & STATUS2_LOCK_CONFUSE) - { - gBattlescriptCurrInstr++; - } - else - { - gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gEffectBank] = gCurrentMove; - gBattleMons[gEffectBank].status2 |= (((Random() & 1) + 2) << 0xA); - } - break; - case MOVE_EFFECT_KNOCK_OFF: - if (gBattleMons[gEffectBank].ability == ABILITY_STICKY_HOLD) - { - if (gBattleMons[gEffectBank].item == 0) - { - gBattlescriptCurrInstr++; - } - else - { - gLastUsedAbility = ABILITY_STICKY_HOLD; - gBattlescriptCurrInstr = BattleScript_StickyHoldActivates; - RecordAbilityBattle(gEffectBank, ABILITY_STICKY_HOLD); - } - break; - } - if (gBattleMons[gEffectBank].item) - { - side = GetBankSide(gEffectBank); - - gLastUsedItem = gBattleMons[gEffectBank].item; - gBattleMons[gEffectBank].item = 0; - gWishFutureKnock.knockedOffPokes[side] |= gBitTable[gBattlePartyID[gEffectBank]]; - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_KnockedOff; - - *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBank]) + 0) = 0; - *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBank]) + 1) = 0; - } - else - { - gBattlescriptCurrInstr++; - } - break; - case MOVE_EFFECT_SP_ATK_TWO_DOWN: // Overheat - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_SAtkDown2; - break; - } - } - } - - gBattleCommunication[MOVE_EFFECT_BYTE] = 0; -} - -static void atk15_seteffectwithchance(void) -{ - u32 percentChance; - - if (gBattleMons[gBankAttacker].ability == ABILITY_SERENE_GRACE) - percentChance = gBattleMoves[gCurrentMove].secondaryEffectChance * 2; - else - percentChance = gBattleMoves[gCurrentMove].secondaryEffectChance; - - if (gBattleCommunication[MOVE_EFFECT_BYTE] & MOVE_EFFECT_CERTAIN - && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) - { - gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(MOVE_EFFECT_CERTAIN); - SetMoveEffect(0, MOVE_EFFECT_CERTAIN); - } - else if (Random() % 100 < percentChance - && gBattleCommunication[MOVE_EFFECT_BYTE] - && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) - { - if (percentChance >= 100) - SetMoveEffect(0, MOVE_EFFECT_CERTAIN); - else - SetMoveEffect(0, 0); - } - else - { - gBattlescriptCurrInstr++; - } - - gBattleCommunication[MOVE_EFFECT_BYTE] = 0; - gBattleScripting.field_16 = 0; -} - -static void atk16_seteffectprimary(void) -{ - SetMoveEffect(TRUE, 0); -} - -static void atk17_seteffectsecondary(void) -{ - SetMoveEffect(FALSE, 0); -} - -static void atk18_status_effect_clear(void) -{ - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - if (gBattleCommunication[MOVE_EFFECT_BYTE] <= MOVE_EFFECT_TOXIC) - gBattleMons[gActiveBank].status1 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); - else - gBattleMons[gActiveBank].status2 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); - - gBattleCommunication[MOVE_EFFECT_BYTE] = 0; - gBattlescriptCurrInstr += 2; - gBattleScripting.field_16 = 0; -} - -static void atk19_faint_pokemon(void) -{ - const u8 *BS_ptr; - - if (gBattlescriptCurrInstr[2] != 0) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - if (gHitMarker & HITMARKER_FAINTED(gActiveBank)) - { - BS_ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 3); - - BattleScriptPop(); - gBattlescriptCurrInstr = BS_ptr; - gSideAffecting[GetBankSide(gActiveBank)] &= ~(SIDE_STATUS_SPIKES_DAMAGED); - } - else - { - gBattlescriptCurrInstr += 7; - } - } - else - { - u8 bank; - - if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER) - { - gActiveBank = gBankAttacker; - bank = gBankTarget; - BS_ptr = BattleScript_FaintAttacker; - } - else - { - gActiveBank = gBankTarget; - bank = gBankAttacker; - BS_ptr = BattleScript_FaintTarget; - } - if (!(gAbsentBankFlags & gBitTable[gActiveBank]) - && gBattleMons[gActiveBank].hp == 0) - { - gHitMarker |= HITMARKER_FAINTED(gActiveBank); - BattleScriptPush(gBattlescriptCurrInstr + 7); - gBattlescriptCurrInstr = BS_ptr; - if (GetBankSide(gActiveBank) == SIDE_PLAYER) - { - gHitMarker |= HITMARKER_x400000; - if (gBattleResults.playerFaintCounter < 0xFF) - gBattleResults.playerFaintCounter++; - AdjustFriendshipOnBattleFaint(gActiveBank); - } - else - { - if (gBattleResults.opponentFaintCounter < 0xFF) - gBattleResults.opponentFaintCounter++; - gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES, NULL); - } - if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBankAttacker].hp != 0) - { - gHitMarker &= ~(HITMARKER_DESTINYBOND); - BattleScriptPush(gBattlescriptCurrInstr); - gBattleMoveDamage = gBattleMons[bank].hp; - gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife; - } - if ((gStatuses3[gBankTarget] & STATUS3_GRUDGE) - && !(gHitMarker & HITMARKER_GRUDGE) - && GetBankSide(gBankAttacker) != GetBankSide(gBankTarget) - && gBattleMons[gBankAttacker].hp != 0 - && gCurrentMove != MOVE_STRUGGLE) - { - u8 moveIndex = *(gBattleStruct->chosenMovesIds + gBankAttacker); - - gBattleMons[gBankAttacker].pp[moveIndex] = 0; - BattleScriptPush(gBattlescriptCurrInstr); - gBattlescriptCurrInstr = BattleScript_GrudgeTakesPp; - gActiveBank = gBankAttacker; - EmitSetMonData(0, moveIndex + REQUEST_PPMOVE1_BATTLE, 0, 1, &gBattleMons[gActiveBank].pp[moveIndex]); - MarkBufferBankForExecution(gActiveBank); - - PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBankAttacker].moves[moveIndex]) - } - } - else - { - gBattlescriptCurrInstr += 7; - } - } -} - -static void atk1A_faint_animation(void) -{ - if (gBattleExecBuffer == 0) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - EmitFaintAnimation(0); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 2; - } -} - -static void atk1B_faint_effects_clear(void) -{ - if (gBattleExecBuffer == 0) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - if (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || gBattleMons[gActiveBank].hp == 0) - { - gBattleMons[gActiveBank].status1 = 0; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 0x4, &gBattleMons[gActiveBank].status1); - MarkBufferBankForExecution(gActiveBank); - } - - UndoEffectsAfterFainting(); // Effects like attractions, trapping, etc. - gBattlescriptCurrInstr += 2; - } -} - -static void atk1C_jumpifstatus(void) -{ - u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); - u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); - const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); - - if (gBattleMons[bank].status1 & flags && gBattleMons[bank].hp) - gBattlescriptCurrInstr = jumpPtr; - else - gBattlescriptCurrInstr += 10; -} - -static void atk1D_jumpifstatus2(void) -{ - u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); - u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); - const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); - - if (gBattleMons[bank].status2 & flags && gBattleMons[bank].hp) - gBattlescriptCurrInstr = jumpPtr; - else - gBattlescriptCurrInstr += 10; -} - -static void atk1E_jumpifability(void) -{ - u8 bank; - u8 ability = gBattlescriptCurrInstr[2]; - const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); - - if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER_SIDE) - { - bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_BANK_SIDE, gBankAttacker, ability, 0, 0); - if (bank) - { - gLastUsedAbility = ability; - gBattlescriptCurrInstr = jumpPtr; - RecordAbilityBattle(bank - 1, gLastUsedAbility); - gBattleScripting.field_15 = bank - 1; - } - else - gBattlescriptCurrInstr += 7; - } - else if (gBattlescriptCurrInstr[1] == BS_GET_NOT_ATTACKER_SIDE) - { - bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gBankAttacker, ability, 0, 0); - if (bank) - { - gLastUsedAbility = ability; - gBattlescriptCurrInstr = jumpPtr; - RecordAbilityBattle(bank - 1, gLastUsedAbility); - gBattleScripting.field_15 = bank - 1; - } - else - gBattlescriptCurrInstr += 7; - } - else - { - bank = GetBattleBank(gBattlescriptCurrInstr[1]); - if (gBattleMons[bank].ability == ability) - { - gLastUsedAbility = ability; - gBattlescriptCurrInstr = jumpPtr; - RecordAbilityBattle(bank, gLastUsedAbility); - gBattleScripting.field_15 = bank; - } - else - gBattlescriptCurrInstr += 7; - } -} - -static void atk1F_jumpifsideaffecting(void) -{ - u8 side; - u16 flags; - const u8* jumpPtr; - - if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER) - side = GET_BANK_SIDE(gBankAttacker); - else - side = GET_BANK_SIDE(gBankTarget); - - flags = BS2ScriptRead16(gBattlescriptCurrInstr + 2); - jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 4); - - if (gSideAffecting[side] & flags) - gBattlescriptCurrInstr = jumpPtr; - else - gBattlescriptCurrInstr += 8; -} - -static void atk20_jumpifstat(void) -{ - u8 ret = 0; - u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); - u8 value = gBattleMons[bank].statStages[gBattlescriptCurrInstr[3]]; - - switch (gBattlescriptCurrInstr[2]) - { - case CMP_EQUAL: - if (value == gBattlescriptCurrInstr[4]) - ret++; - break; - case CMP_NOT_EQUAL: - if (value != gBattlescriptCurrInstr[4]) - ret++; - break; - case CMP_GREATER_THAN: - if (value > gBattlescriptCurrInstr[4]) - ret++; - break; - case CMP_LESS_THAN: - if (value < gBattlescriptCurrInstr[4]) - ret++; - break; - case CMP_COMMON_BITS: - if (value & gBattlescriptCurrInstr[4]) - ret++; - break; - case CMP_NO_COMMON_BITS: - if (!(value & gBattlescriptCurrInstr[4])) - ret++; - break; - } - - if (ret) - gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); - else - gBattlescriptCurrInstr += 9; -} - -static void atk21_jumpifstatus3(void) -{ - u32 flags; - const u8* jumpPtr; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); - jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7); - - if (gBattlescriptCurrInstr[6]) - { - if ((gStatuses3[gActiveBank] & flags) != 0) - gBattlescriptCurrInstr += 11; - else - gBattlescriptCurrInstr = jumpPtr; - } - else - { - if ((gStatuses3[gActiveBank] & flags) != 0) - gBattlescriptCurrInstr = jumpPtr; - else - gBattlescriptCurrInstr += 11; - } -} - -static void atk22_jumpiftype(void) -{ - u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); - u8 type = gBattlescriptCurrInstr[2]; - const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); - - if (gBattleMons[bank].type1 == type || gBattleMons[bank].type2 == type) - gBattlescriptCurrInstr = jumpPtr; - else - gBattlescriptCurrInstr += 7; -} - -static void atk23_getexp(void) -{ - u16 item; - s32 i; // also used as stringId - u8 holdEffect; - s32 sentIn; - - s32 viaExpShare = 0; - u16* exp = &gBattleStruct->expValue; - - gBank1 = GetBattleBank(gBattlescriptCurrInstr[1]); - sentIn = gSentPokesToOpponent[(gBank1 & 2) >> 1]; - - switch (gBattleScripting.atk23_state) - { - case 0: // check if should receive exp at all - if (GetBankSide(gBank1) != SIDE_OPPONENT || (gBattleTypeFlags & - (BATTLE_TYPE_LINK - | BATTLE_TYPE_x2000000 - | BATTLE_TYPE_x4000000 - | BATTLE_TYPE_FRONTIER - | BATTLE_TYPE_SAFARI - | BATTLE_TYPE_BATTLE_TOWER - | BATTLE_TYPE_EREADER_TRAINER))) - { - gBattleScripting.atk23_state = 6; // goto last case - } - else - { - gBattleScripting.atk23_state++; - gBattleStruct->field_DF |= gBitTable[gBattlePartyID[gBank1]]; - } - break; - case 1: // calculate experience points to redistribute - { - u16 calculatedExp; - s32 viaSentIn; - - for (viaSentIn = 0, i = 0; i < 6; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == SPECIES_NONE || GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0) - continue; - if (gBitTable[i] & sentIn) - viaSentIn++; - - item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); - - if (item == ITEM_ENIGMA_BERRY) - holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; - else - holdEffect = ItemId_GetHoldEffect(item); - - if (holdEffect == HOLD_EFFECT_EXP_SHARE) - viaExpShare++; - } - - calculatedExp = gBaseStats[gBattleMons[gBank1].species].expYield * gBattleMons[gBank1].level / 7; - - if (viaExpShare) // at least one mon is getting exp via exp share - { - *exp = calculatedExp / 2 / viaSentIn; - if (*exp == 0) - *exp = 1; - - gExpShareExp = calculatedExp / 2 / viaExpShare; - if (gExpShareExp == 0) - gExpShareExp = 1; - } - else - { - *exp = calculatedExp / viaSentIn; - if (*exp == 0) - *exp = 1; - gExpShareExp = 0; - } - - gBattleScripting.atk23_state++; - gBattleStruct->expGetterId = 0; - gBattleStruct->sentInPokes = sentIn; - } - // fall through - case 2: // set exp value to the poke in expgetter_id and print message - if (gBattleExecBuffer == 0) - { - item = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HELD_ITEM); - - if (item == ITEM_ENIGMA_BERRY) - holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; - else - holdEffect = ItemId_GetHoldEffect(item); - - if (holdEffect != HOLD_EFFECT_EXP_SHARE && !(gBattleStruct->sentInPokes & 1)) - { - *(&gBattleStruct->sentInPokes) >>= 1; - gBattleScripting.atk23_state = 5; - gBattleMoveDamage = 0; // used for exp - } - else if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL) == MAX_MON_LEVEL) - { - *(&gBattleStruct->sentInPokes) >>= 1; - gBattleScripting.atk23_state = 5; - gBattleMoveDamage = 0; // used for exp - } - else - { - // music change in wild battle after fainting a poke - if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) && gBattleMons[0].hp && !gBattleStruct->wildVictorySong) - { - BattleMusicStop(); - PlayBGM(0x161); - gBattleStruct->wildVictorySong++; - } - - if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP)) - { - if (gBattleStruct->sentInPokes & 1) - gBattleMoveDamage = *exp; - else - gBattleMoveDamage = 0; - - if (holdEffect == HOLD_EFFECT_EXP_SHARE) - gBattleMoveDamage += gExpShareExp; - if (holdEffect == HOLD_EFFECT_LUCKY_EGG) - gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; - - if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterId])) - { - // check if the pokemon doesn't belong to the player - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gBattleStruct->expGetterId >= 3) - { - i = 0x149; - } - else - { - gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; - i = 0x14A; - } - } - else - { - i = 0x149; - } - - // get exp getter bank - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - if (!(gBattlePartyID[2] != gBattleStruct->expGetterId) && !(gAbsentBankFlags & gBitTable[2])) - gBattleStruct->expGetterBank = 2; - else - { - if (!(gAbsentBankFlags & gBitTable[0])) - gBattleStruct->expGetterBank = 0; - else - gBattleStruct->expGetterBank = 2; - } - } - else - gBattleStruct->expGetterBank = 0; - - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBank, gBattleStruct->expGetterId) - - // buffer 'gained' or 'gained a boosted' - PREPARE_STRING_BUFFER(gBattleTextBuff2, i) - - PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 5, gBattleMoveDamage) - - PrepareStringBattle(0xD, gBattleStruct->expGetterBank); - MonGainEVs(&gPlayerParty[gBattleStruct->expGetterId], gBattleMons[gBank1].species); - } - gBattleStruct->sentInPokes >>= 1; - gBattleScripting.atk23_state++; - } - } - break; - case 3: // Set stats and give exp - if (gBattleExecBuffer == 0) - { - gBattleBufferB[gBattleStruct->expGetterBank][0] = 0; - if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP) && GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL) != MAX_MON_LEVEL) - { - BATTLE_LVLUP_STATS->hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); - BATTLE_LVLUP_STATS->atk = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); - BATTLE_LVLUP_STATS->def = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); - BATTLE_LVLUP_STATS->spd = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); - BATTLE_LVLUP_STATS->spAtk = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); - BATTLE_LVLUP_STATS->spDef = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPDEF); - - gActiveBank = gBattleStruct->expGetterBank; - EmitExpUpdate(0, gBattleStruct->expGetterId, gBattleMoveDamage); - MarkBufferBankForExecution(gActiveBank); - } - gBattleScripting.atk23_state++; - } - break; - case 4: // lvl up if necessary - if (gBattleExecBuffer == 0) - { - gActiveBank = gBattleStruct->expGetterBank; - if (gBattleBufferB[gActiveBank][0] == 0x21 && gBattleBufferB[gActiveBank][1] == 0xB) - { - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId) - sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); - - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBank, gBattleStruct->expGetterId) - - PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 3, GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL)) - - BattleScriptPushCursor(); - gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterId]; - gBattlescriptCurrInstr = BattleScript_LevelUp; - gBattleMoveDamage = (gBattleBufferB[gActiveBank][2] | (gBattleBufferB[gActiveBank][3] << 8)); - AdjustFriendship(&gPlayerParty[gBattleStruct->expGetterId], 0); - - // update battle mon structure after level up - if (gBattlePartyID[0] == gBattleStruct->expGetterId && gBattleMons[0].hp) - { - gBattleMons[0].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); - gBattleMons[0].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP); - gBattleMons[0].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); - gBattleMons[0].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); - gBattleMons[0].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); - // Why is this duplicated? - gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); - gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); - - gBattleMons[0].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); - gBattleMons[0].spDefense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPDEF); - } - // What is else if? - if (gBattlePartyID[2] == gBattleStruct->expGetterId && gBattleMons[2].hp && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - gBattleMons[2].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); - gBattleMons[2].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP); - gBattleMons[2].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); - gBattleMons[2].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); - gBattleMons[2].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); - // Duplicated again, but this time there's no Sp Defense - gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); - gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); - - gBattleMons[2].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); - } - gBattleScripting.atk23_state = 5; - } - else - { - gBattleMoveDamage = 0; - gBattleScripting.atk23_state = 5; - } - } - break; - case 5: // looper increment - if (gBattleMoveDamage) // there is exp to give, goto case 3 that gives exp - gBattleScripting.atk23_state = 3; - else - { - gBattleStruct->expGetterId++; - if (gBattleStruct->expGetterId <= 5) - gBattleScripting.atk23_state = 2; // loop again - else - gBattleScripting.atk23_state = 6; // we're done - } - break; - case 6: // increment instruction - if (gBattleExecBuffer == 0) - { - // not sure why gf clears the item and ability here - gBattleMons[gBank1].item = 0; - gBattleMons[gBank1].ability = 0; - gBattlescriptCurrInstr += 2; - } - break; - } -} - -#ifdef NONMATCHING -static void atk24(void) -{ - u16 HP_count = 0; - s32 i; - - if (gBattleExecBuffer) - return; - - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId == STEVEN_PARTNER_ID) - { - for (i = 0; i < 3; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) - HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); - } - } - else - { - for (i = 0; i < 6; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) - && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->field_2A0 & gBitTable[i]))) - { - HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); - } - } - } - - if (HP_count == 0) - gBattleOutcome |= BATTLE_LOST; - - for (HP_count = 0, i = 0; i < 6; i++) - { - if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES) && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG) - && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->field_2A1 & gBitTable[i]))) - { - HP_count += GetMonData(&gEnemyParty[i], MON_DATA_HP); - } - } - - if (HP_count == 0) - gBattleOutcome |= BATTLE_WON; - - if (gBattleOutcome == 0 && (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))) - { - s32 foundPlayer; - s32 foundOpponent; - - // Impossible to decompile loops. - for (foundPlayer = 0, i = 0; i < gNoOfAllBanks; i += 2) - { - if (HITMARKER_UNK(i) & gHitMarker && !gSpecialStatuses[i].flag40) - foundPlayer++; - } - - for (foundOpponent = 0, i = 1; i < gNoOfAllBanks; i += 2) - { - if (HITMARKER_UNK(i) & gHitMarker && !gSpecialStatuses[i].flag40) - foundOpponent++; - } - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (foundOpponent + foundPlayer > 1) - gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; - } - else - { - if (foundOpponent != 0 && foundPlayer != 0) - gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; - } - } - else - { - gBattlescriptCurrInstr += 5; - } -} -#else -__attribute__((naked)) -static void atk24(void) -{ - asm("\n\ - .syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r8\n\ - push {r7}\n\ - movs r6, 0\n\ - ldr r0, =gBattleExecBuffer\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - beq _0804ACE2\n\ - b _0804AF22\n\ - _0804ACE2:\n\ - ldr r0, =gBattleTypeFlags\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 15\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0804AD48\n\ - ldr r0, =gPartnerTrainerId\n\ - ldrh r1, [r0]\n\ - ldr r0, =0x00000c03\n\ - cmp r1, r0\n\ - bne _0804AD48\n\ - movs r5, 0\n\ - _0804ACFC:\n\ - movs r0, 0x64\n\ - adds r1, r5, 0\n\ - muls r1, r0\n\ - ldr r0, =gPlayerParty\n\ - adds r4, r1, r0\n\ - adds r0, r4, 0\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _0804AD2C\n\ - adds r0, r4, 0\n\ - movs r1, 0x2D\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - bne _0804AD2C\n\ - adds r0, r4, 0\n\ - movs r1, 0x39\n\ - bl GetMonData\n\ - adds r0, r6, r0\n\ - lsls r0, 16\n\ - lsrs r6, r0, 16\n\ - _0804AD2C:\n\ - adds r5, 0x1\n\ - cmp r5, 0x2\n\ - ble _0804ACFC\n\ - b _0804ADA8\n\ - .pool\n\ - _0804AD48:\n\ - movs r5, 0\n\ - _0804AD4A:\n\ - movs r0, 0x64\n\ - adds r1, r5, 0\n\ - muls r1, r0\n\ - ldr r0, =gPlayerParty\n\ - adds r4, r1, r0\n\ - adds r0, r4, 0\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _0804ADA2\n\ - adds r0, r4, 0\n\ - movs r1, 0x2D\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - bne _0804ADA2\n\ - ldr r0, =gBattleTypeFlags\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 11\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0804AD94\n\ - ldr r0, =gBattleStruct\n\ - ldr r0, [r0]\n\ - movs r1, 0xA8\n\ - lsls r1, 2\n\ - adds r0, r1\n\ - ldrb r1, [r0]\n\ - ldr r2, =gBitTable\n\ - lsls r0, r5, 2\n\ - adds r0, r2\n\ - ldr r0, [r0]\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - bne _0804ADA2\n\ - _0804AD94:\n\ - adds r0, r4, 0\n\ - movs r1, 0x39\n\ - bl GetMonData\n\ - adds r0, r6, r0\n\ - lsls r0, 16\n\ - lsrs r6, r0, 16\n\ - _0804ADA2:\n\ - adds r5, 0x1\n\ - cmp r5, 0x5\n\ - ble _0804AD4A\n\ - _0804ADA8:\n\ - cmp r6, 0\n\ - bne _0804ADB6\n\ - ldr r0, =gBattleOutcome\n\ - ldrb r1, [r0]\n\ - movs r2, 0x2\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ - _0804ADB6:\n\ - movs r6, 0\n\ - movs r5, 0\n\ - _0804ADBA:\n\ - movs r0, 0x64\n\ - adds r1, r5, 0\n\ - muls r1, r0\n\ - ldr r0, =gEnemyParty\n\ - adds r4, r1, r0\n\ - adds r0, r4, 0\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _0804AE10\n\ - adds r0, r4, 0\n\ - movs r1, 0x2D\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - bne _0804AE10\n\ - ldr r0, =gBattleTypeFlags\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 11\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0804AE02\n\ - ldr r0, =gBattleStruct\n\ - ldr r0, [r0]\n\ - ldr r1, =0x000002a1\n\ - adds r0, r1\n\ - ldrb r1, [r0]\n\ - ldr r2, =gBitTable\n\ - lsls r0, r5, 2\n\ - adds r0, r2\n\ - ldr r0, [r0]\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - bne _0804AE10\n\ - _0804AE02:\n\ - adds r0, r4, 0\n\ - movs r1, 0x39\n\ - bl GetMonData\n\ - adds r0, r6, r0\n\ - lsls r0, 16\n\ - lsrs r6, r0, 16\n\ - _0804AE10:\n\ - adds r5, 0x1\n\ - cmp r5, 0x5\n\ - ble _0804ADBA\n\ - ldr r2, =gBattleOutcome\n\ - cmp r6, 0\n\ - bne _0804AE24\n\ - ldrb r0, [r2]\n\ - movs r1, 0x1\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - _0804AE24:\n\ - ldrb r0, [r2]\n\ - cmp r0, 0\n\ - bne _0804AF1A\n\ - ldr r0, =gBattleTypeFlags\n\ - ldr r1, [r0]\n\ - ldr r2, =0x02000002\n\ - ands r1, r2\n\ - mov r8, r0\n\ - cmp r1, 0\n\ - beq _0804AF1A\n\ - movs r3, 0\n\ - movs r5, 0\n\ - ldr r0, =gNoOfAllBanks\n\ - ldrb r1, [r0]\n\ - mov r12, r0\n\ - ldr r7, =gBattlescriptCurrInstr\n\ - cmp r3, r1\n\ - bge _0804AE70\n\ - ldr r0, =gHitMarker\n\ - movs r6, 0x80\n\ - lsls r6, 21\n\ - ldr r4, [r0]\n\ - adds r2, r1, 0\n\ - ldr r1, =gSpecialStatuses\n\ - _0804AE54:\n\ - adds r0, r6, 0\n\ - lsls r0, r5\n\ - ands r0, r4\n\ - cmp r0, 0\n\ - beq _0804AE68\n\ - ldrb r0, [r1]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _0804AE68\n\ - adds r3, 0x1\n\ - _0804AE68:\n\ - adds r1, 0x28\n\ - adds r5, 0x2\n\ - cmp r5, r2\n\ - blt _0804AE54\n\ - _0804AE70:\n\ - movs r2, 0\n\ - movs r5, 0x1\n\ - mov r4, r12\n\ - ldrb r1, [r4]\n\ - cmp r5, r1\n\ - bge _0804AEAA\n\ - ldr r0, =gHitMarker\n\ - movs r4, 0x80\n\ - lsls r4, 21\n\ - mov r12, r4\n\ - ldr r6, [r0]\n\ - ldr r0, =gSpecialStatuses\n\ - adds r4, r1, 0\n\ - adds r1, r0, 0\n\ - adds r1, 0x14\n\ - _0804AE8E:\n\ - mov r0, r12\n\ - lsls r0, r5\n\ - ands r0, r6\n\ - cmp r0, 0\n\ - beq _0804AEA2\n\ - ldrb r0, [r1]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _0804AEA2\n\ - adds r2, 0x1\n\ - _0804AEA2:\n\ - adds r1, 0x28\n\ - adds r5, 0x2\n\ - cmp r5, r4\n\ - blt _0804AE8E\n\ - _0804AEAA:\n\ - mov r1, r8\n\ - ldr r0, [r1]\n\ - movs r1, 0x40\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0804AEF0\n\ - adds r0, r2, r3\n\ - cmp r0, 0x1\n\ - bgt _0804AEF8\n\ - b _0804AF12\n\ - .pool\n\ - _0804AEF0:\n\ - cmp r2, 0\n\ - beq _0804AF12\n\ - cmp r3, 0\n\ - beq _0804AF12\n\ - _0804AEF8:\n\ - ldr r2, [r7]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - adds r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - adds r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - lsls r0, 24\n\ - adds r1, r0\n\ - str r1, [r7]\n\ - b _0804AF22\n\ - _0804AF12:\n\ - ldr r0, [r7]\n\ - adds r0, 0x5\n\ - str r0, [r7]\n\ - b _0804AF22\n\ - _0804AF1A:\n\ - ldr r1, =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x5\n\ - str r0, [r1]\n\ - _0804AF22:\n\ - pop {r3}\n\ - mov r8, r3\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .pool\n\ - .syntax divided"); -} - -#endif // NONMATCHING - -static void MoveValuesCleanUp(void) -{ - gBattleMoveFlags = 0; - gBattleScripting.dmgMultiplier = 1; - gCritMultiplier = 1; - gBattleCommunication[MOVE_EFFECT_BYTE] = 0; - gBattleCommunication[6] = 0; - gHitMarker &= ~(HITMARKER_DESTINYBOND); - gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); -} - -static void atk25_move_values_cleanup(void) -{ - MoveValuesCleanUp(); - gBattlescriptCurrInstr += 1; -} - -static void atk26_set_multihit(void) -{ - gMultiHitCounter = gBattlescriptCurrInstr[1]; - gBattlescriptCurrInstr += 2; -} - -static void atk27_decrement_multihit(void) -{ - if (--gMultiHitCounter == 0) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); -} - -static void atk28_goto(void) -{ - gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); -} - -static void atk29_jumpifbyte(void) -{ - u8 caseID = gBattlescriptCurrInstr[1]; - const u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); - u8 value = gBattlescriptCurrInstr[6]; - const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7); - - gBattlescriptCurrInstr += 11; - - switch (caseID) - { - case CMP_EQUAL: - if (*memByte == value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_NOT_EQUAL: - if (*memByte != value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_GREATER_THAN: - if (*memByte > value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_LESS_THAN: - if (*memByte < value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_COMMON_BITS: - if (*memByte & value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_NO_COMMON_BITS: - if (!(*memByte & value)) - gBattlescriptCurrInstr = jumpPtr; - break; - } -} - -static void atk2A_jumpifhalfword(void) -{ - u8 caseID = gBattlescriptCurrInstr[1]; - const u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); - u16 value = BS2ScriptRead16(gBattlescriptCurrInstr + 6); - const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 8); - - gBattlescriptCurrInstr += 12; - - switch (caseID) - { - case CMP_EQUAL: - if (*memHword == value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_NOT_EQUAL: - if (*memHword != value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_GREATER_THAN: - if (*memHword > value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_LESS_THAN: - if (*memHword < value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_COMMON_BITS: - if (*memHword & value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_NO_COMMON_BITS: - if (!(*memHword & value)) - gBattlescriptCurrInstr = jumpPtr; - break; - } -} - -static void atk2B_jumpifword(void) -{ - u8 caseID = gBattlescriptCurrInstr[1]; - const u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); - u32 value = BSScriptRead32(gBattlescriptCurrInstr + 6); - const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); - - gBattlescriptCurrInstr += 14; - - switch (caseID) - { - case CMP_EQUAL: - if (*memWord == value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_NOT_EQUAL: - if (*memWord != value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_GREATER_THAN: - if (*memWord > value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_LESS_THAN: - if (*memWord < value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_COMMON_BITS: - if (*memWord & value) - gBattlescriptCurrInstr = jumpPtr; - break; - case CMP_NO_COMMON_BITS: - if (!(*memWord & value)) - gBattlescriptCurrInstr = jumpPtr; - break; - } -} - -static void atk2C_jumpifarrayequal(void) -{ - const u8* mem1 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - const u8* mem2 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); - u32 size = gBattlescriptCurrInstr[9]; - const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); - - u8 i; - for (i = 0; i < size; i++) - { - if (*mem1 != *mem2) - { - gBattlescriptCurrInstr += 14; - break; - } - mem1++, mem2++; - } - - if (i == size) - gBattlescriptCurrInstr = jumpPtr; -} - -static void atk2D_jumpifarraynotequal(void) -{ - u8 equalBytes = 0; - const u8* mem1 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - const u8* mem2 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); - u32 size = gBattlescriptCurrInstr[9]; - const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); - - u8 i; - for (i = 0; i < size; i++) - { - if (*mem1 == *mem2) - { - equalBytes++; - } - mem1++, mem2++; - } - - if (equalBytes != size) - gBattlescriptCurrInstr = jumpPtr; - else - gBattlescriptCurrInstr += 14; -} - -static void atk2E_setbyte(void) -{ - u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - *memByte = gBattlescriptCurrInstr[5]; - - gBattlescriptCurrInstr += 6; -} - -static void atk2F_addbyte(void) -{ - u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - *memByte += gBattlescriptCurrInstr[5]; - gBattlescriptCurrInstr += 6; -} - -static void atk30_subbyte(void) -{ - u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - *memByte -= gBattlescriptCurrInstr[5]; - gBattlescriptCurrInstr += 6; -} - -static void atk31_copyarray(void) -{ - u8* dest = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - const u8* src = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); - s32 size = gBattlescriptCurrInstr[9]; - - s32 i; - for (i = 0; i < size; i++) - { - dest[i] = src[i]; - } - - gBattlescriptCurrInstr += 10; -} - -static void atk32_copyarray_withindex(void) -{ - u8* dest = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - const u8* src = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); - const u8* index = BS2ScriptReadPtr(gBattlescriptCurrInstr + 9); - s32 size = gBattlescriptCurrInstr[13]; - - s32 i; - for (i = 0; i < size; i++) - { - dest[i] = src[i + *index]; - } - - gBattlescriptCurrInstr += 14; -} - -static void atk33_orbyte(void) -{ - u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - *memByte |= gBattlescriptCurrInstr[5]; - gBattlescriptCurrInstr += 6; -} - -static void atk34_orhalfword(void) -{ - u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - u16 val = BS2ScriptRead16(gBattlescriptCurrInstr + 5); - - *memHword |= val; - gBattlescriptCurrInstr += 7; -} - -static void atk35_orword(void) -{ - u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - u32 val = BS2ScriptRead32(gBattlescriptCurrInstr + 5); - - *memWord |= val; - gBattlescriptCurrInstr += 9; -} - -static void atk36_bicbyte(void) -{ - u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - *memByte &= ~(gBattlescriptCurrInstr[5]); - gBattlescriptCurrInstr += 6; -} - -static void atk37_bichalfword(void) -{ - u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - u16 val = BS2ScriptRead16(gBattlescriptCurrInstr + 5); - - *memHword &= ~val; - gBattlescriptCurrInstr += 7; -} - -static void atk38_bicword(void) -{ - u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); - u32 val = BS2ScriptRead32(gBattlescriptCurrInstr + 5); - - *memWord &= ~val; - gBattlescriptCurrInstr += 9; -} - -static void atk39_pause(void) -{ - if (gBattleExecBuffer == 0) - { - u16 value = BS2ScriptRead16(gBattlescriptCurrInstr + 1); - if (++gPauseCounterBattle >= value) - { - gPauseCounterBattle = 0; - gBattlescriptCurrInstr += 3; - } - } -} - -static void atk3A_waitstate(void) -{ - if (gBattleExecBuffer == 0) - gBattlescriptCurrInstr++; -} - -static void atk3B_healthbar_update(void) -{ - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) - gActiveBank = gBankTarget; - else - gActiveBank = gBankAttacker; - - EmitHealthBarUpdate(0, gBattleMoveDamage); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 2; -} - -static void atk3C_return(void) -{ - BattleScriptPop(); -} - -static void atk3D_end(void) -{ - if (gBattleTypeFlags & BATTLE_TYPE_ARENA) - sub_81A5718(gBankAttacker); - - gBattleMoveFlags = 0; - gActiveBank = 0; - gFightStateTracker = 0xB; -} - -static void atk3E_end2(void) -{ - gActiveBank = 0; - gFightStateTracker = 0xB; -} - -static void atk3F_end3(void) // pops the main function stack -{ - BattleScriptPop(); - if (BATTLE_CALLBACKS_STACK->size) - BATTLE_CALLBACKS_STACK->size--; - gBattleMainFunc = BATTLE_CALLBACKS_STACK->function[BATTLE_CALLBACKS_STACK->size]; -} - -static void atk41_call(void) -{ - BattleScriptPush(gBattlescriptCurrInstr + 5); - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); -} - -static void atk42_jumpiftype2(void) -{ - u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); - - if (gBattlescriptCurrInstr[2] == gBattleMons[bank].type1 || gBattlescriptCurrInstr[2] == gBattleMons[bank].type2) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 3); - else - gBattlescriptCurrInstr += 7; -} - -static void atk43_jumpifabilitypresent(void) -{ - if (AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, gBattlescriptCurrInstr[1], 0, 0)) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; -} - -static void atk44(void) -{ - *(gBankAttacker + gBattleStruct->field_54) = 1; -} - -static void atk45_playanimation(void) -{ - const u16* argumentPtr; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); - - if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE - || gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE - || gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE) - { - EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 7; - } - else if (gHitMarker & HITMARKER_NO_ANIMATIONS) - { - BattleScriptPush(gBattlescriptCurrInstr + 7); - gBattlescriptCurrInstr = BattleScript_Pausex20; - } - else if (gBattlescriptCurrInstr[2] == B_ANIM_RAIN_CONTINUES - || gBattlescriptCurrInstr[2] == B_ANIM_SUN_CONTINUES - || gBattlescriptCurrInstr[2] == B_ANIM_SANDSTORM_CONTINUES - || gBattlescriptCurrInstr[2] == B_ANIM_HAIL_CONTINUES) - { - EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 7; - } - else if (gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) - { - gBattlescriptCurrInstr += 7; - } - else - { - EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 7; - } -} - -static void atk46_playanimation2(void) // animation Id is stored in the first pointer -{ - const u16* argumentPtr; - const u8* animationIdPtr; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - animationIdPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); - argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); - - if (*animationIdPtr == B_ANIM_STATS_CHANGE - || *animationIdPtr == B_ANIM_SNATCH_MOVE - || *animationIdPtr == B_ANIM_SUBSTITUTE_FADE) - { - EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 10; - } - else if (gHitMarker & HITMARKER_NO_ANIMATIONS) - { - gBattlescriptCurrInstr += 10; - } - else if (*animationIdPtr == B_ANIM_RAIN_CONTINUES - || *animationIdPtr == B_ANIM_SUN_CONTINUES - || *animationIdPtr == B_ANIM_SANDSTORM_CONTINUES - || *animationIdPtr == B_ANIM_HAIL_CONTINUES) - { - EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 10; - } - else if (gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) - { - gBattlescriptCurrInstr += 10; - } - else - { - EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 10; - } -} - -static void atk47_setgraphicalstatchangevalues(void) -{ - u8 value = 0; - switch (gBattleScripting.statChanger & 0xF0) - { - case 0x10: // +1 - value = 0xF; - break; - case 0x20: // +2 - value = 0x27; - break; - case 0x90: // -1 - value = 0x16; - break; - case 0xA0: // -2 - value = 0x2E; - break; - } - gBattleScripting.animArg1 = (gBattleScripting.statChanger & 0xF) + value - 1; - gBattleScripting.animArg2 = 0; - gBattlescriptCurrInstr++; -} - -#ifdef NONMATCHING -static void atk48_playstatchangeanimation(void) -{ - u32 currStat = 0; - s16 statAnimId = 0; - s16 checkingStatAnimId = 0; - s32 changeableStats = 0; - u32 statsToCheck = 0; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - statsToCheck = gBattlescriptCurrInstr[2]; - - if (gBattlescriptCurrInstr[3] & ATK48_STAT_NEGATIVE) // goes down - { - checkingStatAnimId = (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) ? 0x2D : 0x15; - while (statsToCheck != 0) - { - if (statsToCheck & 1) - { - if (!(gBattlescriptCurrInstr[3] & ATK48_LOWER_FAIL_CHECK)) - { - if (gBattleMons[gActiveBank].statStages[currStat] > 0) - { - statAnimId = checkingStatAnimId; - changeableStats++; - } - } - else if (!gSideTimers[GET_BANK_SIDE(gActiveBank)].mistTimer - && gBattleMons[gActiveBank].ability != ABILITY_CLEAR_BODY - && gBattleMons[gActiveBank].ability != ABILITY_WHITE_SMOKE - && !(gBattleMons[gActiveBank].ability == ABILITY_KEEN_EYE && currStat == STAT_STAGE_ACC) - && !(gBattleMons[gActiveBank].ability == ABILITY_HYPER_CUTTER && currStat == STAT_STAGE_ATK)) - { - if (gBattleMons[gActiveBank].statStages[currStat] > 0) - { - statAnimId = checkingStatAnimId; - changeableStats++; - } - } - } - statsToCheck >>= 1, checkingStatAnimId++, currStat++; - } - - if (changeableStats > 1) // more than one stat, so the color is gray - { - if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) - statAnimId = 0x3A; - else - statAnimId = 0x39; - } - } - else // goes up - { - checkingStatAnimId = (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) ? 0x26 : 0xE; - while (statsToCheck != 0) - { - if (statsToCheck & 1 && gBattleMons[gActiveBank].statStages[currStat] < 0xC) - { - statAnimId = checkingStatAnimId; - changeableStats++; - } - statsToCheck >>= 1, checkingStatAnimId += 1, currStat++; - } - - if (changeableStats > 1) // more than one stat, so the color is gray - { - if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) - statAnimId = 0x38; - else - statAnimId = 0x37; - } - } - - if (gBattlescriptCurrInstr[3] & ATK48_BIT_x4 && changeableStats < 2) - { - gBattlescriptCurrInstr += 4; - } - else if (changeableStats != 0 && gBattleScripting.field_1B == 0) - { - EmitBattleAnimation(0, B_ANIM_STATS_CHANGE, statAnimId); - MarkBufferBankForExecution(gActiveBank); - if (gBattlescriptCurrInstr[3] & ATK48_BIT_x4 && changeableStats > 1) - gBattleScripting.field_1B = 1; - gBattlescriptCurrInstr += 4; - } - else - { - gBattlescriptCurrInstr += 4; - } -} -#else -__attribute__((naked)) -static void atk48_playstatchangeanimation(void) -{ - asm("\n\ - .syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x4\n\ - movs r7, 0\n\ - movs r0, 0\n\ - mov r8, r0\n\ - movs r3, 0\n\ - ldr r5, =gBattlescriptCurrInstr\n\ - ldr r0, [r5]\n\ - ldrb r0, [r0, 0x1]\n\ - str r3, [sp]\n\ - bl GetBattleBank\n\ - ldr r2, =gActiveBank\n\ - strb r0, [r2]\n\ - ldr r0, [r5]\n\ - ldrb r4, [r0, 0x2]\n\ - ldrb r1, [r0, 0x3]\n\ - movs r0, 0x1\n\ - ands r0, r1\n\ - ldr r3, [sp]\n\ - cmp r0, 0\n\ - beq _0804BAEC\n\ - movs r0, 0x2\n\ - ands r0, r1\n\ - movs r1, 0x15\n\ - cmp r0, 0\n\ - beq _0804BA18\n\ - movs r1, 0x2D\n\ -_0804BA18:\n\ - cmp r4, 0\n\ - beq _0804BAC0\n\ - movs r0, 0x1\n\ - mov r10, r0\n\ - ldr r0, =gBattleMons + 0x18\n\ - mov r9, r0\n\ - lsls r5, r1, 16\n\ -_0804BA26:\n\ - adds r0, r4, 0\n\ - mov r1, r10\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0804BAB2\n\ - ldr r0, =gBattlescriptCurrInstr\n\ - ldr r0, [r0]\n\ - ldrb r1, [r0, 0x3]\n\ - movs r0, 0x8\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0804BA58\n\ - ldr r0, =gActiveBank\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r7, r0\n\ - b _0804BAA0\n\ - .pool\n\ -_0804BA58:\n\ - ldr r6, =gActiveBank\n\ - ldrb r0, [r6]\n\ - str r3, [sp]\n\ - bl GetBankIdentity\n\ - mov r1, r10\n\ - ands r1, r0\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - ldr r1, =gSideTimers\n\ - adds r0, r1\n\ - ldrb r0, [r0, 0x4]\n\ - ldr r3, [sp]\n\ - cmp r0, 0\n\ - bne _0804BAB2\n\ - ldr r0, =gBattleMons\n\ - ldrb r2, [r6]\n\ - movs r1, 0x58\n\ - muls r2, r1\n\ - adds r0, r2, r0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x1D\n\ - beq _0804BAB2\n\ - cmp r0, 0x49\n\ - beq _0804BAB2\n\ - cmp r0, 0x33\n\ - bne _0804BA96\n\ - cmp r7, 0x6\n\ - beq _0804BAB2\n\ -_0804BA96:\n\ - cmp r0, 0x34\n\ - bne _0804BA9E\n\ - cmp r7, 0x1\n\ - beq _0804BAB2\n\ -_0804BA9E:\n\ - adds r0, r7, r2\n\ -_0804BAA0:\n\ - add r0, r9\n\ - ldrb r0, [r0]\n\ - lsls r0, 24\n\ - asrs r0, 24\n\ - cmp r0, 0\n\ - ble _0804BAB2\n\ - lsrs r0, r5, 16\n\ - mov r8, r0\n\ - adds r3, 0x1\n\ -_0804BAB2:\n\ - lsrs r4, 1\n\ - movs r1, 0x80\n\ - lsls r1, 9\n\ - adds r5, r1\n\ - adds r7, 0x1\n\ - cmp r4, 0\n\ - bne _0804BA26\n\ -_0804BAC0:\n\ - ldr r0, =gBattlescriptCurrInstr\n\ - mov r9, r0\n\ - cmp r3, 0x1\n\ - ble _0804BB4E\n\ - ldr r0, [r0]\n\ - ldrb r1, [r0, 0x3]\n\ - movs r0, 0x2\n\ - ands r0, r1\n\ - movs r1, 0x39\n\ - mov r8, r1\n\ - cmp r0, 0\n\ - beq _0804BB4E\n\ - movs r0, 0x3A\n\ - b _0804BB4C\n\ - .pool\n\ -_0804BAEC:\n\ - movs r0, 0x2\n\ - ands r0, r1\n\ - movs r1, 0xE\n\ - cmp r0, 0\n\ - beq _0804BAF8\n\ - movs r1, 0x26\n\ -_0804BAF8:\n\ - mov r9, r5\n\ - cmp r4, 0\n\ - beq _0804BB34\n\ - ldr r6, =gBattleMons + 0x18\n\ - adds r5, r2, 0\n\ - lsls r2, r1, 16\n\ -_0804BB04:\n\ - movs r0, 0x1\n\ - ands r0, r4\n\ - cmp r0, 0\n\ - beq _0804BB26\n\ - ldrb r1, [r5]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r7, r0\n\ - adds r0, r6\n\ - ldrb r0, [r0]\n\ - lsls r0, 24\n\ - asrs r0, 24\n\ - cmp r0, 0xB\n\ - bgt _0804BB26\n\ - lsrs r1, r2, 16\n\ - mov r8, r1\n\ - adds r3, 0x1\n\ -_0804BB26:\n\ - lsrs r4, 1\n\ - movs r0, 0x80\n\ - lsls r0, 9\n\ - adds r2, r0\n\ - adds r7, 0x1\n\ - cmp r4, 0\n\ - bne _0804BB04\n\ -_0804BB34:\n\ - cmp r3, 0x1\n\ - ble _0804BB4E\n\ - mov r1, r9\n\ - ldr r0, [r1]\n\ - ldrb r1, [r0, 0x3]\n\ - movs r0, 0x2\n\ - ands r0, r1\n\ - movs r1, 0x37\n\ - mov r8, r1\n\ - cmp r0, 0\n\ - beq _0804BB4E\n\ - movs r0, 0x38\n\ -_0804BB4C:\n\ - mov r8, r0\n\ -_0804BB4E:\n\ - mov r1, r9\n\ - ldr r2, [r1]\n\ - ldrb r1, [r2, 0x3]\n\ - movs r0, 0x4\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0804BB6C\n\ - cmp r3, 0x1\n\ - bgt _0804BB6C\n\ - adds r0, r2, 0x4\n\ - mov r1, r9\n\ - b _0804BBBA\n\ - .pool\n\ -_0804BB6C:\n\ - cmp r3, 0\n\ - beq _0804BBB4\n\ - ldr r4, =gBattleScripting\n\ - ldrb r0, [r4, 0x1B]\n\ - cmp r0, 0\n\ - bne _0804BBB4\n\ - movs r0, 0\n\ - movs r1, 0x1\n\ - mov r2, r8\n\ - str r3, [sp]\n\ - bl EmitBattleAnimation\n\ - ldr r0, =gActiveBank\n\ - ldrb r0, [r0]\n\ - bl MarkBufferBankForExecution\n\ - ldr r0, =gBattlescriptCurrInstr\n\ - ldr r0, [r0]\n\ - ldrb r1, [r0, 0x3]\n\ - movs r0, 0x4\n\ - ands r0, r1\n\ - ldr r3, [sp]\n\ - cmp r0, 0\n\ - beq _0804BBA4\n\ - cmp r3, 0x1\n\ - ble _0804BBA4\n\ - movs r0, 0x1\n\ - strb r0, [r4, 0x1B]\n\ -_0804BBA4:\n\ - ldr r1, =gBattlescriptCurrInstr\n\ - b _0804BBB6\n\ - .pool\n\ -_0804BBB4:\n\ - mov r1, r9\n\ -_0804BBB6:\n\ - ldr r0, [r1]\n\ - adds r0, 0x4\n\ -_0804BBBA:\n\ - str r0, [r1]\n\ - add sp, 0x4\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .syntax divided"); -} -#endif // NONMATCHING - -#define ATK49_LAST_CASE 17 - -static void atk49_moveend(void) -{ - s32 i; - bool32 effect; - u8 moveType; - u8 holdEffectAtk; - u16 *choicedMoveAtk; - u8 arg1, arg2; - u16 lastMove; - - effect = FALSE; - - if (gLastUsedMove == 0xFFFF) - lastMove = 0; - else - lastMove = gLastUsedMove; - - arg1 = gBattlescriptCurrInstr[1]; - arg2 = gBattlescriptCurrInstr[2]; - - if (gBattleMons[gBankAttacker].item == ITEM_ENIGMA_BERRY) - holdEffectAtk = gEnigmaBerries[gBankAttacker].holdEffect; - else - holdEffectAtk = ItemId_GetHoldEffect(gBattleMons[gBankAttacker].item); - - choicedMoveAtk = &gBattleStruct->choicedMove[gBankAttacker]; - - GET_MOVE_TYPE(gCurrentMove, moveType); - - do - { - switch (gBattleScripting.atk49_state) - { - case 0: // rage check - if (gBattleMons[gBankTarget].status2 & STATUS2_RAGE - && gBattleMons[gBankTarget].hp != 0 && gBankAttacker != gBankTarget - && GetBankSide(gBankAttacker) != GetBankSide(gBankTarget) - && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT) && TARGET_TURN_DAMAGED - && gBattleMoves[gCurrentMove].power && gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] <= 0xB) - { - gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK]++; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_RageIsBuilding; - effect = TRUE; - } - gBattleScripting.atk49_state++; - break; - case 1: // defrosting check - if (gBattleMons[gBankTarget].status1 & STATUS_FREEZE - && gBattleMons[gBankTarget].hp != 0 && gBankAttacker != gBankTarget - && gSpecialStatuses[gBankTarget].moveturnLostHP_special - && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT) && moveType == TYPE_FIRE) - { - gBattleMons[gBankTarget].status1 &= ~(STATUS_FREEZE); - gActiveBank = gBankTarget; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); - MarkBufferBankForExecution(gActiveBank); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove; - effect = TRUE; - } - gBattleScripting.atk49_state++; - break; - case 2: // target synchronize - if (AbilityBattleEffects(ABILITYEFFECT_SYNCHRONIZE, gBankTarget, 0, 0, 0)) - effect = TRUE; - gBattleScripting.atk49_state++; - break; - case 3: // contact abilities - if (AbilityBattleEffects(ABILITYEFFECT_CONTACT, gBankTarget, 0, 0, 0)) - effect = TRUE; - gBattleScripting.atk49_state++; - break; - case 4: // status immunities - if (AbilityBattleEffects(ABILITYEFFECT_IMMUNITY, 0, 0, 0, 0)) - effect = TRUE; // it loops through all banks, so we increment after its done with all banks - else - gBattleScripting.atk49_state++; - break; - case 5: // attacker synchronize - if (AbilityBattleEffects(ABILITYEFFECT_ATK_SYNCHRONIZE, gBankAttacker, 0, 0, 0)) - effect = TRUE; - gBattleScripting.atk49_state++; - break; - case 6: // update choice band move - if (!(gHitMarker & HITMARKER_OBEYS) || holdEffectAtk != HOLD_EFFECT_CHOICE_BAND - || gLastUsedMove == MOVE_STRUGGLE || (*choicedMoveAtk != 0 && *choicedMoveAtk != 0xFFFF)) - goto LOOP; - if (gLastUsedMove == MOVE_BATON_PASS && !(gBattleMoveFlags & MOVESTATUS_FAILED)) - { - gBattleScripting.atk49_state++; - break; - } - *choicedMoveAtk = gLastUsedMove; - LOOP: - { - for (i = 0; i < 4; i++) - { - if (gBattleMons[gBankAttacker].moves[i] == *choicedMoveAtk) - break; - } - if (i == 4) - *choicedMoveAtk = 0; - - gBattleScripting.atk49_state++; - } - break; - case 7: // changed held items - for (i = 0; i < gNoOfAllBanks; i++) - { - u16* changedItem = &gBattleStruct->changedItems[i]; - if (*changedItem != 0) - { - gBattleMons[i].item = *changedItem; - *changedItem = 0; - } - } - gBattleScripting.atk49_state++; - break; - case 11: // item effects for all banks - if (ItemBattleEffects(3, 0, FALSE)) - effect = TRUE; - else - gBattleScripting.atk49_state++; - break; - case 12: // king's rock and shell bell - if (ItemBattleEffects(4, 0, FALSE)) - effect = TRUE; - gBattleScripting.atk49_state++; - break; - case 8: // make attacker sprite invisible - if (gStatuses3[gBankAttacker] & (STATUS3_SEMI_INVULNERABLE) - && gHitMarker & HITMARKER_NO_ANIMATIONS) - { - gActiveBank = gBankAttacker; - EmitSpriteInvisibility(0, TRUE); - MarkBufferBankForExecution(gActiveBank); - gBattleScripting.atk49_state++; - return; - } - gBattleScripting.atk49_state++; - break; - case 9: // make attacker sprite visible - if (gBattleMoveFlags & MOVESTATUS_NOEFFECT - || !(gStatuses3[gBankAttacker] & (STATUS3_SEMI_INVULNERABLE)) - || HasMoveFailed(gBankAttacker)) - { - gActiveBank = gBankAttacker; - EmitSpriteInvisibility(0, FALSE); - MarkBufferBankForExecution(gActiveBank); - gStatuses3[gBankAttacker] &= ~(STATUS3_SEMI_INVULNERABLE); - gSpecialStatuses[gBankAttacker].restoredBankSprite = 1; - gBattleScripting.atk49_state++; - return; - } - gBattleScripting.atk49_state++; - break; - case 10: // make target sprite visible - if (!gSpecialStatuses[gBankTarget].restoredBankSprite && gBankTarget < gNoOfAllBanks - && !(gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE)) - { - gActiveBank = gBankTarget; - EmitSpriteInvisibility(0, FALSE); - MarkBufferBankForExecution(gActiveBank); - gStatuses3[gBankTarget] &= ~(STATUS3_SEMI_INVULNERABLE); - gBattleScripting.atk49_state++; - return; - } - gBattleScripting.atk49_state++; - break; - case 13: // update substitute - for (i = 0; i < gNoOfAllBanks; i++) - { - if (gDisableStructs[i].substituteHP == 0) - gBattleMons[i].status2 &= ~(STATUS2_SUBSTITUTE); - } - gBattleScripting.atk49_state++; - break; - case 14: // This case looks interesting, although I am not certain what it does. Probably fine tunes edge cases. - if (gHitMarker & HITMARKER_PURSUIT_TRAP) - { - gActiveBank = gBankAttacker; - gBankAttacker = gBankTarget; - gBankTarget = gActiveBank; - gHitMarker &= ~(HITMARKER_PURSUIT_TRAP); - } - if (gHitMarker & HITMARKER_ATTACKSTRING_PRINTED) - { - gUnknownMovesUsedByBanks[gBankAttacker] = gLastUsedMove; - } - if (!(gAbsentBankFlags & gBitTable[gBankAttacker]) - && !(gBattleStruct->field_91 & gBitTable[gBankAttacker]) - && gBattleMoves[lastMove].effect != EFFECT_BATON_PASS) - { - if (gHitMarker & HITMARKER_OBEYS) - { - gLastUsedMovesByBanks[gBankAttacker] = gLastUsedMove; - gUnknown_02024260[gBankAttacker] = gCurrentMove; - } - else - { - gLastUsedMovesByBanks[gBankAttacker] = 0xFFFF; - gUnknown_02024260[gBankAttacker] = 0xFFFF; - } - - if (!(gHitMarker & HITMARKER_FAINTED(gBankTarget))) - gUnknown_02024270[gBankTarget] = gBankAttacker; - - if (gHitMarker & HITMARKER_OBEYS && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) - { - if (gLastUsedMove == 0xFFFF) - { - gUnknown_02024250[gBankTarget] = gLastUsedMove; - } - else - { - gUnknown_02024250[gBankTarget] = gCurrentMove; - GET_MOVE_TYPE(gCurrentMove, gUnknown_02024258[gBankTarget]); - } - } - else - { - gUnknown_02024250[gBankTarget] = 0xFFFF; - } - } - gBattleScripting.atk49_state++; - break; - case 15: // mirror move - if (!(gAbsentBankFlags & gBitTable[gBankAttacker]) && !(gBattleStruct->field_91 & gBitTable[gBankAttacker]) - && gBattleMoves[lastMove].flags & FLAG_MIRROR_MOVE_AFFECTED && gHitMarker & HITMARKER_OBEYS - && gBankAttacker != gBankTarget && !(gHitMarker & HITMARKER_FAINTED(gBankTarget)) - && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) - { - u8 target, attacker; - - *(gBattleStruct->mirrorMoves + gBankTarget * 2 + 0) = gLastUsedMove; - *(gBattleStruct->mirrorMoves + gBankTarget * 2 + 1) = gLastUsedMove >> 8; - - target = gBankTarget; - attacker = gBankAttacker; - *(attacker * 2 + target * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 0) = gLastUsedMove; - - target = gBankTarget; - attacker = gBankAttacker; - *(attacker * 2 + target * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 1) = gLastUsedMove >> 8; - } - gBattleScripting.atk49_state++; - break; - case 16: // - if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) && gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && !gProtectStructs[gBankAttacker].chargingTurn && gBattleMoves[gCurrentMove].target == MOVE_TARGET_BOTH - && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) - { - u8 bank = GetBankByIdentity(GetBankIdentity(gBankTarget) ^ BIT_MON); - if (gBattleMons[bank].hp != 0) - { - gBankTarget = bank; - gHitMarker |= HITMARKER_NO_ATTACKSTRING; - gBattleScripting.atk49_state = 0; - MoveValuesCleanUp(); - BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); - gBattlescriptCurrInstr = gUnknown_082DB87D; - return; - } - else - { - gHitMarker |= HITMARKER_NO_ATTACKSTRING; - } - } - gBattleScripting.atk49_state++; - break; - case ATK49_LAST_CASE: - break; - } - - if (arg1 == 1 && effect == FALSE) - gBattleScripting.atk49_state = ATK49_LAST_CASE; - if (arg1 == 2 && arg2 == gBattleScripting.atk49_state) - gBattleScripting.atk49_state = ATK49_LAST_CASE; - - } while (gBattleScripting.atk49_state != ATK49_LAST_CASE && effect == FALSE); - - if (gBattleScripting.atk49_state == ATK49_LAST_CASE && effect == FALSE) - gBattlescriptCurrInstr += 3; -} - -static void atk4A_typecalc2(void) -{ - u8 flags = 0; - s32 i = 0; - u8 moveType = gBattleMoves[gCurrentMove].type; - - if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) - { - gLastUsedAbility = gBattleMons[gBankTarget].ability; - gBattleMoveFlags |= (MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED); - gUnknown_02024250[gBankTarget] = 0; - gBattleCommunication[6] = moveType; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - else - { - while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) - { - if (gTypeEffectiveness[i] == TYPE_FORESIGHT) - { - if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) - { - break; - } - else - { - i += 3; - continue; - } - } - - if (gTypeEffectiveness[i] == moveType) - { - // check type1 - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1) - { - if (gTypeEffectiveness[i + 2] == 0) - { - gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; - break; - } - if (gTypeEffectiveness[i + 2] == 5) - { - flags |= MOVESTATUS_NOTVERYEFFECTIVE; - } - if (gTypeEffectiveness[i + 2] == 20) - { - flags |= MOVESTATUS_SUPEREFFECTIVE; - } - } - // check type2 - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2) - { - if (gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 - && gTypeEffectiveness[i + 2] == 0) - { - gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; - break; - } - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 - && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 - && gTypeEffectiveness[i + 2] == 5) - { - flags |= MOVESTATUS_NOTVERYEFFECTIVE; - } - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 - && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 - && gTypeEffectiveness[i + 2] == 20) - { - flags |= MOVESTATUS_SUPEREFFECTIVE; - } - } - } - i += 3; - } - } - - if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD - && !(flags & MOVESTATUS_NOEFFECT) - && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2 - && (!(flags & MOVESTATUS_SUPEREFFECTIVE) || ((flags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) - && gBattleMoves[gCurrentMove].power) - { - gLastUsedAbility = ABILITY_WONDER_GUARD; - gBattleMoveFlags |= MOVESTATUS_MISSED; - gUnknown_02024250[gBankTarget] = 0; - gBattleCommunication[6] = 3; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) - gProtectStructs[gBankAttacker].notEffective = 1; - - gBattlescriptCurrInstr++; -} - -static void atk4B_return_atk_to_ball(void) -{ - gActiveBank = gBankAttacker; - if (!(gHitMarker & HITMARKER_FAINTED(gActiveBank))) - { - EmitReturnPokeToBall(0, 0); - MarkBufferBankForExecution(gActiveBank); - } - gBattlescriptCurrInstr++; -} - -static void atk4C_copy_poke_data(void) -{ - if (gBattleExecBuffer) - return; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - gBattlePartyID[gActiveBank] = *(gBattleStruct->field_5C + gActiveBank); - - EmitGetMonData(0, 0, gBitTable[gBattlePartyID[gActiveBank]]); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 2; -} - -static void atk4D_switch_data_update(void) -{ - struct BattlePokemon oldData; - s32 i; - u8 *monData; - - if (gBattleExecBuffer) - return; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - oldData = gBattleMons[gActiveBank]; - monData = (u8*)(&gBattleMons[gActiveBank]); - - for (i = 0; i < sizeof(struct BattlePokemon); i++) - { - monData[i] = gBattleBufferB[gActiveBank][4 + i]; - } - - gBattleMons[gActiveBank].type1 = gBaseStats[gBattleMons[gActiveBank].species].type1; - gBattleMons[gActiveBank].type2 = gBaseStats[gBattleMons[gActiveBank].species].type2; - gBattleMons[gActiveBank].ability = GetAbilityBySpecies(gBattleMons[gActiveBank].species, gBattleMons[gActiveBank].altAbility); - - // check knocked off item - i = GetBankSide(gActiveBank); - if (gWishFutureKnock.knockedOffPokes[i] & gBitTable[gBattlePartyID[gActiveBank]]) - { - gBattleMons[gActiveBank].item = 0; - } - - if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS) - { - for (i = 0; i < 8; i++) - { - gBattleMons[gActiveBank].statStages[i] = oldData.statStages[i]; - } - gBattleMons[gActiveBank].status2 = oldData.status2; - } - - SwitchInClearStructs(); - - if (gBattleTypeFlags & BATTLE_TYPE_PALACE && gBattleMons[gActiveBank].maxHP / 2 >= gBattleMons[gActiveBank].hp - && gBattleMons[gActiveBank].hp != 0 && !(gBattleMons[gActiveBank].status1 & STATUS_SLEEP)) - { - gBattleStruct->field_92 |= gBitTable[gActiveBank]; - } - - gBattleScripting.bank = gActiveBank; - gBattleTextBuff1[0] = PLACEHOLDER_BEGIN; - gBattleTextBuff1[1] = 7; - gBattleTextBuff1[2] = gActiveBank; - gBattleTextBuff1[3] = gBattlePartyID[gActiveBank]; - gBattleTextBuff1[4] = EOS; - - gBattlescriptCurrInstr += 2; -} - -static void atk4E_switchin_anim(void) -{ - if (gBattleExecBuffer) - return; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - if (GetBankSide(gActiveBank) == SIDE_OPPONENT - && !(gBattleTypeFlags & (BATTLE_TYPE_LINK - | BATTLE_TYPE_EREADER_TRAINER - | BATTLE_TYPE_x2000000 - | BATTLE_TYPE_x4000000 - | BATTLE_TYPE_FRONTIER))) - HandleSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBank].species), FLAG_SET_SEEN, gBattleMons[gActiveBank].personality); - - gAbsentBankFlags &= ~(gBitTable[gActiveBank]); - - EmitSwitchInAnim(0, gBattlePartyID[gActiveBank], gBattlescriptCurrInstr[2]); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 3; - - if (gBattleTypeFlags & BATTLE_TYPE_ARENA) - sub_81A56B4(); -} - -static void atk4F_jump_if_cannot_switch(void) -{ - s32 val = 0; - s32 compareVar = 0; - struct Pokemon *party = NULL; - s32 r7 = 0; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1] & ~(ATK4F_DONT_CHECK_STATUSES)); - - if (!(gBattlescriptCurrInstr[1] & ATK4F_DONT_CHECK_STATUSES) - && ((gBattleMons[gActiveBank].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) - || (gStatuses3[gActiveBank] & STATUS3_ROOTED))) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - } - else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) - { - #ifndef NONMATCHING - asm("":::"r5"); - #endif // NONMATCHING - if (GetBankSide(gActiveBank) == SIDE_OPPONENT) - party = gEnemyParty; - else - party = gPlayerParty; - - val = 0; - if (2 & gActiveBank) - val = 3; - - for (compareVar = val + 3; val < compareVar; val++) - { - if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&party[val], MON_DATA_IS_EGG) - && GetMonData(&party[val], MON_DATA_HP) != 0 - && gBattlePartyID[gActiveBank] != val) - break; - } - - if (val == compareVar) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; - } - else if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (gBattleTypeFlags & BATTLE_TYPE_x800000) - { - if (GetBankSide(gActiveBank) == SIDE_PLAYER) - { - party = gPlayerParty; - - val = 0; - if (sub_806D82C(sub_806D864(gActiveBank)) == TRUE) - val = 3; - } - else - { - party = gEnemyParty; - - if (gActiveBank == 1) - val = 0; - else - val = 3; - } - } - else - { - if (GetBankSide(gActiveBank) == SIDE_OPPONENT) - party = gEnemyParty; - else - party = gPlayerParty; - - - val = 0; - if (sub_806D82C(sub_806D864(gActiveBank)) == TRUE) - val = 3; - } - - for (compareVar = val + 3; val < compareVar; val++) - { - if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&party[val], MON_DATA_IS_EGG) - && GetMonData(&party[val], MON_DATA_HP) != 0 - && gBattlePartyID[gActiveBank] != val) - break; - } - - if (val == compareVar) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; - } - else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && GetBankSide(gActiveBank) == SIDE_OPPONENT) - { - party = gEnemyParty; - - val = 0; - if (gActiveBank == 3) - val = 3; - - for (compareVar = val + 3; val < compareVar; val++) - { - if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&party[val], MON_DATA_IS_EGG) - && GetMonData(&party[val], MON_DATA_HP) != 0 - && gBattlePartyID[gActiveBank] != val) - break; - } - - if (val == compareVar) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; - } - else - { - if (GetBankSide(gActiveBank) == SIDE_OPPONENT) - { - r7 = GetBankByIdentity(1); - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - compareVar = GetBankByIdentity(3); - else - compareVar = r7; - - party = gEnemyParty; - } - else - { - r7 = GetBankByIdentity(0); - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - compareVar = GetBankByIdentity(2); - else - compareVar = r7; - - party = gPlayerParty; - } - for (val = 0; val < 6; val++) - { - if (GetMonData(&party[val], MON_DATA_HP) != 0 - && GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&party[val], MON_DATA_IS_EGG) - && val != gBattlePartyID[r7] && val != gBattlePartyID[compareVar]) - break; - } - - if (val == 6) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; - } -} - -static void sub_804CF10(u8 arg0) -{ - *(gBattleStruct->field_58 + gActiveBank) = gBattlePartyID[gActiveBank]; - *(gBattleStruct->field_5C + gActiveBank) = 6; - gBattleStruct->field_93 &= ~(gBitTable[gActiveBank]); - - EmitChoosePokemon(0, 1, arg0, 0, gBattleStruct->field_60[gActiveBank]); - MarkBufferBankForExecution(gActiveBank); -} - -static void atk50_openpartyscreen(void) -{ - u32 flags; - u8 hitmarkerFaintBits; - u8 bank; - const u8 *jumpPtr; - - bank = 0; - flags = 0; - jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - - if (gBattlescriptCurrInstr[1] == 5) - { - if ((gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI)) != BATTLE_TYPE_DOUBLE) - { - for (gActiveBank = 0; gActiveBank < gNoOfAllBanks; gActiveBank++) - { - if (gHitMarker & HITMARKER_FAINTED(gActiveBank)) - { - if (sub_80423F4(gActiveBank, 6, 6)) - { - gAbsentBankFlags |= gBitTable[gActiveBank]; - gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); - EmitLinkStandbyMsg(0, 2, 0); - MarkBufferBankForExecution(gActiveBank); - } - else if (!gSpecialStatuses[gActiveBank].flag40) - { - sub_804CF10(6); - gSpecialStatuses[gActiveBank].flag40 = 1; - } - } - else - { - EmitLinkStandbyMsg(0, 2, 0); - MarkBufferBankForExecution(gActiveBank); - } - } - } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - u8 flag40_0, flag40_1, flag40_2, flag40_3; - - hitmarkerFaintBits = gHitMarker >> 0x1C; - - if (gBitTable[0] & hitmarkerFaintBits) - { - gActiveBank = 0; - if (sub_80423F4(0, 6, 6)) - { - gAbsentBankFlags |= gBitTable[gActiveBank]; - gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); - Emit_x2A(0); - MarkBufferBankForExecution(gActiveBank); - } - else if (!gSpecialStatuses[gActiveBank].flag40) - { - sub_804CF10(gBattleStruct->field_5C[2]); - gSpecialStatuses[gActiveBank].flag40 = 1; - } - else - { - EmitLinkStandbyMsg(0, 2, 0); - MarkBufferBankForExecution(gActiveBank); - flags |= 1; - } - } - if (gBitTable[2] & hitmarkerFaintBits && !(gBitTable[0] & hitmarkerFaintBits)) - { - gActiveBank = 2; - if (sub_80423F4(2, 6, 6)) - { - gAbsentBankFlags |= gBitTable[gActiveBank]; - gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); - Emit_x2A(0); - MarkBufferBankForExecution(gActiveBank); - } - else if (!gSpecialStatuses[gActiveBank].flag40) - { - sub_804CF10(gBattleStruct->field_5C[0]); - gSpecialStatuses[gActiveBank].flag40 = 1; - } - else if (!(flags & 1)) - { - EmitLinkStandbyMsg(0, 2, 0); - MarkBufferBankForExecution(gActiveBank); - } - } - if (gBitTable[1] & hitmarkerFaintBits) - { - gActiveBank = 1; - if (sub_80423F4(1, 6, 6)) - { - gAbsentBankFlags |= gBitTable[gActiveBank]; - gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); - Emit_x2A(0); - MarkBufferBankForExecution(gActiveBank); - } - else if (!gSpecialStatuses[gActiveBank].flag40) - { - sub_804CF10(gBattleStruct->field_5C[3]); - gSpecialStatuses[gActiveBank].flag40 = 1; - } - else - { - EmitLinkStandbyMsg(0, 2, 0); - MarkBufferBankForExecution(gActiveBank); - flags |= 2; - } - } - if (gBitTable[3] & hitmarkerFaintBits && !(gBitTable[1] & hitmarkerFaintBits)) - { - gActiveBank = 3; - if (sub_80423F4(3, 6, 6)) - { - gAbsentBankFlags |= gBitTable[gActiveBank]; - gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); - Emit_x2A(0); - MarkBufferBankForExecution(gActiveBank); - } - else if (!gSpecialStatuses[gActiveBank].flag40) - { - sub_804CF10(gBattleStruct->field_5C[1]); - gSpecialStatuses[gActiveBank].flag40 = 1; - } - else if (!(flags & 2)) - { - EmitLinkStandbyMsg(0, 2, 0); - MarkBufferBankForExecution(gActiveBank); - } - } - - flag40_0 = gSpecialStatuses[0].flag40; - if (!flag40_0) - { - flag40_2 = gSpecialStatuses[2].flag40; - if (!flag40_2 && hitmarkerFaintBits != 0) - { - if (gAbsentBankFlags & gBitTable[0]) - gActiveBank = 2; - else - gActiveBank = 0; - - EmitLinkStandbyMsg(0, 2, 0); - MarkBufferBankForExecution(gActiveBank); - } - - } - flag40_1 = gSpecialStatuses[1].flag40; - if (!flag40_1) - { - flag40_3 = gSpecialStatuses[3].flag40; - if (!flag40_3 && hitmarkerFaintBits != 0) - { - if (gAbsentBankFlags & gBitTable[1]) - gActiveBank = 3; - else - gActiveBank = 1; - - EmitLinkStandbyMsg(0, 2, 0); - MarkBufferBankForExecution(gActiveBank); - } - } - } - gBattlescriptCurrInstr += 6; - } - else if (gBattlescriptCurrInstr[1] == 6) - { - if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - hitmarkerFaintBits = gHitMarker >> 0x1C; - if (gBitTable[2] & hitmarkerFaintBits && gBitTable[0] & hitmarkerFaintBits) - { - gActiveBank = 2; - if (sub_80423F4(2, gBattleBufferB[0][1], 6)) - { - gAbsentBankFlags |= gBitTable[gActiveBank]; - gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); - Emit_x2A(0); - MarkBufferBankForExecution(gActiveBank); - } - else if (!gSpecialStatuses[gActiveBank].flag40) - { - sub_804CF10(gBattleStruct->field_5C[0]); - gSpecialStatuses[gActiveBank].flag40 = 1; - } - } - if (gBitTable[3] & hitmarkerFaintBits && hitmarkerFaintBits & gBitTable[1]) - { - gActiveBank = 3; - if (sub_80423F4(3, gBattleBufferB[1][1], 6)) - { - gAbsentBankFlags |= gBitTable[gActiveBank]; - gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); - Emit_x2A(0); - MarkBufferBankForExecution(gActiveBank); - } - else if (!gSpecialStatuses[gActiveBank].flag40) - { - sub_804CF10(gBattleStruct->field_5C[1]); - gSpecialStatuses[gActiveBank].flag40 = 1; - } - } - gBattlescriptCurrInstr += 6; - } - else - { - gBattlescriptCurrInstr += 6; - } - } - else - { - gBattlescriptCurrInstr += 6; - } - - hitmarkerFaintBits = gHitMarker >> 0x1C; - - gBank1 = 0; - while (1) - { - if (gBitTable[gBank1] & hitmarkerFaintBits) - break; - if (gBank1 >= gNoOfAllBanks) - break; - gBank1++; - } - - if (gBank1 == gNoOfAllBanks) - gBattlescriptCurrInstr = jumpPtr; - } - else - { - if (gBattlescriptCurrInstr[1] & 0x80) - hitmarkerFaintBits = 0; // used here as the caseId for the EmitChoose function - else - hitmarkerFaintBits = 1; - - bank = GetBattleBank(gBattlescriptCurrInstr[1] & ~(0x80)); - if (gSpecialStatuses[bank].flag40) - { - gBattlescriptCurrInstr += 6; - } - else if (sub_80423F4(bank, 6, 6)) - { - gActiveBank = bank; - gAbsentBankFlags |= gBitTable[gActiveBank]; - gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); - gBattlescriptCurrInstr = jumpPtr; - } - else - { - gActiveBank = bank; - *(gBattleStruct->field_58 + gActiveBank) = gBattlePartyID[gActiveBank]; - *(gBattleStruct->field_5C + gActiveBank) = 6; - gBattleStruct->field_93 &= ~(gBitTable[gActiveBank]); - - EmitChoosePokemon(0, hitmarkerFaintBits, *(gBattleStruct->field_5C + (gActiveBank ^ 2)), 0, gBattleStruct->field_60[gActiveBank]); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 6; - - if (GetBankIdentity(gActiveBank) == 0 && gBattleResults.playerSwitchesCounter < 0xFF) - gBattleResults.playerSwitchesCounter++; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - for (gActiveBank = 0; gActiveBank < gNoOfAllBanks; gActiveBank++) - { - if (gActiveBank != bank) - { - EmitLinkStandbyMsg(0, 2, 0); - MarkBufferBankForExecution(gActiveBank); - } - } - } - else - { - gActiveBank = GetBankByIdentity(GetBankIdentity(bank) ^ BIT_SIDE); - if (gAbsentBankFlags & gBitTable[gActiveBank]) - gActiveBank ^= BIT_MON; - - EmitLinkStandbyMsg(0, 2, 0); - MarkBufferBankForExecution(gActiveBank); - } - } - } -} - -static void atk51_switch_handle_order(void) -{ - s32 i; - if (gBattleExecBuffer) - return; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - switch (gBattlescriptCurrInstr[2]) - { - case 0: - for (i = 0; i < gNoOfAllBanks; i++) - { - if (gBattleBufferB[i][0] == 0x22) - { - *(gBattleStruct->field_5C + i) = gBattleBufferB[i][1]; - if (!(gBattleStruct->field_93 & gBitTable[i])) - { - RecordedBattle_SetBankAction(i, gBattleBufferB[i][1]); - gBattleStruct->field_93 |= gBitTable[i]; - } - } - } - break; - case 1: - if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - sub_803BDA0(gActiveBank); - break; - case 2: - if (!(gBattleStruct->field_93 & gBitTable[gActiveBank])) - { - RecordedBattle_SetBankAction(gActiveBank, gBattleBufferB[gActiveBank][1]); - gBattleStruct->field_93 |= gBitTable[gActiveBank]; - } - // fall through - case 3: - gBattleCommunication[0] = gBattleBufferB[gActiveBank][1]; - *(gBattleStruct->field_5C + gActiveBank) = gBattleBufferB[gActiveBank][1]; - - if ((gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_LINK)) == (BATTLE_TYPE_MULTI | BATTLE_TYPE_LINK)) - { - *(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 0) &= 0xF; - *(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBank][2] & 0xF0); - *(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 1) = gBattleBufferB[gActiveBank][3]; - - *((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 0) &= (0xF0); - *((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBank][2] & 0xF0) >> 4; - *((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 2) = gBattleBufferB[gActiveBank][3]; - } - else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) - { - sub_80571DC(gActiveBank, *(gBattleStruct->field_5C + gActiveBank)); - } - else - { - sub_803BDA0(gActiveBank); - } - - PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBankAttacker].species) - PREPARE_MON_NICK_BUFFER(gBattleTextBuff2, gActiveBank, gBattleBufferB[gActiveBank][1]) - - break; - } - - gBattlescriptCurrInstr += 3; -} - -static void atk52_switch_in_effects(void) -{ - s32 i; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - sub_803FA70(gActiveBank); - - gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); - gSpecialStatuses[gActiveBank].flag40 = 0; - - if (!(gSideAffecting[GetBankSide(gActiveBank)] & SIDE_STATUS_SPIKES_DAMAGED) - && (gSideAffecting[GetBankSide(gActiveBank)] & SIDE_STATUS_SPIKES) - && gBattleMons[gActiveBank].type1 != TYPE_FLYING - && gBattleMons[gActiveBank].type2 != TYPE_FLYING - && gBattleMons[gActiveBank].ability != ABILITY_LEVITATE) - { - u8 spikesDmg; - - gSideAffecting[GetBankSide(gActiveBank)] |= SIDE_STATUS_SPIKES_DAMAGED; - - gBattleMons[gActiveBank].status2 &= ~(STATUS2_DESTINY_BOND); - gHitMarker &= ~(HITMARKER_DESTINYBOND); - - spikesDmg = (5 - gSideTimers[GetBankSide(gActiveBank)].spikesAmount) * 2; - gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / (spikesDmg); - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - gBattleScripting.bank = gActiveBank; - BattleScriptPushCursor(); - - if (gBattlescriptCurrInstr[1] == 0) - gBattlescriptCurrInstr = gUnknown_082DAE90; - else if (gBattlescriptCurrInstr[1] == 1) - gBattlescriptCurrInstr = gUnknown_082DAE59; - else - gBattlescriptCurrInstr = gUnknown_082DAEC7; - } - else - { - if (gBattleMons[gActiveBank].ability == ABILITY_TRUANT && !gDisableStructs[gActiveBank].truantUnknownBit) - gDisableStructs[gActiveBank].truantCounter = 1; - - gDisableStructs[gActiveBank].truantUnknownBit = 0; - - if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBank, 0, 0, 0) == 0 && - ItemBattleEffects(0, gActiveBank, 0) == 0) - { - gSideAffecting[GetBankSide(gActiveBank)] &= ~(SIDE_STATUS_SPIKES_DAMAGED); - - for (i = 0; i < gNoOfAllBanks; i++) - { - if (gTurnOrder[i] == gActiveBank) - gUnknown_0202407A[i] = 0xC; - } - - for (i = 0; i < gNoOfAllBanks; i++) - { - u16* hpOnSwitchout = &gBattleStruct->hpOnSwitchout[GetBankSide(i)]; - *hpOnSwitchout = gBattleMons[i].hp; - } - - if (gBattlescriptCurrInstr[1] == 5) - { - u32 hitmarkerFaintBits = gHitMarker >> 0x1C; - - gBank1++; - while (1) - { - if (hitmarkerFaintBits & gBitTable[gBank1] && !(gAbsentBankFlags & gBitTable[gBank1])) - break; - if (gBank1 >= gNoOfAllBanks) - break; - gBank1++; - } - } - gBattlescriptCurrInstr += 2; - } - } -} - -static void atk53_trainer_slide(void) -{ - gActiveBank = GetBankByIdentity(gBattlescriptCurrInstr[1]); - EmitTrainerSlide(0); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 2; -} - -static void atk54_effectiveness_sound(void) -{ - gActiveBank = gBankAttacker; - EmitEffectivenessSound(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1)); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 3; -} - -static void atk55_play_sound(void) -{ - gActiveBank = gBankAttacker; - EmitPlaySound(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1), 0); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 3; -} - -static void atk56_fainting_cry(void) -{ - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - EmitFaintingCry(0); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 2; -} - -static void atk57(void) -{ - gActiveBank = GetBankByIdentity(0); - Emit_x37(0, gBattleOutcome); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 1; -} - -static void atk58_return_to_ball(void) -{ - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - EmitReturnPokeToBall(0, 1); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 2; -} - -static void atk59_learnmove_inbattle(void) -{ - const u8* jumpPtr1 = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - const u8* jumpPtr2 = BSScriptReadPtr(gBattlescriptCurrInstr + 5); - - u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], gBattlescriptCurrInstr[9]); - while (ret == 0xFFFE) - ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], 0); - - if (ret == 0) - { - gBattlescriptCurrInstr = jumpPtr2; - } - else if (ret == 0xFFFF) - { - gBattlescriptCurrInstr += 10; - } - else - { - gActiveBank = GetBankByIdentity(0); - - if (gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId - && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) - { - GiveMoveToBattleMon(&gBattleMons[gActiveBank], ret); - } - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - gActiveBank = GetBankByIdentity(2); - if (gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId - && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) - { - GiveMoveToBattleMon(&gBattleMons[gActiveBank], ret); - } - } - - gBattlescriptCurrInstr = jumpPtr1; - } -} - -static void atk5A_yesnoboxlearnmove(void) -{ - gActiveBank = 0; - - switch (gBattleScripting.learnMoveState) - { - case 0: - sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); - sub_814F9EC(gText_BattleYesNoChoice, 0xC); - gBattleScripting.learnMoveState++; - gBattleCommunication[CURSOR_POSITION] = 0; - BattleCreateCursorAt(0); - break; - case 1: - if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) - { - PlaySE(SE_SELECT); - BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); - gBattleCommunication[CURSOR_POSITION] = 0; - BattleCreateCursorAt(0); - } - if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) - { - PlaySE(SE_SELECT); - BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); - gBattleCommunication[CURSOR_POSITION] = 1; - BattleCreateCursorAt(1); - } - if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - if (gBattleCommunication[1] == 0) - { - sub_8056A3C(0x18, 0x8, 0x1D, 0xD, 1); - BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); - gBattleScripting.learnMoveState++; - } - else - { - gBattleScripting.learnMoveState = 5; - } - } - else if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - gBattleScripting.learnMoveState = 5; - } - break; - case 2: - if (!gPaletteFade.active) - { - FreeAllWindowBuffers(); - sub_81BFA38(gPlayerParty, gBattleStruct->expGetterId, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, gMoveToLearn); - gBattleScripting.learnMoveState++; - } - break; - case 3: - if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2) - { - gBattleScripting.learnMoveState++; - } - break; - case 4: - if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2) - { - u8 movePosition = sub_81C1B94(); - if (movePosition == 4) - { - gBattleScripting.learnMoveState = 5; - } - else - { - u16 moveId = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MOVE1 + movePosition); - if (IsHMMove2(moveId)) - { - PrepareStringBattle(0x13F, gActiveBank); - gBattleScripting.learnMoveState = 6; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - - PREPARE_MOVE_BUFFER(gBattleTextBuff2, moveId) - - RemoveMonPPBonus(&gPlayerParty[gBattleStruct->expGetterId], movePosition); - SetMonMoveSlot(&gPlayerParty[gBattleStruct->expGetterId], gMoveToLearn, movePosition); - - if (gBattlePartyID[0] == gBattleStruct->expGetterId - && !(gBattleMons[0].status2 & STATUS2_TRANSFORMED) - && !(gDisableStructs[0].unk18_b & gBitTable[movePosition])) - { - RemoveBattleMonPPBonus(&gBattleMons[0], movePosition); - SetBattleMonMoveSlot(&gBattleMons[0], gMoveToLearn, movePosition); - } - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && gBattlePartyID[2] == gBattleStruct->expGetterId - && !(gBattleMons[2].status2 & STATUS2_TRANSFORMED) - && !(gDisableStructs[2].unk18_b & gBitTable[movePosition])) - { - RemoveBattleMonPPBonus(&gBattleMons[2], movePosition); - SetBattleMonMoveSlot(&gBattleMons[2], gMoveToLearn, movePosition); - } - } - } - } - break; - case 5: - sub_8056A3C(0x18, 8, 0x1D, 0xD, 1); - gBattlescriptCurrInstr += 5; - break; - case 6: - if (gBattleExecBuffer == 0) - { - gBattleScripting.learnMoveState = 2; - } - break; - } -} - -static void atk5B_yesnoboxstoplearningmove(void) -{ - switch (gBattleScripting.learnMoveState) - { - case 0: - sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); - sub_814F9EC(gText_BattleYesNoChoice, 0xC); - gBattleScripting.learnMoveState++; - gBattleCommunication[CURSOR_POSITION] = 0; - BattleCreateCursorAt(0); - break; - case 1: - if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) - { - PlaySE(SE_SELECT); - BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); - gBattleCommunication[CURSOR_POSITION] = 0; - BattleCreateCursorAt(0); - } - if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) - { - PlaySE(SE_SELECT); - BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); - gBattleCommunication[CURSOR_POSITION] = 1; - BattleCreateCursorAt(1); - } - if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - - if (gBattleCommunication[1] != 0) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; - - sub_8056A3C(0x18, 0x8, 0x1D, 0xD, 1); - } - else if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - sub_8056A3C(0x18, 0x8, 0x1D, 0xD, 1); - } - break; - } -} - -static void atk5C_hitanimation(void) -{ - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) - { - gBattlescriptCurrInstr += 2; - } - else if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE) || !(gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE) || gDisableStructs[gActiveBank].substituteHP == 0) - { - EmitHitAnimation(0); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 2; - } - else - { - gBattlescriptCurrInstr += 2; - } -} - -static u32 GetTrainerMoneyToGive(u16 trainerId) -{ - u32 i = 0; - u32 lastMonLevel = 0; - u32 moneyReward = 0; - - if (trainerId == SECRET_BASE_OPPONENT) - { - moneyReward = 20 * gBattleResources->secretBase->partyLevels[0] * gBattleStruct->moneyMultiplier; - } - else - { - switch (gTrainers[trainerId].partyFlags) - { - case 0: - { - const struct TrainerMonNoItemDefaultMoves *party = gTrainers[trainerId].party.NoItemDefaultMoves; - lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; - } - break; - case PARTY_FLAG_CUSTOM_MOVES: - { - const struct TrainerMonNoItemCustomMoves *party = gTrainers[trainerId].party.NoItemCustomMoves; - lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; - } - break; - case PARTY_FLAG_HAS_ITEM: - { - const struct TrainerMonItemDefaultMoves *party = gTrainers[trainerId].party.ItemDefaultMoves; - lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; - } - break; - case PARTY_FLAG_CUSTOM_MOVES | PARTY_FLAG_HAS_ITEM: - { - const struct TrainerMonItemCustomMoves *party = gTrainers[trainerId].party.ItemCustomMoves; - lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; - } - break; - } - - for (; gTrainerMoneyTable[i].classId != 0xFF; i++) - { - if (gTrainerMoneyTable[i].classId == gTrainers[trainerId].trainerClass) - break; - } - - if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) - moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * gTrainerMoneyTable[i].value; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * 2 * gTrainerMoneyTable[i].value; - else - moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * gTrainerMoneyTable[i].value; - } - - return moneyReward; -} - -static void atk5D_getmoneyreward(void) -{ - u32 moneyReward = GetTrainerMoneyToGive(gTrainerBattleOpponent_A); - if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) - moneyReward += GetTrainerMoneyToGive(gTrainerBattleOpponent_B); - - AddMoney(&gSaveBlock1Ptr->money, moneyReward); - - PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff1, 5, moneyReward) - - gBattlescriptCurrInstr++; -} - -static void atk5E_8025A70(void) -{ - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - switch (gBattleCommunication[0]) - { - case 0: - EmitGetMonData(0, REQUEST_ALL_BATTLE, 0); - MarkBufferBankForExecution(gActiveBank); - gBattleCommunication[0]++; - break; - case 1: - if (gBattleExecBuffer == 0) - { - s32 i; - struct BattlePokemon* bufferPoke = (struct BattlePokemon*) &gBattleBufferB[gActiveBank][4]; - for (i = 0; i < 4; i++) - { - gBattleMons[gActiveBank].moves[i] = bufferPoke->moves[i]; - gBattleMons[gActiveBank].pp[i] = bufferPoke->pp[i]; - } - gBattlescriptCurrInstr += 2; - } - break; - } -} - -static void atk5F_8025B24(void) -{ - gActiveBank = gBankAttacker; - gBankAttacker = gBankTarget; - gBankTarget = gActiveBank; - - if (gHitMarker & HITMARKER_PURSUIT_TRAP) - gHitMarker &= ~(HITMARKER_PURSUIT_TRAP); - else - gHitMarker |= HITMARKER_PURSUIT_TRAP; - - gBattlescriptCurrInstr++; -} - -static void atk60_increment_gamestat(void) -{ - if (GetBankSide(gBankAttacker) == SIDE_PLAYER) - IncrementGameStat(gBattlescriptCurrInstr[1]); - - gBattlescriptCurrInstr += 2; -} - -static void atk61_8025BA4(void) -{ - s32 i; - struct Pokemon* party; - struct HpAndStatus hpStatuses[6]; - - if (gBattleExecBuffer) - return; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - if (GetBankSide(gActiveBank) == SIDE_PLAYER) - party = gPlayerParty; - else - party = gEnemyParty; - - for (i = 0; i < 6; i++) - { - if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_NONE - || GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG) - { - hpStatuses[i].hp = 0xFFFF; - hpStatuses[i].status = 0; - } - else - { - hpStatuses[i].hp = GetMonData(&party[i], MON_DATA_HP); - hpStatuses[i].status = GetMonData(&party[i], MON_DATA_STATUS); - } - } - - EmitCmd48(0, hpStatuses, 1); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 2; -} - -static void atk62_08025C6C(void) -{ - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - EmitCmd49(0); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 2; -} - -static void atk63_jumptorandomattack(void) -{ - if (gBattlescriptCurrInstr[1] != 0) - gCurrentMove = gRandomMove; - else - gLastUsedMove = gCurrentMove = gRandomMove; - - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; -} - -static void atk64_statusanimation(void) -{ - if (gBattleExecBuffer == 0) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) - && gDisableStructs[gActiveBank].substituteHP == 0 - && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) - { - EmitStatusAnimation(0, FALSE, gBattleMons[gActiveBank].status1); - MarkBufferBankForExecution(gActiveBank); - } - gBattlescriptCurrInstr += 2; - } -} - -static void atk65_status2animation(void) -{ - u32 wantedToAnimate; - - if (gBattleExecBuffer == 0) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - wantedToAnimate = BSScriptRead32(gBattlescriptCurrInstr + 2); - if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) - && gDisableStructs[gActiveBank].substituteHP == 0 - && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) - { - EmitStatusAnimation(0, TRUE, gBattleMons[gActiveBank].status2 & wantedToAnimate); - MarkBufferBankForExecution(gActiveBank); - } - gBattlescriptCurrInstr += 6; - } -} - -static void atk66_chosenstatusanimation(void) -{ - u32 wantedStatus; - - if (gBattleExecBuffer == 0) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - wantedStatus = BSScriptRead32(gBattlescriptCurrInstr + 3); - if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) - && gDisableStructs[gActiveBank].substituteHP == 0 - && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) - { - EmitStatusAnimation(0, gBattlescriptCurrInstr[2], wantedStatus); - MarkBufferBankForExecution(gActiveBank); - } - gBattlescriptCurrInstr += 7; - } -} - -static void atk67_yesnobox(void) -{ - switch (gBattleCommunication[0]) - { - case 0: - sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); - sub_814F9EC(gText_BattleYesNoChoice, 0xC); - gBattleCommunication[0]++; - gBattleCommunication[CURSOR_POSITION] = 0; - BattleCreateCursorAt(0); - break; - case 1: - if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) - { - PlaySE(SE_SELECT); - BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); - gBattleCommunication[CURSOR_POSITION] = 0; - BattleCreateCursorAt(0); - } - if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) - { - PlaySE(SE_SELECT); - BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); - gBattleCommunication[CURSOR_POSITION] = 1; - BattleCreateCursorAt(1); - } - if (gMain.newKeys & B_BUTTON) - { - gBattleCommunication[CURSOR_POSITION] = 1; - PlaySE(SE_SELECT); - sub_8056A3C(0x18, 8, 0x1D, 0xD, 1); - gBattlescriptCurrInstr++; - } - else if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - sub_8056A3C(0x18, 8, 0x1D, 0xD, 1); - gBattlescriptCurrInstr++; - } - break; - } -} - -static void atk68_80246A0(void) -{ - s32 i; - - for (i = 0; i < gNoOfAllBanks; i++) - gUnknown_0202407A[i] = 0xC; - - gBattlescriptCurrInstr++; -} - -static void atk69_dmg_adjustment3(void) // The same as 0x7, except there's no random damage multiplier. -{ - u8 holdEffect, quality; - - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - { - holdEffect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; - } - else - { - holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); - } - - gStringBank = gBankTarget; - - if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) - { - RecordItemEffectBattle(gBankTarget, holdEffect); - gSpecialStatuses[gBankTarget].focusBanded = 1; - } - if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) - goto END; - if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE && !gProtectStructs[gBankTarget].endured - && !gSpecialStatuses[gBankTarget].focusBanded) - goto END; - - if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) - goto END; - - gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; - - if (gProtectStructs[gBankTarget].endured) - { - gBattleMoveFlags |= MOVESTATUS_ENDURED; - } - else if (gSpecialStatuses[gBankTarget].focusBanded) - { - gBattleMoveFlags |= MOVESTATUS_HUNGON; - gLastUsedItem = gBattleMons[gBankTarget].item; - } - - END: - gBattlescriptCurrInstr++; -} - -static void atk6A_removeitem(void) -{ - u16* usedHeldItem; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBank]; - *usedHeldItem = gBattleMons[gActiveBank].item; - gBattleMons[gActiveBank].item = 0; - - EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBank].item); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 2; -} - -static void atk6B_atknameinbuff1(void) -{ - PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBankAttacker, gBattlePartyID[gBankAttacker]) - - gBattlescriptCurrInstr++; -} - -static void atk6C_draw_lvlupbox(void) -{ - if (gBattleScripting.atk6C_state == 0) - { - if (IsMonGettingExpSentOut()) - gBattleScripting.atk6C_state = 3; - else - gBattleScripting.atk6C_state = 1; - } - - switch (gBattleScripting.atk6C_state) - { - case 1: - gBattle_BG2_Y = 0x60; - SetBgAttribute(2, BG_CTRL_ATTR_MOSAIC, 0); - ShowBg(2); - sub_804F17C(); - gBattleScripting.atk6C_state = 2; - break; - case 2: - if (!sub_804F1CC()) - gBattleScripting.atk6C_state = 3; - break; - case 3: - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0x100; - SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 1); - SetBgAttribute(1, BG_CTRL_ATTR_MOSAIC, 0); - ShowBg(0); - ShowBg(1); - sub_8056A3C(0x12, 7, 0x1D, 0x13, 0x80); - gBattleScripting.atk6C_state = 4; - break; - case 4: - sub_804F100(); - PutWindowTilemap(13); - CopyWindowToVram(13, 3); - gBattleScripting.atk6C_state++; - break; - case 5: - case 7: - if (!IsDma3ManagerBusyWithBgCopy()) - { - gBattle_BG1_Y = 0; - gBattleScripting.atk6C_state++; - } - break; - case 6: - if (gMain.newKeys != 0) - { - PlaySE(SE_SELECT); - sub_804F144(); - CopyWindowToVram(13, 2); - gBattleScripting.atk6C_state++; - } - break; - case 8: - if (gMain.newKeys != 0) - { - PlaySE(SE_SELECT); - sub_8056A3C(0x12, 7, 0x1D, 0x13, 0x81); - gBattleScripting.atk6C_state++; - } - break; - case 9: - if (!sub_804F344()) - { - ClearWindowTilemap(14); - CopyWindowToVram(14, 1); - - ClearWindowTilemap(13); - CopyWindowToVram(13, 1); - - SetBgAttribute(2, BG_CTRL_ATTR_MOSAIC, 2); - ShowBg(2); - - gBattleScripting.atk6C_state = 10; - } - break; - case 10: - if (!IsDma3ManagerBusyWithBgCopy()) - { - SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 0); - SetBgAttribute(1, BG_CTRL_ATTR_MOSAIC, 1); - ShowBg(0); - ShowBg(1); - gBattlescriptCurrInstr++; - } - break; - } -} - -static void sub_804F100(void) -{ - struct StatsArray currentStats; - - sub_81D388C(&gPlayerParty[gBattleStruct->expGetterId], ¤tStats); - sub_81D3640(0xD, gBattleResources->statsBeforeLvlUp, ¤tStats, 0xE, 0xD, 0xF); -} - -static void sub_804F144(void) -{ - struct StatsArray currentStats; - - sub_81D388C(&gPlayerParty[gBattleStruct->expGetterId], ¤tStats); - sub_81D3784(0xD, ¤tStats, 0xE, 0xD, 0xF); -} - -static void sub_804F17C(void) -{ - gBattle_BG2_Y = 0; - gBattle_BG2_X = 0x1A0; - - LoadPalette(sUnknown_0831C2C8, 0x60, 0x20); - CopyToWindowPixelBuffer(14, sUnknown_0831C2E8, 0, 0); - PutWindowTilemap(14); - CopyWindowToVram(14, 3); - - PutMonIconOnLvlUpBox(); -} - -static bool8 sub_804F1CC(void) -{ - if (IsDma3ManagerBusyWithBgCopy()) - return TRUE; - - if (gBattle_BG2_X == 0x200) - return FALSE; - - if (gBattle_BG2_X == 0x1A0) - PutLevelAndGenderOnLvlUpBox(); - - gBattle_BG2_X += 8; - if (gBattle_BG2_X >= 0x200) - gBattle_BG2_X = 0x200; - - return (gBattle_BG2_X != 0x200); -} - -static void PutLevelAndGenderOnLvlUpBox(void) -{ - u16 monLevel; - u8 monGender; - struct TextSubPrinter subPrinter; - u8 *txtPtr; - u32 var; - - monLevel = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); - monGender = GetMonGender(&gPlayerParty[gBattleStruct->expGetterId]); - GetMonNickname(&gPlayerParty[gBattleStruct->expGetterId], gStringVar4); - - subPrinter.current_text_offset = gStringVar4; - subPrinter.windowId = 14; - subPrinter.fontId = 0; - subPrinter.x = 32; - subPrinter.y = 0; - subPrinter.currentX = 32; - subPrinter.currentY = 0; - subPrinter.letterSpacing = 0; - subPrinter.lineSpacing = 0; - subPrinter.fontColor_l = TEXT_COLOR_TRANSPARENT; - subPrinter.fontColor_h = TEXT_COLOR_WHITE; - subPrinter.bgColor = TEXT_COLOR_TRANSPARENT; - subPrinter.shadowColor = TEXT_COLOR_DARK_GREY; - - AddTextPrinter(&subPrinter, 0xFF, NULL); - - txtPtr = gStringVar4; - gStringVar4[0] = CHAR_SPECIAL_F9; - txtPtr++; - txtPtr[0] = 5; - txtPtr++; - - var = (u32)(txtPtr); - txtPtr = ConvertIntToDecimalStringN(txtPtr, monLevel, STR_CONV_MODE_LEFT_ALIGN, 3); - var = (u32)(txtPtr) - var; - txtPtr = StringFill(txtPtr, 0x77, 4 - var); - - if (monGender != MON_GENDERLESS) - { - if (monGender == MON_MALE) - { - txtPtr = WriteColorChangeControlCode(txtPtr, 0, 0xC); - txtPtr = WriteColorChangeControlCode(txtPtr, 1, 0xD); - *(txtPtr++) = CHAR_MALE; - } - else - { - txtPtr = WriteColorChangeControlCode(txtPtr, 0, 0xE); - txtPtr = WriteColorChangeControlCode(txtPtr, 1, 0xF); - *(txtPtr++) = CHAR_FEMALE; - } - *(txtPtr++) = EOS; - } - - subPrinter.y = 10; - subPrinter.currentY = 10; - AddTextPrinter(&subPrinter, 0xFF, NULL); - - CopyWindowToVram(14, 2); -} - -static bool8 sub_804F344(void) -{ - if (gBattle_BG2_X == 0x1A0) - return FALSE; - - if (gBattle_BG2_X - 16 < 0x1A0) - gBattle_BG2_X = 0x1A0; - else - gBattle_BG2_X -= 16; - - return (gBattle_BG2_X != 0x1A0); -} - -#define sDestroy data0 -#define sSavedLvlUpBoxXPosition data1 - -static void PutMonIconOnLvlUpBox(void) -{ - u8 spriteId; - const u16* iconPal; - struct SpriteSheet iconSheet; - struct SpritePalette iconPalSheet; - - u16 species = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPECIES); - u32 personality = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_PERSONALITY); - - const u8* iconPtr = GetMonIconPtr(species, personality, 1); - iconSheet.data = iconPtr; - iconSheet.size = 0x200; - iconSheet.tag = MON_ICON_LVLUP_BOX_TAG; - - iconPal = GetValidMonIconPalettePtr(species); - iconPalSheet.data = iconPal; - iconPalSheet.tag = MON_ICON_LVLUP_BOX_TAG; - - LoadSpriteSheet(&iconSheet); - LoadSpritePalette(&iconPalSheet); - - spriteId = CreateSprite(&sSpriteTemplate_MonIconOnLvlUpBox, 256, 10, 0); - gSprites[spriteId].sDestroy = FALSE; - gSprites[spriteId].sSavedLvlUpBoxXPosition = gBattle_BG2_X; -} - -static void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite) -{ - sprite->pos2.x = sprite->sSavedLvlUpBoxXPosition - gBattle_BG2_X; - - if (sprite->pos2.x != 0) - { - sprite->sDestroy = TRUE; - } - else if (sprite->sDestroy) - { - DestroySprite(sprite); - FreeSpriteTilesByTag(MON_ICON_LVLUP_BOX_TAG); - FreeSpritePaletteByTag(MON_ICON_LVLUP_BOX_TAG); - } -} - -#undef sDestroy -#undef sSavedLvlUpBoxXPosition - -static bool32 IsMonGettingExpSentOut(void) -{ - if (gBattlePartyID[0] == gBattleStruct->expGetterId) - return TRUE; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlePartyID[2] == gBattleStruct->expGetterId) - return TRUE; - - return FALSE; -} - -static void atk6D_reset_sentpokes_value(void) -{ - ResetSentPokesToOpponentValue(); - gBattlescriptCurrInstr++; -} - -static void atk6E_set_atk_to_player0(void) -{ - gBankAttacker = GetBankByIdentity(0); - gBattlescriptCurrInstr++; -} - -static void atk6F_set_visible(void) -{ - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - EmitSpriteInvisibility(0, FALSE); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 2; -} - -static void atk70_record_last_used_ability(void) -{ - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - RecordAbilityBattle(gActiveBank, gLastUsedAbility); - gBattlescriptCurrInstr += 1; // UB: Should be + 2, one byte for command and one byte for bank argument. -} - -void BufferMoveToLearnIntoBattleTextBuff2(void) -{ - PREPARE_MOVE_BUFFER(gBattleTextBuff2, gMoveToLearn); -} - -static void atk71_buffer_move_to_learn(void) -{ - BufferMoveToLearnIntoBattleTextBuff2(); - gBattlescriptCurrInstr++; -} - -static void atk72_jump_if_can_run_frombattle(void) -{ - if (CanRunFromBattle(gBank1)) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; -} - -static void atk73_hp_thresholds(void) -{ - u8 opposingBank; - s32 result; - - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - opposingBank = gActiveBank ^ BIT_SIDE; - - result = gBattleMons[opposingBank].hp * 100 / gBattleMons[opposingBank].maxHP; - if (result == 0) - result = 1; - - if (result > 69 || !gBattleMons[opposingBank].hp) - gBattleStruct->hpScale = 0; - else if (result > 39) - gBattleStruct->hpScale = 1; - else if (result > 9) - gBattleStruct->hpScale = 2; - else - gBattleStruct->hpScale = 3; - } - - gBattlescriptCurrInstr += 2; -} - -static void atk74_hp_thresholds2(void) -{ - u8 opposingBank; - s32 result; - u8 hpSwitchout; - - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - opposingBank = gActiveBank ^ BIT_SIDE; - hpSwitchout = *(gBattleStruct->hpOnSwitchout + GetBankSide(opposingBank)); - result = (hpSwitchout - gBattleMons[opposingBank].hp) * 100 / hpSwitchout; - - if (gBattleMons[opposingBank].hp >= hpSwitchout) - gBattleStruct->hpScale = 0; - else if (result <= 29) - gBattleStruct->hpScale = 1; - else if (result <= 69) - gBattleStruct->hpScale = 2; - else - gBattleStruct->hpScale = 3; - } - - gBattlescriptCurrInstr += 2; -} - -static void atk75_item_effect_on_opponent(void) -{ - gBankInMenu = gBankAttacker; - ExecuteTableBasedItemEffect(&gEnemyParty[gBattlePartyID[gBankAttacker]], gLastUsedItem, gBattlePartyID[gBankAttacker], 0, 1); - - gBattlescriptCurrInstr += 1; -} - -static void atk76_various(void) -{ - u8 side; - s32 i; - - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - switch (gBattlescriptCurrInstr[2]) - { - case VARIOUS_CANCEL_MULTI_TURN_MOVES: - CancelMultiTurnMoves(gActiveBank); - break; - case VARIOUS_SET_MAGIC_COAT_TARGET: - gBankAttacker = gBankTarget; - side = GetBankSide(gBankAttacker) ^ 1; - if (gSideTimers[side].followmeTimer != 0 && gBattleMons[gSideTimers[side].followmeTarget].hp != 0) - gBankTarget = gSideTimers[side].followmeTarget; - else - gBankTarget = gActiveBank; - break; - case 2: - gBattleCommunication[0] = IsRunningFromBattleImpossible(); - break; - case VARIOUS_GET_MOVE_TARGET: - gBankTarget = GetMoveTarget(gCurrentMove, 0); - break; - case 4: - if (gHitMarker & HITMARKER_FAINTED(gActiveBank)) - gBattleCommunication[0] = 1; - else - gBattleCommunication[0] = 0; - break; - case VARIOUS_RESET_INTIMIDATE_TRACE_BITS: - gSpecialStatuses[gActiveBank].intimidatedPoke = 0; - gSpecialStatuses[gActiveBank].traced = 0; - break; - case VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP: - if (gBattlePartyID[0] == gBattleStruct->expGetterId || gBattlePartyID[2] == gBattleStruct->expGetterId) - { - u16 *choicedMove; - - if (gBattlePartyID[0] == gBattleStruct->expGetterId) - gActiveBank = 0; - else - gActiveBank = 2; - - choicedMove = &gBattleStruct->choicedMove[gActiveBank]; - - for (i = 0; i < 4; i++) - { - if (gBattleMons[gActiveBank].moves[i] == *choicedMove) - break; - } - if (i == 4) - *choicedMove = 0; - } - break; - case 7: - if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE)) - && gBattleTypeFlags & BATTLE_TYPE_TRAINER - && gBattleMons[0].hp != 0 - && gBattleMons[1].hp != 0) - { - gHitMarker &= ~(HITMARKER_x400000); - } - break; - case 8: - gBattleCommunication[0] = 0; - gBattleScripting.bank = gActiveBank = gBattleCommunication[1]; - if (!(gBattleStruct->field_92 & gBitTable[gActiveBank]) - && gBattleMons[gActiveBank].maxHP / 2 >= gBattleMons[gActiveBank].hp - && gBattleMons[gActiveBank].hp != 0 - && !(gBattleMons[gActiveBank].status1 & STATUS_SLEEP)) - { - gBattleStruct->field_92 |= gBitTable[gActiveBank]; - gBattleCommunication[0] = 1; - gBattleCommunication[MULTISTRING_CHOOSER] = sUnknown_0831C4F8[GetNatureFromPersonality(gBattleMons[gActiveBank].personality)]; - } - break; - case 9: - i = sub_81A5258(gBattleCommunication); - if (i == 0) - return; - - gBattleCommunication[1] = i; - break; - case 10: - gBattleMons[1].hp = 0; - gHitMarker |= HITMARKER_FAINTED(1); - gBattleStruct->field_2A1 |= gBitTable[gBattlePartyID[1]]; - gDisableStructs[1].truantUnknownBit = 1; - break; - case 11: - gBattleMons[0].hp = 0; - gHitMarker |= HITMARKER_FAINTED(0); - gHitMarker |= HITMARKER_x400000; - gBattleStruct->field_2A0 |= gBitTable[gBattlePartyID[0]]; - gDisableStructs[0].truantUnknownBit = 1; - break; - case 12: - gBattleMons[0].hp = 0; - gBattleMons[1].hp = 0; - gHitMarker |= HITMARKER_FAINTED(0); - gHitMarker |= HITMARKER_FAINTED(1); - gHitMarker |= HITMARKER_x400000; - gBattleStruct->field_2A0 |= gBitTable[gBattlePartyID[0]]; - gBattleStruct->field_2A1 |= gBitTable[gBattlePartyID[1]]; - gDisableStructs[0].truantUnknownBit = 1; - gDisableStructs[1].truantUnknownBit = 1; - break; - case 13: - EmitCmd13(0); - MarkBufferBankForExecution(gActiveBank); - break; - case 14: - sub_81A5BF8(); - break; - case 15: - sub_81A5D44(); - break; - case 16: - BattleStringExpandPlaceholdersToDisplayedString(gRefereeStringsTable[gBattlescriptCurrInstr[1]]); - sub_814F9EC(gDisplayedStringBattle, 0x16); - break; - case 17: - if (IsTextPrinterActive(0x16)) - return; - break; - case VARIOUS_WAIT_CRY: - if (!IsCryFinished()) - return; - break; - case VARIOUS_RETURN_OPPONENT_MON1: - gActiveBank = 1; - if (gBattleMons[gActiveBank].hp != 0) - { - EmitReturnPokeToBall(0, 0); - MarkBufferBankForExecution(gActiveBank); - } - break; - case VARIOUS_RETURN_OPPONENT_MON2: - if (gNoOfAllBanks > 3) - { - gActiveBank = 3; - if (gBattleMons[gActiveBank].hp != 0) - { - EmitReturnPokeToBall(0, 0); - MarkBufferBankForExecution(gActiveBank); - } - } - break; - case 21: - m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x55); - break; - case 22: - m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); - break; - case 23: - gBattleStruct->field_2A2 |= gBitTable[gActiveBank]; - break; - case 24: - if (sub_805725C(gActiveBank)) - return; - break; - case VARIOUS_SET_TELEPORT_OUTCOME: - if (GetBankSide(gActiveBank) == SIDE_PLAYER) - gBattleOutcome = BATTLE_PLAYER_TELEPORTED; - else - gBattleOutcome = BATTLE_OPPONENT_TELEPORTED; - break; - case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC: - EmitPlaySound(0, 0x19C, 1); - MarkBufferBankForExecution(gActiveBank); - break; - } - - gBattlescriptCurrInstr += 3; -} - -static void atk77_set_protect_like(void) // protect and endure -{ - bool8 notLastTurn = TRUE; - u16 lastMove = gUnknown_02024260[gBankAttacker]; - - if (lastMove != MOVE_PROTECT && lastMove != MOVE_DETECT && lastMove != MOVE_ENDURE) - gDisableStructs[gBankAttacker].protectUses = 0; - - if (gCurrentMoveTurn == (gNoOfAllBanks - 1)) - notLastTurn = FALSE; - - if (sProtectSuccessRates[gDisableStructs[gBankAttacker].protectUses] >= Random() && notLastTurn) - { - if (gBattleMoves[gCurrentMove].effect == EFFECT_PROTECT) - { - gProtectStructs[gBankAttacker].protected = 1; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - if (gBattleMoves[gCurrentMove].effect == EFFECT_ENDURE) - { - gProtectStructs[gBankAttacker].endured = 1; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - gDisableStructs[gBankAttacker].protectUses++; - } - else - { - gDisableStructs[gBankAttacker].protectUses = 0; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - gBattleMoveFlags |= MOVESTATUS_MISSED; - } - - gBattlescriptCurrInstr++; -} - -static void atk78_faintifabilitynotdamp(void) -{ - if (gBattleExecBuffer) - return; - - for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) - { - if (gBattleMons[gBankTarget].ability == ABILITY_DAMP) - break; - } - - if (gBankTarget == gNoOfAllBanks) - { - gActiveBank = gBankAttacker; - gBattleMoveDamage = gBattleMons[gActiveBank].hp; - EmitHealthBarUpdate(0, 0x7FFF); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr++; - - for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) - { - if (gBankTarget == gBankAttacker) - continue; - if (!(gAbsentBankFlags & gBitTable[gBankTarget])) - break; - } - } - else - { - gLastUsedAbility = ABILITY_DAMP; - RecordAbilityBattle(gBankTarget, gBattleMons[gBankTarget].ability); - gBattlescriptCurrInstr = BattleScript_DampStopsExplosion; - } -} - -static void atk79_setatkhptozero(void) -{ - if (gBattleExecBuffer) - return; - - gActiveBank = gBankAttacker; - gBattleMons[gActiveBank].hp = 0; - EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBank].hp); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr++; -} - -static void atk7A_jumpwhiletargetvalid(void) // Used by intimidate to loop through all targets. -{ - const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - for (gBankTarget++; ; gBankTarget++) - { - if (gBankTarget == gBankAttacker) - continue; - if (!(gAbsentBankFlags & gBitTable[gBankTarget])) - break; - } - - if (gBankTarget >= gNoOfAllBanks) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = jumpPtr; - } - else - gBattlescriptCurrInstr += 5; -} - -static void atk7B_healhalfHP_if_possible(void) -{ - const u8* failPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - - if (gBattlescriptCurrInstr[5] == BS_GET_ATTACKER) - gBankTarget = gBankAttacker; - - gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - - if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) - gBattlescriptCurrInstr = failPtr; - else - gBattlescriptCurrInstr += 6; -} - -static void atk7C_trymirrormove(void) -{ - s32 validMovesCount; - s32 i; - u16 move; - u16 movesArray[4]; - - for (i = 0; i < 3; i++) - movesArray[i] = 0; - - for (validMovesCount = 0, i = 0; i < gNoOfAllBanks; i++) - { - if (i != gBankAttacker) - { - move = *(i * 2 + gBankAttacker * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 0) - | (*(i * 2 + gBankAttacker * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 1) << 8); - - if (move != 0 && move != 0xFFFF) - { - movesArray[validMovesCount] = move; - validMovesCount++; - } - } - } - - move = *(gBattleStruct->mirrorMoves + gBankAttacker * 2 + 0) - | (*(gBattleStruct->mirrorMoves + gBankAttacker * 2 + 1) << 8); - - if (move != 0 && move != 0xFFFF) - { - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gCurrentMove = move; - gBankTarget = GetMoveTarget(gCurrentMove, 0); - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; - } - else if (validMovesCount) - { - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - i = Random() % validMovesCount; - gCurrentMove = movesArray[i]; - gBankTarget = GetMoveTarget(gCurrentMove, 0); - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; - } - else - { - gSpecialStatuses[gBankAttacker].flag20 = 1; - gBattlescriptCurrInstr++; - } -} - -static void atk7D_set_rain(void) -{ - if (gBattleWeather & WEATHER_RAIN_ANY) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else - { - gBattleWeather = WEATHER_RAIN_TEMPORARY; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - gWishFutureKnock.weatherDuration = 5; - } - gBattlescriptCurrInstr++; -} - -static void atk7E_setreflect(void) -{ - if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_REFLECT) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else - { - gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_REFLECT; - gSideTimers[GET_BANK_SIDE(gBankAttacker)].reflectTimer = 5; - gSideTimers[GET_BANK_SIDE(gBankAttacker)].reflectBank = gBankAttacker; - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_ATK_SIDE) == 2) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - gBattlescriptCurrInstr++; -} - -static void atk7F_setseeded(void) -{ - if (gBattleMoveFlags & MOVESTATUS_NOEFFECT || gStatuses3[gBankTarget] & STATUS3_LEECHSEED) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else if (gBattleMons[gBankTarget].type1 == TYPE_GRASS || gBattleMons[gBankTarget].type2 == TYPE_GRASS) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else - { - gStatuses3[gBankTarget] |= gBankAttacker; - gStatuses3[gBankTarget] |= STATUS3_LEECHSEED; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - - gBattlescriptCurrInstr++; -} - -static void atk80_manipulatedamage(void) -{ - switch (gBattlescriptCurrInstr[1]) - { - case ATK80_DMG_CHANGE_SIGN: - gBattleMoveDamage *= -1; - break; - case ATK80_DMG_HALF_BY_TWO_NOT_MORE_THAN_HALF_MAX_HP: - gBattleMoveDamage /= 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - if ((gBattleMons[gBankTarget].maxHP / 2) < gBattleMoveDamage) - gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; - break; - case ATK80_DMG_DOUBLED: - gBattleMoveDamage *= 2; - break; - } - - gBattlescriptCurrInstr += 2; -} - -static void atk81_setrest(void) -{ - const u8* failJump = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - gActiveBank = gBankTarget = gBankAttacker; - gBattleMoveDamage = gBattleMons[gBankTarget].maxHP * (-1); - - if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) - { - gBattlescriptCurrInstr = failJump; - } - else - { - if (gBattleMons[gBankTarget].status1 & ((u8)(~STATUS_SLEEP))) - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - - gBattleMons[gBankTarget].status1 = 3; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 5; - } -} - -static void atk82_jumpifnotfirstturn(void) -{ - const u8* failJump = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - - if (gDisableStructs[gBankAttacker].isFirstTurn) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = failJump; -} - -static void atk83_nop(void) -{ - gBattlescriptCurrInstr++; -} - -bool8 UproarWakeUpCheck(u8 bank) -{ - s32 i; - - for (i = 0; i < gNoOfAllBanks; i++) - { - if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || gBattleMons[bank].ability == ABILITY_SOUNDPROOF) - continue; - - gBattleScripting.bank = i; - - if (gBankTarget == 0xFF) - gBankTarget = i; - else if (gBankTarget == i) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - - break; - } - - if (i == gNoOfAllBanks) - return FALSE; - else - return TRUE; -} - -static void atk84_jump_if_cant_sleep(void) -{ - const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - - if (UproarWakeUpCheck(gBankTarget)) - { - gBattlescriptCurrInstr = jumpPtr; - } - else if (gBattleMons[gBankTarget].ability == ABILITY_INSOMNIA - || gBattleMons[gBankTarget].ability == ABILITY_VITAL_SPIRIT) - { - gLastUsedAbility = gBattleMons[gBankTarget].ability; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - gBattlescriptCurrInstr = jumpPtr; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - else - { - gBattlescriptCurrInstr += 5; - } -} - -static void atk85_stockpile(void) -{ - if (gDisableStructs[gBankAttacker].stockpileCounter == 3) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - gDisableStructs[gBankAttacker].stockpileCounter++; - - PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 1, gDisableStructs[gBankAttacker].stockpileCounter) - - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - gBattlescriptCurrInstr++; -} - -static void atk86_stockpiletobasedamage(void) -{ - const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - if (gDisableStructs[gBankAttacker].stockpileCounter == 0) - { - gBattlescriptCurrInstr = jumpPtr; - } - else - { - if (gBattleCommunication[6] != 1) - { - gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, - gSideAffecting[GET_BANK_SIDE(gBankTarget)], 0, - 0, gBankAttacker, gBankTarget) - * gDisableStructs[gBankAttacker].stockpileCounter; - gBattleScripting.animTurn = gDisableStructs[gBankAttacker].stockpileCounter; - - if (gProtectStructs[gBankAttacker].helpingHand) - gBattleMoveDamage = gBattleMoveDamage * 15 / 10; - } - - gDisableStructs[gBankAttacker].stockpileCounter = 0; - gBattlescriptCurrInstr += 5; - } -} - -static void atk87_stockpiletohpheal(void) -{ - const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - - if (gDisableStructs[gBankAttacker].stockpileCounter == 0) - { - gBattlescriptCurrInstr = jumpPtr; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else if (gBattleMons[gBankAttacker].maxHP == gBattleMons[gBankAttacker].hp) - { - gDisableStructs[gBankAttacker].stockpileCounter = 0; - gBattlescriptCurrInstr = jumpPtr; - gBankTarget = gBankAttacker; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / (1 << (3 - gDisableStructs[gBankAttacker].stockpileCounter)); - - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - - gBattleScripting.animTurn = gDisableStructs[gBankAttacker].stockpileCounter; - gDisableStructs[gBankAttacker].stockpileCounter = 0; - gBattlescriptCurrInstr += 5; - gBankTarget = gBankAttacker; - } -} - -static void atk88_negativedamage(void) -{ - gBattleMoveDamage = -(gHpDealt / 2); - if (gBattleMoveDamage == 0) - gBattleMoveDamage = -1; - - gBattlescriptCurrInstr++; -} - -static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8* BS_ptr) -{ - bool8 certain = 0; - bool8 notProtectAffected = FALSE; - u32 index; - - if (flags & MOVE_EFFECT_AFFECTS_USER) - gActiveBank = gBankAttacker; - else - gActiveBank = gBankTarget; - - flags &= ~(MOVE_EFFECT_AFFECTS_USER); - - if (flags & MOVE_EFFECT_CERTAIN) - certain++; - flags &= ~(MOVE_EFFECT_CERTAIN); - - if (flags & STAT_CHANGE_NOT_PROTECT_AFFECTED) - notProtectAffected++; - flags &= ~(STAT_CHANGE_NOT_PROTECT_AFFECTED); - - PREPARE_STAT_BUFFER(gBattleTextBuff1, statId) - - if ((statValue << 0x18) < 0) // stat decrease - { - if (gSideTimers[GET_BANK_SIDE(gActiveBank)].mistTimer - && !certain && gCurrentMove != MOVE_CURSE) - { - if (flags == STAT_CHANGE_BS_PTR) - { - if (gSpecialStatuses[gActiveBank].statLowered) - { - gBattlescriptCurrInstr = BS_ptr; - } - else - { - BattleScriptPush(BS_ptr); - gBattleScripting.bank = gActiveBank; - gBattlescriptCurrInstr = BattleScript_MistProtected; - gSpecialStatuses[gActiveBank].statLowered = 1; - } - } - return STAT_CHANGE_DIDNT_WORK; - } - else if (gCurrentMove != MOVE_CURSE - && notProtectAffected != TRUE && JumpIfMoveAffectedByProtect(0)) - { - gBattlescriptCurrInstr = BattleScript_ButItFailed; - return STAT_CHANGE_DIDNT_WORK; - } - else if ((gBattleMons[gActiveBank].ability == ABILITY_CLEAR_BODY - || gBattleMons[gActiveBank].ability == ABILITY_WHITE_SMOKE) - && !certain && gCurrentMove != MOVE_CURSE) - { - if (flags == STAT_CHANGE_BS_PTR) - { - if (gSpecialStatuses[gActiveBank].statLowered) - { - gBattlescriptCurrInstr = BS_ptr; - } - else - { - BattleScriptPush(BS_ptr); - gBattleScripting.bank = gActiveBank; - gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss; - gLastUsedAbility = gBattleMons[gActiveBank].ability; - RecordAbilityBattle(gActiveBank, gLastUsedAbility); - gSpecialStatuses[gActiveBank].statLowered = 1; - } - } - return STAT_CHANGE_DIDNT_WORK; - } - else if (gBattleMons[gActiveBank].ability == ABILITY_KEEN_EYE - && !certain && statId == STAT_STAGE_ACC) - { - if (flags == STAT_CHANGE_BS_PTR) - { - BattleScriptPush(BS_ptr); - gBattleScripting.bank = gActiveBank; - gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; - gLastUsedAbility = gBattleMons[gActiveBank].ability; - RecordAbilityBattle(gActiveBank, gLastUsedAbility); - } - return STAT_CHANGE_DIDNT_WORK; - } - else if (gBattleMons[gActiveBank].ability == ABILITY_HYPER_CUTTER - && !certain && statId == STAT_STAGE_ATK) - { - if (flags == STAT_CHANGE_BS_PTR) - { - BattleScriptPush(BS_ptr); - gBattleScripting.bank = gActiveBank; - gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; - gLastUsedAbility = gBattleMons[gActiveBank].ability; - RecordAbilityBattle(gActiveBank, gLastUsedAbility); - } - return STAT_CHANGE_DIDNT_WORK; - } - else if (gBattleMons[gActiveBank].ability == ABILITY_SHIELD_DUST && flags == 0) - { - return STAT_CHANGE_DIDNT_WORK; - } - else // try to decrease - { - statValue = -GET_STAT_BUFF_VALUE(statValue); - gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; - index = 1; - if (statValue == -2) - { - gBattleTextBuff2[1] = B_BUFF_STRING; - gBattleTextBuff2[2] = 0xD3; // harshly - gBattleTextBuff2[3] = 0xD3 >> 8; - index = 4; - } - gBattleTextBuff2[index] = B_BUFF_STRING; - index++; - gBattleTextBuff2[index] = 0xD4; // fell - index++; - gBattleTextBuff2[index] = 0xD4 >> 8; - index++; - gBattleTextBuff2[index] = B_BUFF_EOS; - - if (gBattleMons[gActiveBank].statStages[statId] == 0) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - else - gBattleCommunication[MULTISTRING_CHOOSER] = (gBankTarget == gActiveBank); - - } - } - else // stat increase - { - statValue = GET_STAT_BUFF_VALUE(statValue); - gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; - index = 1; - if (statValue == 2) - { - gBattleTextBuff2[1] = B_BUFF_STRING; - gBattleTextBuff2[2] = 0xD1; // sharply - gBattleTextBuff2[3] = 0xD1 >> 8; - index = 4; - } - gBattleTextBuff2[index] = B_BUFF_STRING; - index++; - gBattleTextBuff2[index] = 0xD2; // rose - index++; - gBattleTextBuff2[index] = 0xD2 >> 8; - index++; - gBattleTextBuff2[index] = B_BUFF_EOS; - - if (gBattleMons[gActiveBank].statStages[statId] == 0xC) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - else - gBattleCommunication[MULTISTRING_CHOOSER] = (gBankTarget == gActiveBank); - } - - gBattleMons[gActiveBank].statStages[statId] += statValue; - if (gBattleMons[gActiveBank].statStages[statId] < 0) - gBattleMons[gActiveBank].statStages[statId] = 0; - if (gBattleMons[gActiveBank].statStages[statId] > 0xC) - gBattleMons[gActiveBank].statStages[statId] = 0xC; - - if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && flags & STAT_CHANGE_BS_PTR) - gBattleMoveFlags |= MOVESTATUS_MISSED; - - if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && !(flags & STAT_CHANGE_BS_PTR)) - return STAT_CHANGE_DIDNT_WORK; - - return STAT_CHANGE_WORKED; -} - -static void atk89_statbuffchange(void) -{ - const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - if (ChangeStatBuffs(gBattleScripting.statChanger & 0xF0, GET_STAT_BUFF_ID(gBattleScripting.statChanger), gBattlescriptCurrInstr[1], jumpPtr) == STAT_CHANGE_WORKED) - gBattlescriptCurrInstr += 6; -} - -static void atk8A_normalisebuffs(void) // haze -{ - s32 i, j; - - for (i = 0; i < gNoOfAllBanks; i++) - { - for (j = 0; j < BATTLE_STATS_NO; j++) - gBattleMons[i].statStages[j] = 6; - } - - gBattlescriptCurrInstr++; -} - -static void atk8B_setbide(void) -{ - gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gBankAttacker] = gCurrentMove; - gTakenDmg[gBankAttacker] = 0; - gBattleMons[gBankAttacker].status2 |= (STATUS2_BIDE - 0x100); // 2 turns - - gBattlescriptCurrInstr++; -} - -static void atk8C_confuseifrepeatingattackends(void) -{ - if (!(gBattleMons[gBankAttacker].status2 & STATUS2_LOCK_CONFUSE)) - gBattleCommunication[MOVE_EFFECT_BYTE] = (MOVE_EFFECT_THRASH | MOVE_EFFECT_AFFECTS_USER); - - gBattlescriptCurrInstr++; -} - -static void atk8D_setmultihit_counter(void) -{ - if (gBattlescriptCurrInstr[1]) - { - gMultiHitCounter = gBattlescriptCurrInstr[1]; - } - else - { - gMultiHitCounter = Random() & 3; - if (gMultiHitCounter > 1) - gMultiHitCounter = (Random() & 3) + 2; - else - gMultiHitCounter += 2; - } - - gBattlescriptCurrInstr += 2; -} - -static void atk8E_init_multihit_string(void) -{ - PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) - - gBattlescriptCurrInstr++; -} - -static bool8 sub_8051064(void) -{ - if (gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) - { - *(gBattleStruct->field_58 + gBankTarget) = gBattlePartyID[gBankTarget]; - } - else - { - u16 random = Random() & 0xFF; - if ((u32)((random * (gBattleMons[gBankAttacker].level + gBattleMons[gBankTarget].level) >> 8) + 1) <= (gBattleMons[gBankTarget].level / 4)) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - return FALSE; - } - *(gBattleStruct->field_58 + gBankTarget) = gBattlePartyID[gBankTarget]; - } - - gBattlescriptCurrInstr = gUnknown_082DADD8; - return TRUE; -} - -static void atk8F_forcerandomswitch(void) -{ - s32 i; - s32 bank1PartyId = 0; - s32 bank2PartyId = 0; - - #ifdef NONMATCHING - s32 lastMonId = 0; // + 1 - #else - register s32 lastMonId asm("r8") = 0; // + 1 - #endif // NONMATCHING - - s32 firstMonId = 0; - s32 monsCount = 0; - struct Pokemon* party = NULL; - s32 validMons = 0; - s32 minNeeded = 0; - - if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER)) - { - if (GetBankSide(gBankTarget) == SIDE_PLAYER) - party = gPlayerParty; - else - party = gEnemyParty; - - if ((gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_LINK) - || (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_x2000000) - || (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)) - { - if ((gBankTarget & BIT_MON) != 0) - { - firstMonId = 3; - lastMonId = 6; - } - else - { - firstMonId = 0; - lastMonId = 3; - } - monsCount = 3; - minNeeded = 1; - bank2PartyId = gBattlePartyID[gBankTarget]; - bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; - } - else if ((gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK) - || (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_x2000000)) - { - if (sub_806D82C(sub_806D864(gBankTarget)) == 1) - { - firstMonId = 3; - lastMonId = 6; - } - else - { - firstMonId = 0; - lastMonId = 3; - } - monsCount = 3; - minNeeded = 1; - bank2PartyId = gBattlePartyID[gBankTarget]; - bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; - } - else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) - { - if (GetBankSide(gBankTarget) == SIDE_PLAYER) - { - firstMonId = 0; - lastMonId = 6; - monsCount = 6; - minNeeded = 2; // since there are two opponents, it has to be a double battle - } - else - { - if ((gBankTarget & BIT_MON) != 0) - { - firstMonId = 3; - lastMonId = 6; - } - else - { - firstMonId = 0; - lastMonId = 3; - } - monsCount = 3; - minNeeded = 1; - } - bank2PartyId = gBattlePartyID[gBankTarget]; - bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; - } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - firstMonId = 0; - lastMonId = 6; - monsCount = 6; - minNeeded = 2; - bank2PartyId = gBattlePartyID[gBankTarget]; - bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; - } - else - { - firstMonId = 0; - lastMonId = 6; - monsCount = 6; - minNeeded = 1; - bank2PartyId = gBattlePartyID[gBankTarget]; // there is only one pokemon out in single battles - bank1PartyId = gBattlePartyID[gBankTarget]; - } - - for (i = firstMonId; i < lastMonId; i++) - { - if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&party[i], MON_DATA_IS_EGG) - && GetMonData(&party[i], MON_DATA_HP) != 0) - { - validMons++; - } - } - - if (validMons <= minNeeded) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - if (sub_8051064()) - { - do - { - i = Random() % monsCount; - i += firstMonId; - } - while (i == bank2PartyId - || i == bank1PartyId - || GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_NONE - || GetMonData(&party[i], MON_DATA_IS_EGG) == TRUE - || GetMonData(&party[i], MON_DATA_HP) == 0); - } - *(gBattleStruct->field_5C + gBankTarget) = i; - - if (!sub_81B1250()) - sub_803BDA0(gBankTarget); - - if ((gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) - || (gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_MULTI) - || (gBattleTypeFlags & BATTLE_TYPE_x2000000 && gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) - || (gBattleTypeFlags & BATTLE_TYPE_x2000000 && gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - sub_81B8E80(gBankTarget, i, 0); - sub_81B8E80(gBankTarget ^ BIT_MON, i, 1); - } - - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) - sub_80571DC(gBankTarget, i); - } - } - else - { - sub_8051064(); - } -} - -static void atk90_conversion_type_change(void) // randomly changes user's type to one of its moves' type -{ - u8 validMoves = 0; - u8 moveChecked; - u8 moveType; - - while (validMoves < 4) - { - if (gBattleMons[gBankAttacker].moves[validMoves] == 0) - break; - - validMoves++; - } - - for (moveChecked = 0; moveChecked < validMoves; moveChecked++) - { - moveType = gBattleMoves[gBattleMons[gBankAttacker].moves[moveChecked]].type; - - if (moveType == TYPE_MYSTERY) - { - if (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST) - moveType = TYPE_GHOST; - else - moveType = TYPE_NORMAL; - } - if (moveType != gBattleMons[gBankAttacker].type1 - && moveType != gBattleMons[gBankAttacker].type2) - { - break; - } - } - - if (moveChecked == validMoves) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - do - { - - while ((moveChecked = Random() & 3) >= validMoves); - - moveType = gBattleMoves[gBattleMons[gBankAttacker].moves[moveChecked]].type; - - if (moveType == TYPE_MYSTERY) - { - if (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST) - moveType = TYPE_GHOST; - else - moveType = TYPE_NORMAL; - } - } - while (moveType == gBattleMons[gBankAttacker].type1 || moveType == gBattleMons[gBankAttacker].type2); - - gBattleMons[gBankAttacker].type1 = moveType; - gBattleMons[gBankAttacker].type2 = moveType; - - PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType) - - gBattlescriptCurrInstr += 5; - } -} - -static void atk91_givepaydaymoney(void) -{ - if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) && gPaydayMoney != 0) - { - u32 bonusMoney = gPaydayMoney * gBattleStruct->moneyMultiplier; - AddMoney(&gSaveBlock1Ptr->money, bonusMoney); - - PREPARE_HWORD_NUMBER_BUFFER(gBattleTextBuff1, 5, bonusMoney) - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_PrintPayDayMoneyString; - } - else - { - gBattlescriptCurrInstr++; - } -} - -static void atk92_setlightscreen(void) -{ - if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_LIGHTSCREEN) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else - { - gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_LIGHTSCREEN; - gSideTimers[GET_BANK_SIDE(gBankAttacker)].lightscreenTimer = 5; - gSideTimers[GET_BANK_SIDE(gBankAttacker)].lightscreenBank = gBankAttacker; - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_ATK_SIDE) == 2) - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 3; - } - - gBattlescriptCurrInstr++; -} - -static void atk93_ko_move(void) -{ - u8 holdEffect, param; - - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - { - holdEffect = gEnigmaBerries[gBankTarget].holdEffect; - param = gEnigmaBerries[gBankTarget].holdEffectParam; - } - else - { - holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - param = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); - } - - gStringBank = gBankTarget; - - if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < param) - { - RecordItemEffectBattle(gBankTarget, HOLD_EFFECT_FOCUS_BAND); - gSpecialStatuses[gBankTarget].focusBanded = 1; - } - - if (gBattleMons[gBankTarget].ability == ABILITY_STURDY) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gLastUsedAbility = ABILITY_STURDY; - gBattlescriptCurrInstr = BattleScript_SturdyPreventsOHKO; - RecordAbilityBattle(gBankTarget, ABILITY_STURDY); - } - else - { - u16 chance; - if (!(gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS)) - { - chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBankAttacker].level - gBattleMons[gBankTarget].level); - if (Random() % 100 + 1 < chance && gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) - chance = TRUE; - else - chance = FALSE; - } - else if (gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker - && gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) - { - chance = TRUE; - } - else - { - chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBankAttacker].level - gBattleMons[gBankTarget].level); - if (Random() % 100 + 1 < chance && gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) - chance = TRUE; - else - chance = FALSE; - } - if (chance) - { - if (gProtectStructs[gBankTarget].endured) - { - gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; - gBattleMoveFlags |= MOVESTATUS_ENDURED; - } - else if (gSpecialStatuses[gBankTarget].focusBanded) - { - gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; - gBattleMoveFlags |= MOVESTATUS_HUNGON; - gLastUsedItem = gBattleMons[gBankTarget].item; - } - else - { - gBattleMoveDamage = gBattleMons[gBankTarget].hp; - gBattleMoveFlags |= MOVESTATUS_ONEHITKO; - } - gBattlescriptCurrInstr += 5; - } - else - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - if (gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - } -} - -static void atk94_damagetohalftargethp(void) // super fang -{ - gBattleMoveDamage = gBattleMons[gBankTarget].hp / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - gBattlescriptCurrInstr++; -} - -static void atk95_setsandstorm(void) -{ - if (gBattleWeather & WEATHER_SANDSTORM_ANY) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else - { - gBattleWeather = WEATHER_SANDSTORM_TEMPORARY; - gBattleCommunication[MULTISTRING_CHOOSER] = 3; - gWishFutureKnock.weatherDuration = 5; - } - gBattlescriptCurrInstr++; -} - -static void atk96_weatherdamage(void) -{ - if (WEATHER_HAS_EFFECT) - { - if (gBattleWeather & WEATHER_SANDSTORM_ANY) - { - if (gBattleMons[gBankAttacker].type1 != TYPE_ROCK - && gBattleMons[gBankAttacker].type1 != TYPE_STEEL - && gBattleMons[gBankAttacker].type1 != TYPE_GROUND - && gBattleMons[gBankAttacker].type2 != TYPE_ROCK - && gBattleMons[gBankAttacker].type2 != TYPE_STEEL - && gBattleMons[gBankAttacker].type2 != TYPE_GROUND - && gBattleMons[gBankAttacker].ability != ABILITY_SAND_VEIL - && !(gStatuses3[gBankAttacker] & STATUS3_UNDERGROUND) - && !(gStatuses3[gBankAttacker] & STATUS3_UNDERWATER)) - { - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - } - else - { - gBattleMoveDamage = 0; - } - } - if (gBattleWeather & WEATHER_HAIL) - { - if (gBattleMons[gBankAttacker].type1 != TYPE_ICE - && gBattleMons[gBankAttacker].type2 != TYPE_ICE - && !(gStatuses3[gBankAttacker] & STATUS3_UNDERGROUND) - && !(gStatuses3[gBankAttacker] & STATUS3_UNDERWATER)) - { - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - } - else - { - gBattleMoveDamage = 0; - } - } - } - else - { - gBattleMoveDamage = 0; - } - - if (gAbsentBankFlags & gBitTable[gBankAttacker]) - gBattleMoveDamage = 0; - - gBattlescriptCurrInstr++; -} - -static void atk97_try_infatuation(void) -{ - struct Pokemon *monAttacker, *monTarget; - u16 speciesAttacker, speciesTarget; - u32 personalityAttacker, personalityTarget; - - if (GetBankSide(gBankAttacker) == SIDE_PLAYER) - monAttacker = &gPlayerParty[gBattlePartyID[gBankAttacker]]; - else - monAttacker = &gEnemyParty[gBattlePartyID[gBankAttacker]]; - - if (GetBankSide(gBankTarget) == SIDE_PLAYER) - monTarget = &gPlayerParty[gBattlePartyID[gBankTarget]]; - else - monTarget = &gEnemyParty[gBattlePartyID[gBankTarget]]; - - speciesAttacker = GetMonData(monAttacker, MON_DATA_SPECIES); - personalityAttacker = GetMonData(monAttacker, MON_DATA_PERSONALITY); - - speciesTarget = GetMonData(monTarget, MON_DATA_SPECIES); - personalityTarget = GetMonData(monTarget, MON_DATA_PERSONALITY); - - if (gBattleMons[gBankTarget].ability == ABILITY_OBLIVIOUS) - { - gBattlescriptCurrInstr = BattleScript_ObliviousPreventsAttraction; - gLastUsedAbility = ABILITY_OBLIVIOUS; - RecordAbilityBattle(gBankTarget, ABILITY_OBLIVIOUS); - } - else - { - if (GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) - || gBattleMons[gBankTarget].status2 & STATUS2_INFATUATION - || GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == MON_GENDERLESS - || GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) == MON_GENDERLESS) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gBattleMons[gBankTarget].status2 |= STATUS2_INFATUATED_WITH(gBankAttacker); - gBattlescriptCurrInstr += 5; - } - } -} - -static void atk98_status_icon_update(void) -{ - if (gBattleExecBuffer) - return; - - if (gBattlescriptCurrInstr[1] != BS_ATTACKER_WITH_PARTNER) - { - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - EmitStatusIconUpdate(0, gBattleMons[gActiveBank].status1, gBattleMons[gActiveBank].status2); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 2; - } - else - { - gActiveBank = gBankAttacker; - if (!(gAbsentBankFlags & gBitTable[gActiveBank])) - { - EmitStatusIconUpdate(0, gBattleMons[gActiveBank].status1, gBattleMons[gActiveBank].status2); - MarkBufferBankForExecution(gActiveBank); - } - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - gActiveBank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); - if (!(gAbsentBankFlags & gBitTable[gActiveBank])) - { - EmitStatusIconUpdate(0, gBattleMons[gActiveBank].status1, gBattleMons[gActiveBank].status2); - MarkBufferBankForExecution(gActiveBank); - } - } - gBattlescriptCurrInstr += 2; - } -} - -static void atk99_setmist(void) -{ - if (gSideTimers[GET_BANK_SIDE(gBankAttacker)].mistTimer) - { - gBattleMoveFlags |= MOVESTATUS_FAILED; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - gSideTimers[GET_BANK_SIDE(gBankAttacker)].mistTimer = 5; - gSideTimers[GET_BANK_SIDE(gBankAttacker)].mistBank = gBankAttacker; - gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_MIST; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - gBattlescriptCurrInstr++; -} - -static void atk9A_set_focusenergy(void) -{ - if (gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) - { - gBattleMoveFlags |= MOVESTATUS_FAILED; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - gBattleMons[gBankAttacker].status2 |= STATUS2_FOCUS_ENERGY; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - gBattlescriptCurrInstr++; -} - -static void atk9B_transformdataexecution(void) -{ - gLastUsedMove = 0xFFFF; - gBattlescriptCurrInstr++; - if (gBattleMons[gBankTarget].status2 & STATUS2_TRANSFORMED - || gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE) - { - gBattleMoveFlags |= MOVESTATUS_FAILED; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - s32 i; - u8 *battleMonAttacker, *battleMonTarget; - - gBattleMons[gBankAttacker].status2 |= STATUS2_TRANSFORMED; - gDisableStructs[gBankAttacker].disabledMove = 0; - gDisableStructs[gBankAttacker].disableTimer1 = 0; - gDisableStructs[gBankAttacker].unk0 = gBattleMons[gBankTarget].personality; - gDisableStructs[gBankAttacker].unk18_b = 0; - - PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBankTarget].species) - - battleMonAttacker = (u8*)(&gBattleMons[gBankAttacker]); - battleMonTarget = (u8*)(&gBattleMons[gBankTarget]); - - for (i = 0; i < offsetof(struct BattlePokemon, pp); i++) - battleMonAttacker[i] = battleMonTarget[i]; - - for (i = 0; i < 4; i++) - { - if (gBattleMoves[gBattleMons[gBankAttacker].moves[i]].pp < 5) - gBattleMons[gBankAttacker].pp[i] = gBattleMoves[gBattleMons[gBankAttacker].moves[i]].pp; - else - gBattleMons[gBankAttacker].pp[i] = 5; - } - - gActiveBank = gBankAttacker; - EmitResetActionMoveSelection(0, RESET_MOVE_SELECTION); - MarkBufferBankForExecution(gActiveBank); - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } -} - -static void atk9C_set_substitute(void) -{ - u32 hp = gBattleMons[gBankAttacker].maxHP / 4; - if (gBattleMons[gBankAttacker].maxHP / 4 == 0) - hp = 1; - - if (gBattleMons[gBankAttacker].hp <= hp) - { - gBattleMoveDamage = 0; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4; // one bit value will only work for pokemon which max hp can go to 1020(which is more than possible in games) - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - gBattleMons[gBankAttacker].status2 |= STATUS2_SUBSTITUTE; - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_WRAPPED); - gDisableStructs[gBankAttacker].substituteHP = gBattleMoveDamage; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE; - } - - gBattlescriptCurrInstr++; -} - -static bool8 IsMoveUncopyableByMimic(u16 move) -{ - s32 i; - for (i = 0; sMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END - && sMovesForbiddenToCopy[i] != move; i++); - - return (sMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END); -} - -static void atk9D_mimicattackcopy(void) -{ - gLastUsedMove = 0xFFFF; - - if (IsMoveUncopyableByMimic(gLastUsedMovesByBanks[gBankTarget]) - || gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED - || gLastUsedMovesByBanks[gBankTarget] == 0 - || gLastUsedMovesByBanks[gBankTarget] == 0xFFFF) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - s32 i; - - for (i = 0; i < 4; i++) - { - if (gBattleMons[gBankAttacker].moves[i] == gLastUsedMovesByBanks[gBankTarget]) - break; - } - - if (i == 4) - { - gBattleMons[gBankAttacker].moves[gCurrMovePos] = gLastUsedMovesByBanks[gBankTarget]; - if (gBattleMoves[gLastUsedMovesByBanks[gBankTarget]].pp < 5) - gBattleMons[gBankAttacker].pp[gCurrMovePos] = gBattleMoves[gLastUsedMovesByBanks[gBankTarget]].pp; - else - gBattleMons[gBankAttacker].pp[gCurrMovePos] = 5; - - - PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastUsedMovesByBanks[gBankTarget]) - - gDisableStructs[gBankAttacker].unk18_b |= gBitTable[gCurrMovePos]; - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - } -} - -#ifdef NONMATCHING -static void atk9E_metronome(void) -{ - while (1) - { - const u16 *move; - s32 i, j; - - gCurrentMove = (Random() & 0x1FF) + 1; - if (gCurrentMove > LAST_MOVE_INDEX) - continue; - - for (i = 0; i < 4; i++); // ? - - for (move = sMovesForbiddenToCopy; ; move++) - { - if (*move == gCurrentMove) - break; - if (*move == METRONOME_FORBIDDEN_END) - break; - } - - if (*move == METRONOME_FORBIDDEN_END) - break; - } - - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; - gBankTarget = GetMoveTarget(gCurrentMove, 0); -} - -#else -__attribute__((naked)) -static void atk9E_metronome(void) -{ - asm( - "\n\ - .syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r8\n\ - push {r7}\n\ - ldr r7, =gCurrentMove\n\ - movs r6, 0xB1\n\ - lsls r6, 1\n\ - ldr r5, =sMovesForbiddenToCopy\n\ - ldr r0, =gBattlescriptCurrInstr\n\ - mov r8, r0\n\ -_080524EE:\n\ - bl Random\n\ - ldr r2, =0x000001ff\n\ - adds r1, r2, 0\n\ - ands r0, r1\n\ - adds r0, 0x1\n\ - strh r0, [r7]\n\ - cmp r0, r6\n\ - bhi _080524EE\n\ - movs r0, 0x3\n\ -_08052502:\n\ - subs r0, 0x1\n\ - cmp r0, 0\n\ - bge _08052502\n\ - ldr r4, =gCurrentMove\n\ - ldrh r2, [r4]\n\ - ldr r3, =0x0000ffff\n\ - subs r0, r5, 0x2\n\ -_08052510:\n\ - adds r0, 0x2\n\ - ldrh r1, [r0]\n\ - cmp r1, r2\n\ - beq _0805251C\n\ - cmp r1, r3\n\ - bne _08052510\n\ -_0805251C:\n\ - ldr r0, =0x0000ffff\n\ - cmp r1, r0\n\ - bne _080524EE\n\ - ldr r2, =gHitMarker\n\ - ldr r0, [r2]\n\ - ldr r1, =0xfffffbff\n\ - ands r0, r1\n\ - str r0, [r2]\n\ - ldr r3, =gBattleScriptsForMoveEffects\n\ - ldr r2, =gBattleMoves\n\ - ldrh r1, [r4]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r0, [r0]\n\ - lsls r0, 2\n\ - adds r0, r3\n\ - ldr r0, [r0]\n\ - mov r1, r8\n\ - str r0, [r1]\n\ - ldrh r0, [r4]\n\ - movs r1, 0\n\ - bl GetMoveTarget\n\ - ldr r1, =gBankTarget\n\ - strb r0, [r1]\n\ - pop {r3}\n\ - mov r8, r3\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .pool\n\ - .syntax divided"); -} - -#endif // NONMATCHING - -static void atk9F_dmgtolevel(void) -{ - gBattleMoveDamage = gBattleMons[gBankAttacker].level; - gBattlescriptCurrInstr++; -} - -static void atkA0_psywavedamageeffect(void) -{ - s32 randDamage; - - while ((randDamage = (Random() & 0xF)) > 10); - - randDamage *= 10; - gBattleMoveDamage = gBattleMons[gBankAttacker].level * (randDamage + 50) / 100; - gBattlescriptCurrInstr++; -} - -static void atkA1_counterdamagecalculator(void) -{ - u8 sideAttacker = GetBankSide(gBankAttacker); - u8 sideTarget = GetBankSide(gProtectStructs[gBankAttacker].physicalBank); - - if (gProtectStructs[gBankAttacker].physicalDmg - && sideAttacker != sideTarget - && gBattleMons[gProtectStructs[gBankAttacker].physicalBank].hp) - { - gBattleMoveDamage = gProtectStructs[gBankAttacker].physicalDmg * 2; - - if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp) - gBankTarget = gSideTimers[sideTarget].followmeTarget; - else - gBankTarget = gProtectStructs[gBankAttacker].physicalBank; - - gBattlescriptCurrInstr += 5; - } - else - { - gSpecialStatuses[gBankAttacker].flag20 = 1; - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkA2_mirrorcoatdamagecalculator(void) // a copy of atkA1 with the physical -> special field changes -{ - u8 sideAttacker = GetBankSide(gBankAttacker); - u8 sideTarget = GetBankSide(gProtectStructs[gBankAttacker].specialBank); - - if (gProtectStructs[gBankAttacker].specialDmg && sideAttacker != sideTarget && gBattleMons[gProtectStructs[gBankAttacker].specialBank].hp) - { - gBattleMoveDamage = gProtectStructs[gBankAttacker].specialDmg * 2; - - if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp) - gBankTarget = gSideTimers[sideTarget].followmeTarget; - else - gBankTarget = gProtectStructs[gBankAttacker].specialBank; - - gBattlescriptCurrInstr += 5; - } - else - { - gSpecialStatuses[gBankAttacker].flag20 = 1; - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkA3_disablelastusedattack(void) -{ - s32 i; - - for (i = 0; i < 4; i++) - { - if (gBattleMons[gBankTarget].moves[i] == gLastUsedMovesByBanks[gBankTarget]) - break; - } - if (gDisableStructs[gBankTarget].disabledMove == 0 - && i != 4 && gBattleMons[gBankTarget].pp[i] != 0) - { - PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBankTarget].moves[i]) - - gDisableStructs[gBankTarget].disabledMove = gBattleMons[gBankTarget].moves[i]; - gDisableStructs[gBankTarget].disableTimer1 = (Random() & 3) + 2; - gDisableStructs[gBankTarget].disableTimer2 = gDisableStructs[gBankTarget].disableTimer1; // used to save the random amount of turns? - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkA4_setencore(void) -{ - s32 i; - - for (i = 0; i < 4; i++) - { - if (gBattleMons[gBankTarget].moves[i] == gLastUsedMovesByBanks[gBankTarget]) - break; - } - - if (gLastUsedMovesByBanks[gBankTarget] == MOVE_STRUGGLE - || gLastUsedMovesByBanks[gBankTarget] == MOVE_ENCORE - || gLastUsedMovesByBanks[gBankTarget] == MOVE_MIRROR_MOVE) - { - i = 4; - } - - if (gDisableStructs[gBankTarget].encoredMove == 0 - && i != 4 && gBattleMons[gBankTarget].pp[i] != 0) - { - gDisableStructs[gBankTarget].encoredMove = gBattleMons[gBankTarget].moves[i]; - gDisableStructs[gBankTarget].encoredMovePos = i; - gDisableStructs[gBankTarget].encoreTimer1 = (Random() & 3) + 3; - gDisableStructs[gBankTarget].encoreTimer2 = gDisableStructs[gBankTarget].encoreTimer1; - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkA5_painsplitdmgcalc(void) -{ - if (!(gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE)) - { - s32 hpDiff = (gBattleMons[gBankAttacker].hp + gBattleMons[gBankTarget].hp) / 2; - s32 painSplitHp = gBattleMoveDamage = gBattleMons[gBankTarget].hp - hpDiff; - u8* storeLoc = (void*)(&gBattleScripting.painSplitHp); - - storeLoc[0] = (painSplitHp); - storeLoc[1] = (painSplitHp & 0x0000FF00) >> 8; - storeLoc[2] = (painSplitHp & 0x00FF0000) >> 16; - storeLoc[3] = (painSplitHp & 0xFF000000) >> 24; - - gBattleMoveDamage = gBattleMons[gBankAttacker].hp - hpDiff; - gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF; - - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -#ifdef NONMATCHING -static void atkA6_settypetorandomresistance(void) // conversion 2 -{ - if (gUnknown_02024250[gBankAttacker] == 0 - || gUnknown_02024250[gBankAttacker] == 0xFFFF) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else if (IsTwoTurnsMove(gUnknown_02024250[gBankAttacker]) - && gBattleMons[gUnknown_02024270[gBankAttacker]].status2 & STATUS2_MULTIPLETURNS) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - s32 type = 0, rands = 0; - do - { - while (((type = (Random() & 0x7F)) > 0x70)); - - type *= 3; - - if (gTypeEffectiveness[type] == gUnknown_02024258[gBankAttacker] - && gTypeEffectiveness[type + 2] <= 5 - && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1] - && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1]) - { - gBattleMons[gBankAttacker].type1 = type; - gBattleMons[gBankAttacker].type2 = type; - - PREPARE_TYPE_BUFFER(gBattleTextBuff1, type) - - gBattlescriptCurrInstr += 5; - return; - } - - rands++; - } while (rands <= 999); - - type = 0, rands = 0; - do - { - s8 var = (s8)(gTypeEffectiveness[type]); - if (var > -1 || var < -2) - { - if (gTypeEffectiveness[type] == gUnknown_02024258[gBankAttacker] - && gTypeEffectiveness[type + 2] <= 5 - && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1] - && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1]) - { - gBattleMons[gBankAttacker].type1 = gTypeEffectiveness[rands + 1]; - gBattleMons[gBankAttacker].type2 = gTypeEffectiveness[rands + 1]; - - PREPARE_TYPE_BUFFER(gBattleTextBuff1, gTypeEffectiveness[rands + 1]) - - gBattlescriptCurrInstr += 5; - return; - } - } - type += 3, rands += 3; - } while (rands < 336); - - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -#else -__attribute__((naked)) -static void atkA6_settypetorandomresistance(void) // conversion 2 -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - ldr r1, =gUnknown_02024250\n\ - ldr r4, =gBankAttacker\n\ - ldrb r0, [r4]\n\ - lsls r0, 1\n\ - adds r2, r0, r1\n\ - ldrh r1, [r2]\n\ - cmp r1, 0\n\ - beq _08052B7E\n\ - ldr r0, =0x0000ffff\n\ - cmp r1, r0\n\ - beq _08052B7E\n\ - ldrh r0, [r2]\n\ - bl IsTwoTurnsMove\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08052C1C\n\ - ldr r1, =gBattleMons\n\ - ldr r2, =gUnknown_02024270\n\ - ldrb r0, [r4]\n\ - adds r0, r2\n\ - ldrb r2, [r0]\n\ - movs r0, 0x58\n\ - muls r0, r2\n\ - adds r1, 0x50\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 5\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08052C1C\n\ -_08052B7E:\n\ - ldr r3, =gBattlescriptCurrInstr\n\ - ldr r2, [r3]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - lsls r0, 24\n\ - orrs r1, r0\n\ - str r1, [r3]\n\ - b _08052D08\n\ - .pool\n\ -_08052BB4:\n\ - mov r0, r12\n\ - strb r5, [r0]\n\ - mov r1, r10\n\ - ldrb r0, [r1]\n\ - muls r0, r2\n\ - adds r0, r7\n\ - adds r0, 0x22\n\ - strb r5, [r0]\n\ - ldr r1, =gBattleTextBuff1\n\ - movs r0, 0xFD\n\ - strb r0, [r1]\n\ - movs r0, 0x3\n\ - strb r0, [r1, 0x1]\n\ - strb r5, [r1, 0x2]\n\ - movs r0, 0xFF\n\ - strb r0, [r1, 0x3]\n\ - ldr r1, =gBattlescriptCurrInstr\n\ - b _08052C0A\n\ - .pool\n\ -_08052BE0:\n\ - mov r0, r8\n\ - adds r0, 0x1\n\ - adds r0, r3\n\ - ldrb r2, [r0]\n\ - strb r2, [r4]\n\ - mov r4, r10\n\ - ldrb r0, [r4]\n\ - muls r0, r6\n\ - ldr r7, =gBattleMons\n\ - adds r0, r7\n\ - adds r0, 0x22\n\ - strb r2, [r0]\n\ - ldr r1, =gBattleTextBuff1\n\ - movs r0, 0xFD\n\ - strb r0, [r1]\n\ - movs r0, 0x3\n\ - strb r0, [r1, 0x1]\n\ - strb r2, [r1, 0x2]\n\ - movs r0, 0xFF\n\ - strb r0, [r1, 0x3]\n\ - mov r1, r12\n\ -_08052C0A:\n\ - ldr r0, [r1]\n\ - adds r0, 0x5\n\ - str r0, [r1]\n\ - b _08052D08\n\ - .pool\n\ -_08052C1C:\n\ - movs r4, 0\n\ - mov r8, r4\n\ - movs r7, 0x7F\n\ - mov r9, r7\n\ -_08052C24:\n\ - bl Random\n\ - mov r4, r9\n\ - ands r4, r0\n\ - cmp r4, 0x70\n\ - bhi _08052C24\n\ - lsls r0, r4, 1\n\ - adds r4, r0, r4\n\ - ldr r6, =gTypeEffectiveness\n\ - adds r3, r4, r6\n\ - ldr r1, =gUnknown_02024258\n\ - ldr r2, =gBankAttacker\n\ - ldrb r5, [r2]\n\ - lsls r0, r5, 1\n\ - adds r0, r1\n\ - ldrb r1, [r3]\n\ - mov r10, r2\n\ - ldrh r0, [r0]\n\ - cmp r1, r0\n\ - bne _08052C80\n\ - adds r0, r4, 0x2\n\ - adds r0, r6\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x5\n\ - bhi _08052C80\n\ - ldr r7, =gBattleMons\n\ - movs r2, 0x58\n\ - adds r0, r5, 0\n\ - muls r0, r2\n\ - adds r3, r0, r7\n\ - movs r0, 0x21\n\ - adds r0, r3\n\ - mov r12, r0\n\ - adds r0, r4, 0x1\n\ - adds r0, r6\n\ - ldrb r5, [r0]\n\ - mov r1, r12\n\ - ldrb r0, [r1]\n\ - adds r1, r5, 0\n\ - cmp r0, r1\n\ - beq _08052C80\n\ - adds r0, r3, 0\n\ - adds r0, 0x22\n\ - ldrb r0, [r0]\n\ - cmp r0, r1\n\ - bne _08052BB4\n\ -_08052C80:\n\ - movs r7, 0x1\n\ - add r8, r7\n\ - ldr r0, =0x000003e7\n\ - cmp r8, r0\n\ - ble _08052C24\n\ - movs r0, 0\n\ - mov r8, r0\n\ - ldr r1, =gBattlescriptCurrInstr\n\ - mov r12, r1\n\ - ldr r3, =gTypeEffectiveness\n\ - adds r0, r4, 0x1\n\ - adds r0, r3\n\ - mov r9, r0\n\ - adds r5, r3, 0\n\ -_08052C9C:\n\ - ldrb r1, [r5]\n\ - cmp r1, 0xFF\n\ - bgt _08052CA6\n\ - cmp r1, 0xFE\n\ - bge _08052CE0\n\ -_08052CA6:\n\ - mov r4, r10\n\ - ldrb r2, [r4]\n\ - lsls r0, r2, 1\n\ - ldr r7, =gUnknown_02024258\n\ - adds r0, r7\n\ - ldrh r0, [r0]\n\ - cmp r1, r0\n\ - bne _08052CE0\n\ - ldrb r0, [r5, 0x2]\n\ - cmp r0, 0x5\n\ - bhi _08052CE0\n\ - movs r6, 0x58\n\ - adds r0, r2, 0\n\ - muls r0, r6\n\ - ldr r1, =gBattleMons\n\ - adds r2, r0, r1\n\ - adds r4, r2, 0\n\ - adds r4, 0x21\n\ - ldrb r0, [r4]\n\ - mov r7, r9\n\ - ldrb r1, [r7]\n\ - cmp r0, r1\n\ - beq _08052CE0\n\ - adds r0, r2, 0\n\ - adds r0, 0x22\n\ - ldrb r0, [r0]\n\ - cmp r0, r1\n\ - beq _08052CE0\n\ - b _08052BE0\n\ -_08052CE0:\n\ - adds r5, 0x3\n\ - movs r0, 0x3\n\ - add r8, r0\n\ - ldr r0, =0x0000014f\n\ - cmp r8, r0\n\ - bls _08052C9C\n\ - mov r1, r12\n\ - ldr r2, [r1]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - lsls r0, 24\n\ - orrs r1, r0\n\ - mov r4, r12\n\ - str r1, [r4]\n\ -_08052D08:\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .pool\n\ - .syntax divided"); -} -#endif // NONMATCHING - -static void atkA7_setalwayshitflag(void) -{ - gStatuses3[gBankTarget] &= ~(STATUS3_ALWAYS_HITS); - gStatuses3[gBankTarget] |= 0x10; - gDisableStructs[gBankTarget].bankWithSureHit = gBankAttacker; - gBattlescriptCurrInstr++; -} - -static void atkA8_copymovepermanently(void) // sketch -{ - gLastUsedMove = 0xFFFF; - - if (!(gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED) - && gUnknownMovesUsedByBanks[gBankTarget] != MOVE_STRUGGLE - && gUnknownMovesUsedByBanks[gBankTarget] != 0 - && gUnknownMovesUsedByBanks[gBankTarget] != 0xFFFF - && gUnknownMovesUsedByBanks[gBankTarget] != MOVE_SKETCH) - { - s32 i; - - for (i = 0; i < 4; i++) - { - if (gBattleMons[gBankAttacker].moves[i] == MOVE_SKETCH) - continue; - if (gBattleMons[gBankAttacker].moves[i] == gUnknownMovesUsedByBanks[gBankTarget]) - break; - } - - if (i != 4) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else // sketch worked - { - struct MovePpInfo movePpData; - - gBattleMons[gBankAttacker].moves[gCurrMovePos] = gUnknownMovesUsedByBanks[gBankTarget]; - gBattleMons[gBankAttacker].pp[gCurrMovePos] = gBattleMoves[gUnknownMovesUsedByBanks[gBankTarget]].pp; - gActiveBank = gBankAttacker; - - for (i = 0; i < 4; i++) - { - movePpData.move[i] = gBattleMons[gBankAttacker].moves[i]; - movePpData.pp[i] = gBattleMons[gBankAttacker].pp[i]; - } - movePpData.ppBonuses = gBattleMons[gBankAttacker].ppBonuses; - - EmitSetMonData(0, REQUEST_MOVES_PP_BATTLE, 0, sizeof(struct MovePpInfo), &movePpData); - MarkBufferBankForExecution(gActiveBank); - - PREPARE_MOVE_BUFFER(gBattleTextBuff1, gUnknownMovesUsedByBanks[gBankTarget]) - - gBattlescriptCurrInstr += 5; - } - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static bool8 IsTwoTurnsMove(u16 move) -{ - if (gBattleMoves[move].effect == EFFECT_SKULL_BASH - || gBattleMoves[move].effect == EFFECT_RAZOR_WIND - || gBattleMoves[move].effect == EFFECT_SKY_ATTACK - || gBattleMoves[move].effect == EFFECT_SOLARBEAM - || gBattleMoves[move].effect == EFFECT_FLY - || gBattleMoves[move].effect == EFFECT_BIDE) - return TRUE; - else - return FALSE; -} - -static bool8 IsInvalidForSleepTalkOrAssist(u16 move) -{ - if (move == 0 || move == MOVE_SLEEP_TALK || move == MOVE_ASSIST - || move == MOVE_MIRROR_MOVE || move == MOVE_METRONOME) - return TRUE; - else - return FALSE; -} - -static u8 AttacksThisTurn(u8 bank, u16 move) // Note: returns 1 if it's a charging turn, otherwise 2 -{ - // first argument is unused - if (gBattleMoves[move].effect == EFFECT_SOLARBEAM - && (gBattleWeather & WEATHER_SUN_ANY)) - return 2; - - if (gBattleMoves[move].effect == EFFECT_SKULL_BASH - || gBattleMoves[move].effect == EFFECT_RAZOR_WIND - || gBattleMoves[move].effect == EFFECT_SKY_ATTACK - || gBattleMoves[move].effect == EFFECT_SOLARBEAM - || gBattleMoves[move].effect == EFFECT_FLY - || gBattleMoves[move].effect == EFFECT_BIDE) - { - if ((gHitMarker & HITMARKER_x8000000)) - return 1; - } - return 2; -} - -static void atkA9_sleeptalk_choose_move(void) -{ - s32 i; - u8 unusableMovesBits = 0; - - for (i = 0; i < 4; i++) - { - if (IsInvalidForSleepTalkOrAssist(gBattleMons[gBankAttacker].moves[i]) - || gBattleMons[gBankAttacker].moves[i] == MOVE_FOCUS_PUNCH - || gBattleMons[gBankAttacker].moves[i] == MOVE_UPROAR - || IsTwoTurnsMove(gBattleMons[gBankAttacker].moves[i])) - { - unusableMovesBits |= gBitTable[i]; - } - - } - - unusableMovesBits = CheckMoveLimitations(gBankAttacker, unusableMovesBits, ~(MOVE_LIMITATION_PP)); - if (unusableMovesBits == 0xF) // all 4 moves cannot be chosen - { - gBattlescriptCurrInstr += 5; - } - else // at least one move can be chosen - { - u32 movePosition; - - do - { - movePosition = Random() & 3; - } while ((gBitTable[movePosition] & unusableMovesBits)); - - gRandomMove = gBattleMons[gBankAttacker].moves[movePosition]; - gCurrMovePos = movePosition; - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gBankTarget = GetMoveTarget(gRandomMove, 0); - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkAA_set_destinybond(void) -{ - gBattleMons[gBankAttacker].status2 |= STATUS2_DESTINY_BOND; - gBattlescriptCurrInstr++; -} - -static void DestinyBondFlagUpdate(void) -{ - u8 sideAttacker = GetBankSide(gBankAttacker); - u8 sideTarget = GetBankSide(gBankTarget); - if (gBattleMons[gBankTarget].status2 & STATUS2_DESTINY_BOND - && sideAttacker != sideTarget - && !(gHitMarker & HITMARKER_GRUDGE)) - { - gHitMarker |= HITMARKER_DESTINYBOND; - } -} - -static void atkAB_DestinyBondFlagUpdate(void) -{ - DestinyBondFlagUpdate(); - gBattlescriptCurrInstr++; -} - -static void atkAC_remaininghptopower(void) -{ - s32 i; - s32 hpFraction = GetScaledHPFraction(gBattleMons[gBankAttacker].hp, gBattleMons[gBankAttacker].maxHP, 48); - - for (i = 0; i < (s32) sizeof(sFlailHpScaleToPowerTable); i += 2) - { - if (hpFraction <= sFlailHpScaleToPowerTable[i]) - break; - } - - gDynamicBasePower = sFlailHpScaleToPowerTable[i + 1]; - gBattlescriptCurrInstr++; -} - -static void atkAD_spite_ppreduce(void) -{ - if (gLastUsedMovesByBanks[gBankTarget] != 0 - && gLastUsedMovesByBanks[gBankTarget] != 0xFFFF) - { - s32 i; - - for (i = 0; i < 4; i++) - { - if (gLastUsedMovesByBanks[gBankTarget] == gBattleMons[gBankTarget].moves[i]) - break; - } - - if (i != 4 && gBattleMons[gBankTarget].pp[i] > 1) - { - s32 ppToDeduct = (Random() & 3) + 2; - if (gBattleMons[gBankTarget].pp[i] < ppToDeduct) - ppToDeduct = gBattleMons[gBankTarget].pp[i]; - - PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastUsedMovesByBanks[gBankTarget]) - - ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, 0, 1); - - PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct) - - gBattleMons[gBankTarget].pp[i] -= ppToDeduct; - gActiveBank = gBankTarget; - - if (!(gDisableStructs[gActiveBank].unk18_b & gBitTable[i]) - && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) - { - EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + i, 0, 1, &gBattleMons[gActiveBank].pp[i]); - MarkBufferBankForExecution(gActiveBank); - } - - gBattlescriptCurrInstr += 5; - - if (gBattleMons[gBankTarget].pp[i] == 0) - CancelMultiTurnMoves(gBankTarget); - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkAE_heal_party_status(void) -{ - u32 zero = 0; - u8 toHeal = 0; - - if (gCurrentMove == MOVE_HEAL_BELL) - { - struct Pokemon* party; - s32 i; - - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - - if (GetBankSide(gBankAttacker) == SIDE_PLAYER) - party = gPlayerParty; - else - party = gEnemyParty; - - if (gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF) - { - gBattleMons[gBankAttacker].status1 = 0; - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); - } - else - { - RecordAbilityBattle(gBankAttacker, gBattleMons[gBankAttacker].ability); - gBattleCommunication[MULTISTRING_CHOOSER] |= 1; - } - - gActiveBank = gBattleScripting.bank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && !(gAbsentBankFlags & gBitTable[gActiveBank])) - { - if (gBattleMons[gActiveBank].ability != ABILITY_SOUNDPROOF) - { - gBattleMons[gActiveBank].status1 = 0; - gBattleMons[gActiveBank].status2 &= ~(STATUS2_NIGHTMARE); - } - else - { - RecordAbilityBattle(gActiveBank, gBattleMons[gActiveBank].ability); - gBattleCommunication[MULTISTRING_CHOOSER] |= 2; - } - } - - for (i = 0; i < 6; i++) - { - u16 species = GetMonData(&party[i], MON_DATA_SPECIES2); - u8 abilityBit = GetMonData(&party[i], MON_DATA_ALT_ABILITY); - - if (species != 0 && species != SPECIES_EGG) - { - u8 ability; - - if (gBattlePartyID[gBankAttacker] == i) - ability = gBattleMons[gBankAttacker].ability; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && gBattlePartyID[gActiveBank] == i - && !(gAbsentBankFlags & gBitTable[gActiveBank])) - ability = gBattleMons[gActiveBank].ability; - else - ability = GetAbilityBySpecies(species, abilityBit); - - if (ability != ABILITY_SOUNDPROOF) - toHeal |= (1 << i); - } - } - } - else // Aromatherapy - { - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - toHeal = 0x3F; - - gBattleMons[gBankAttacker].status1 = 0; - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); - - gActiveBank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ 2); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && !(gAbsentBankFlags & gBitTable[gActiveBank])) - { - gBattleMons[gActiveBank].status1 = 0; - gBattleMons[gActiveBank].status2 &= ~(STATUS2_NIGHTMARE); - } - - } - - if (toHeal) - { - gActiveBank = gBankAttacker; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, toHeal, 4, &zero); - MarkBufferBankForExecution(gActiveBank); - } - - gBattlescriptCurrInstr++; -} - -static void atkAF_cursetarget(void) -{ - if (gBattleMons[gBankTarget].status2 & STATUS2_CURSED) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gBattleMons[gBankTarget].status2 |= STATUS2_CURSED; - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - gBattlescriptCurrInstr += 5; - } -} - -static void atkB0_set_spikes(void) -{ - u8 targetSide = GetBankSide(gBankAttacker) ^ BIT_SIDE; - - if (gSideTimers[targetSide].spikesAmount == 3) - { - gSpecialStatuses[gBankAttacker].flag20 = 1; - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gSideAffecting[targetSide] |= SIDE_STATUS_SPIKES; - gSideTimers[targetSide].spikesAmount++; - gBattlescriptCurrInstr += 5; - } -} - -static void atkB1_set_foresight(void) -{ - gBattleMons[gBankTarget].status2 |= STATUS2_FORESIGHT; - gBattlescriptCurrInstr++; -} - -static void atkB2_setperishsong(void) -{ - s32 i; - s32 notAffectedCount = 0; - - for (i = 0; i < gNoOfAllBanks; i++) - { - if (gStatuses3[i] & STATUS3_PERISH_SONG - || gBattleMons[i].ability == ABILITY_SOUNDPROOF) - { - notAffectedCount++; - } - else - { - gStatuses3[i] |= STATUS3_PERISH_SONG; - gDisableStructs[i].perishSong1 = 3; - gDisableStructs[i].perishSong2 = 3; - } - } - - PressurePPLoseOnUsingPerishSong(gBankAttacker); - - if (notAffectedCount == gNoOfAllBanks) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; -} - -static void atkB3_rolloutdamagecalculation(void) -{ - if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) - { - CancelMultiTurnMoves(gBankAttacker); - gBattlescriptCurrInstr = BattleScript_PauseEffectivenessSoundResultMsgEndMove; - } - else - { - s32 i; - - if (!(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) // first hit - { - gDisableStructs[gBankAttacker].rolloutTimer1 = 5; - gDisableStructs[gBankAttacker].rolloutTimer2 = 5; - gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gBankAttacker] = gCurrentMove; - } - if (--gDisableStructs[gBankAttacker].rolloutTimer1 == 0) // last hit - { - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS); - } - - gDynamicBasePower = gBattleMoves[gCurrentMove].power; - - for (i = 1; i < (5 - gDisableStructs[gBankAttacker].rolloutTimer1); i++) - gDynamicBasePower *= 2; - - if (gBattleMons[gBankAttacker].status2 & STATUS2_DEFENSE_CURL) - gDynamicBasePower *= 2; - - gBattlescriptCurrInstr++; - } -} - -static void atkB4_jumpifconfusedandstatmaxed(void) -{ - if (gBattleMons[gBankTarget].status2 & STATUS2_CONFUSION - && gBattleMons[gBankTarget].statStages[gBattlescriptCurrInstr[1]] == 0xC) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; -} - -static void atkB5_furycuttercalc(void) -{ - if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) - { - gDisableStructs[gBankAttacker].furyCutterCounter = 0; - gBattlescriptCurrInstr = BattleScript_PauseEffectivenessSoundResultMsgEndMove; - } - else - { - s32 i; - - if (gDisableStructs[gBankAttacker].furyCutterCounter != 5) - gDisableStructs[gBankAttacker].furyCutterCounter++; - - gDynamicBasePower = gBattleMoves[gCurrentMove].power; - - for (i = 1; i < gDisableStructs[gBankAttacker].furyCutterCounter; i++) - gDynamicBasePower *= 2; - - gBattlescriptCurrInstr++; - } -} - -static void atkB6_happinesstodamagecalculation(void) -{ - if (gBattleMoves[gCurrentMove].effect == EFFECT_RETURN) - gDynamicBasePower = 10 * (gBattleMons[gBankAttacker].friendship) / 25; - else // EFFECT_FRUSTRATION - gDynamicBasePower = 10 * (255 - gBattleMons[gBankAttacker].friendship) / 25; - - gBattlescriptCurrInstr++; -} - -static void atkB7_presentdamagecalculation(void) -{ - s32 rand = Random() & 0xFF; - - if (rand < 102) - gDynamicBasePower = 40; - else if (rand < 178) - gDynamicBasePower = 80; - else if (rand < 204) - gDynamicBasePower = 120; - else - { - gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - } - if (rand < 204) - gBattlescriptCurrInstr = BattleScript_PresentDamageTarget; - else if (gBattleMons[gBankTarget].maxHP == gBattleMons[gBankTarget].hp) - gBattlescriptCurrInstr = BattleScript_AlreadyAtFullHp; - else - { - gBattleMoveFlags &= ~(MOVESTATUS_NOTAFFECTED); - gBattlescriptCurrInstr = BattleScript_PresentHealTarget; - } -} - -static void atkB8_set_safeguard(void) -{ - if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_SAFEGUARD) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else - { - gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_SAFEGUARD; - gSideTimers[GET_BANK_SIDE(gBankAttacker)].safeguardTimer = 5; - gSideTimers[GET_BANK_SIDE(gBankAttacker)].safeguardBank = gBankAttacker; - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - } - - gBattlescriptCurrInstr++; -} - -static void atkB9_magnitudedamagecalculation(void) -{ - s32 magnitude = Random() % 100; - - if (magnitude < 5) - { - gDynamicBasePower = 10; - magnitude = 4; - } - else if (magnitude < 15) - { - gDynamicBasePower = 30; - magnitude = 5; - } - else if (magnitude < 35) - { - gDynamicBasePower = 50; - magnitude = 6; - } - else if (magnitude < 65) - { - gDynamicBasePower = 70; - magnitude = 7; - } - else if (magnitude < 85) - { - gDynamicBasePower = 90; - magnitude = 8; - } - else if (magnitude < 95) - { - gDynamicBasePower = 110; - magnitude = 9; - } - else - { - gDynamicBasePower = 150; - magnitude = 10; - } - - - PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 2, magnitude) - - for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) - { - if (gBankTarget == gBankAttacker) - continue; - if (!(gAbsentBankFlags & gBitTable[gBankTarget])) // a valid target was found - break; - } - - gBattlescriptCurrInstr++; -} - -static void atkBA_jumpifnopursuitswitchdmg(void) -{ - if (gMultiHitCounter == 1) - { - if (GetBankSide(gBankAttacker) == SIDE_PLAYER) - gBankTarget = GetBankByIdentity(IDENTITY_OPPONENT_MON1); - else - gBankTarget = GetBankByIdentity(IDENTITY_PLAYER_MON1); - } - else - { - if (GetBankSide(gBankAttacker) == SIDE_PLAYER) - gBankTarget = GetBankByIdentity(IDENTITY_OPPONENT_MON2); - else - gBankTarget = GetBankByIdentity(IDENTITY_PLAYER_MON2); - } - - if (gActionForBanks[gBankTarget] == 0 - && gBankAttacker == *(gBattleStruct->moveTarget + gBankTarget) - && !(gBattleMons[gBankTarget].status1 & (STATUS_SLEEP | STATUS_FREEZE)) - && gBattleMons[gBankAttacker].hp - && !gDisableStructs[gBankTarget].truantCounter - && gChosenMovesByBanks[gBankTarget] == MOVE_PURSUIT) - { - s32 i; - - for (i = 0; i < gNoOfAllBanks; i++) - { - if (gTurnOrder[i] == gBankTarget) - gUnknown_0202407A[i] = 11; - } - - gCurrentMove = MOVE_PURSUIT; - gCurrMovePos = gUnknown_020241E9 = *(gBattleStruct->chosenMovesIds + gBankTarget); - gBattlescriptCurrInstr += 5; - gBattleScripting.animTurn = 1; - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkBB_setsunny(void) -{ - if (gBattleWeather & WEATHER_SUN_ANY) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else - { - gBattleWeather = WEATHER_SUN_TEMPORARY; - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - gWishFutureKnock.weatherDuration = 5; - } - - gBattlescriptCurrInstr++; -} - -static void atkBC_maxattackhalvehp(void) // belly drum -{ - u32 halfHp = gBattleMons[gBankAttacker].maxHP / 2; - - if (!(gBattleMons[gBankAttacker].maxHP / 2)) - halfHp = 1; - - if (gBattleMons[gBankAttacker].statStages[STAT_STAGE_ATK] < 12 - && gBattleMons[gBankAttacker].hp > halfHp) - { - gBattleMons[gBankAttacker].statStages[STAT_STAGE_ATK] = 12; - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkBD_copyfoestats(void) // psych up -{ - s32 i; - - for (i = 0; i < BATTLE_STATS_NO; i++) - { - gBattleMons[gBankAttacker].statStages[i] = gBattleMons[gBankTarget].statStages[i]; - } - - gBattlescriptCurrInstr += 5; // Has an unused jump ptr(possibly for a failed attempt) parameter. -} - -static void atkBE_rapidspinfree(void) -{ - if (gBattleMons[gBankAttacker].status2 & STATUS2_WRAPPED) - { - gBattleScripting.bank = gBankTarget; - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_WRAPPED); - gBankTarget = *(gBattleStruct->wrappedBy + gBankAttacker); - - gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN; - gBattleTextBuff1[1] = B_BUFF_MOVE; - gBattleTextBuff1[2] = *(gBattleStruct->wrappedMove + gBankAttacker * 2 + 0); - gBattleTextBuff1[3] = *(gBattleStruct->wrappedMove + gBankAttacker * 2 + 1); - gBattleTextBuff1[4] = B_BUFF_EOS; - - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_WrapFree; - } - else if (gStatuses3[gBankAttacker] & STATUS3_LEECHSEED) - { - gStatuses3[gBankAttacker] &= ~(STATUS3_LEECHSEED); - gStatuses3[gBankAttacker] &= ~(STATUS3_LEECHSEED_BANK); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_LeechSeedFree; - } - else if (gSideAffecting[GetBankSide(gBankAttacker)] & SIDE_STATUS_SPIKES) - { - gSideAffecting[GetBankSide(gBankAttacker)] &= ~(SIDE_STATUS_SPIKES); - gSideTimers[GetBankSide(gBankAttacker)].spikesAmount = 0; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_SpikesFree; - } - else - { - gBattlescriptCurrInstr++; - } -} - -static void atkBF_set_defense_curl(void) -{ - gBattleMons[gBankAttacker].status2 |= STATUS2_DEFENSE_CURL; - gBattlescriptCurrInstr++; -} - -static void atkC0_recoverbasedonsunlight(void) -{ - gBankTarget = gBankAttacker; - - if (gBattleMons[gBankAttacker].hp != gBattleMons[gBankAttacker].maxHP) - { - if (gBattleWeather == 0 || !WEATHER_HAS_EFFECT) - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; - else if (gBattleWeather & WEATHER_SUN_ANY) - gBattleMoveDamage = 20 * gBattleMons[gBankAttacker].maxHP / 30; - else // not sunny weather - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4; - - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -#ifdef NONMATCHING -static void atkC1_hidden_power(void) -{ - s32 powerBits; - s32 typeBits; - - powerBits = ((gBattleMons[gBankAttacker].hpIV & 2) >> 1) - | ((gBattleMons[gBankAttacker].attackIV & 2) << 0) - | ((gBattleMons[gBankAttacker].defenseIV & 2) << 1) - | ((gBattleMons[gBankAttacker].speedIV & 2) << 2) - | ((gBattleMons[gBankAttacker].spAttackIV & 2) << 3) - | ((gBattleMons[gBankAttacker].spDefenseIV & 2) << 4); - - typeBits = ((gBattleMons[gBankAttacker].hpIV & 1) << 0) - | ((gBattleMons[gBankAttacker].attackIV & 1) << 1) - | ((gBattleMons[gBankAttacker].defenseIV & 1) << 2) - | ((gBattleMons[gBankAttacker].speedIV & 1) << 3) - | ((gBattleMons[gBankAttacker].spAttackIV & 1) << 4) - | ((gBattleMons[gBankAttacker].spDefenseIV & 1) << 5); - - gDynamicBasePower = (40 * powerBits) / 63 + 30; - - gBattleStruct->dynamicMoveType = (15 * typeBits) / 63 + 1; - if (gBattleStruct->dynamicMoveType > 8) - gBattleStruct->dynamicMoveType++; - gBattleStruct->dynamicMoveType |= 0xC0; - - gBattlescriptCurrInstr++; -} - -#else -__attribute__((naked)) -static void atkC1_hidden_power(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - ldr r2, =gBattleMons\n\ - ldr r0, =gBankAttacker\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - adds r4, r1, 0\n\ - muls r4, r0\n\ - adds r4, r2\n\ - ldrb r0, [r4, 0x14]\n\ - mov r10, r0\n\ - mov r7, r10\n\ - lsls r7, 27\n\ - adds r0, r7, 0\n\ - lsrs r0, 27\n\ - mov r10, r0\n\ - movs r1, 0x2\n\ - mov r2, r10\n\ - ands r2, r1\n\ - asrs r2, 1\n\ - ldrh r7, [r4, 0x14]\n\ - mov r9, r7\n\ - mov r0, r9\n\ - lsls r0, 22\n\ - mov r9, r0\n\ - lsrs r3, r0, 27\n\ - adds r0, r1, 0\n\ - ands r0, r3\n\ - orrs r2, r0\n\ - ldrb r7, [r4, 0x15]\n\ - mov r8, r7\n\ - mov r0, r8\n\ - lsls r0, 25\n\ - mov r8, r0\n\ - lsrs r3, r0, 27\n\ - adds r0, r1, 0\n\ - ands r0, r3\n\ - lsls r0, 1\n\ - orrs r2, r0\n\ - ldr r6, [r4, 0x14]\n\ - lsls r6, 12\n\ - lsrs r3, r6, 27\n\ - adds r0, r1, 0\n\ - ands r0, r3\n\ - lsls r0, 2\n\ - orrs r2, r0\n\ - ldrh r5, [r4, 0x16]\n\ - lsls r5, 23\n\ - lsrs r3, r5, 27\n\ - adds r0, r1, 0\n\ - ands r0, r3\n\ - lsls r0, 3\n\ - orrs r2, r0\n\ - ldrb r3, [r4, 0x17]\n\ - lsls r3, 26\n\ - lsrs r0, r3, 27\n\ - ands r1, r0\n\ - lsls r1, 4\n\ - orrs r2, r1\n\ - movs r1, 0x1\n\ - adds r4, r1, 0\n\ - mov r7, r10\n\ - ands r4, r7\n\ - mov r0, r9\n\ - lsrs r0, 27\n\ - mov r9, r0\n\ - adds r0, r1, 0\n\ - mov r7, r9\n\ - ands r0, r7\n\ - lsls r0, 1\n\ - orrs r4, r0\n\ - mov r0, r8\n\ - lsrs r0, 27\n\ - mov r8, r0\n\ - adds r0, r1, 0\n\ - mov r7, r8\n\ - ands r0, r7\n\ - lsls r0, 2\n\ - orrs r4, r0\n\ - lsrs r6, 27\n\ - adds r0, r1, 0\n\ - ands r0, r6\n\ - lsls r0, 3\n\ - orrs r4, r0\n\ - lsrs r5, 27\n\ - adds r0, r1, 0\n\ - ands r0, r5\n\ - lsls r0, 4\n\ - orrs r4, r0\n\ - lsrs r3, 27\n\ - ands r1, r3\n\ - lsls r1, 5\n\ - orrs r4, r1\n\ - ldr r5, =gDynamicBasePower\n\ - lsls r0, r2, 2\n\ - adds r0, r2\n\ - lsls r0, 3\n\ - movs r1, 0x3F\n\ - bl __divsi3\n\ - adds r0, 0x1E\n\ - strh r0, [r5]\n\ - ldr r6, =gBattleStruct\n\ - ldr r5, [r6]\n\ - lsls r0, r4, 4\n\ - subs r0, r4\n\ - movs r1, 0x3F\n\ - bl __divsi3\n\ - adds r0, 0x1\n\ - strb r0, [r5, 0x13]\n\ - ldr r1, [r6]\n\ - ldrb r0, [r1, 0x13]\n\ - cmp r0, 0x8\n\ - bls _080544F0\n\ - adds r0, 0x1\n\ - strb r0, [r1, 0x13]\n\ -_080544F0:\n\ - ldr r2, [r6]\n\ - ldrb r0, [r2, 0x13]\n\ - movs r1, 0xC0\n\ - orrs r0, r1\n\ - strb r0, [r2, 0x13]\n\ - ldr r1, =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x1\n\ - str r0, [r1]\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .pool\n\ - .syntax divided"); -} -#endif // NONMATCHING - -static void atkC2_selectnexttarget(void) -{ - for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) - { - if (gBankTarget == gBankAttacker) - continue; - if (!(gAbsentBankFlags & gBitTable[gBankTarget])) - break; - } - gBattlescriptCurrInstr++; -} - -static void atkC3_setfutureattack(void) -{ - if (gWishFutureKnock.futureSightCounter[gBankTarget] != 0) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gSideAffecting[GET_BANK_SIDE(gBankTarget)] |= SIDE_STATUS_FUTUREATTACK; - gWishFutureKnock.futureSightMove[gBankTarget] = gCurrentMove; - gWishFutureKnock.futureSightAttacker[gBankTarget] = gBankAttacker; - gWishFutureKnock.futureSightCounter[gBankTarget] = 3; - gWishFutureKnock.futureSightDmg[gBankTarget] = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, - gSideAffecting[GET_BANK_SIDE(gBankTarget)], 0, - 0, gBankAttacker, gBankTarget); - - if (gProtectStructs[gBankAttacker].helpingHand) - gWishFutureKnock.futureSightDmg[gBankTarget] = gWishFutureKnock.futureSightDmg[gBankTarget] * 15 / 10; - - if (gCurrentMove == MOVE_DOOM_DESIRE) - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - - gBattlescriptCurrInstr += 5; - } -} - -static void atkC4_beat_up(void) -{ - struct Pokemon* party; - - if (GetBankSide(gBankAttacker) == SIDE_PLAYER) - party = gPlayerParty; - else - party = gEnemyParty; - - if (gBattleMons[gBankTarget].hp == 0) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - u8 beforeLoop = gBattleCommunication[0]; - for (;gBattleCommunication[0] < 6; gBattleCommunication[0]++) - { - if (GetMonData(&party[gBattleCommunication[0]], MON_DATA_HP) - && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) - && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) != SPECIES_EGG - && !GetMonData(&party[gBattleCommunication[0]], MON_DATA_STATUS)) - break; - } - if (gBattleCommunication[0] < 6) - { - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBankAttacker, gBattleCommunication[0]) - - gBattlescriptCurrInstr += 9; - - gBattleMoveDamage = gBaseStats[GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES)].baseAttack; - gBattleMoveDamage *= gBattleMoves[gCurrentMove].power; - gBattleMoveDamage *= (GetMonData(&party[gBattleCommunication[0]], MON_DATA_LEVEL) * 2 / 5 + 2); - gBattleMoveDamage /= gBaseStats[gBattleMons[gBankTarget].species].baseDefense; - gBattleMoveDamage = (gBattleMoveDamage / 50) + 2; - if (gProtectStructs[gBankAttacker].helpingHand) - gBattleMoveDamage = gBattleMoveDamage * 15 / 10; - - gBattleCommunication[0]++; - } - else if (beforeLoop != 0) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 5); - } -} - -static void atkC5_setsemiinvulnerablebit(void) -{ - switch (gCurrentMove) - { - case MOVE_FLY: - case MOVE_BOUNCE: - gStatuses3[gBankAttacker] |= STATUS3_ON_AIR; - break; - case MOVE_DIG: - gStatuses3[gBankAttacker] |= STATUS3_UNDERGROUND; - break; - case MOVE_DIVE: - gStatuses3[gBankAttacker] |= STATUS3_UNDERWATER; - break; - } - - gBattlescriptCurrInstr++; -} - -static void atkC6_clearsemiinvulnerablebit(void) -{ - switch (gCurrentMove) - { - case MOVE_FLY: - case MOVE_BOUNCE: - gStatuses3[gBankAttacker] &= ~STATUS3_ON_AIR; - break; - case MOVE_DIG: - gStatuses3[gBankAttacker] &= ~STATUS3_UNDERGROUND; - break; - case MOVE_DIVE: - gStatuses3[gBankAttacker] &= ~STATUS3_UNDERWATER; - break; - } - - gBattlescriptCurrInstr++; -} - -static void atkC7_setminimize(void) -{ - if (gHitMarker & HITMARKER_OBEYS) - gStatuses3[gBankAttacker] |= STATUS3_MINIMIZED; - - gBattlescriptCurrInstr++; -} - -static void atkC8_sethail(void) -{ - if (gBattleWeather & WEATHER_HAIL_ANY) - { - gBattleMoveFlags |= MOVESTATUS_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else - { - gBattleWeather = WEATHER_HAIL; - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - gWishFutureKnock.weatherDuration = 5; - } - - gBattlescriptCurrInstr++; -} - -static void atkC9_jumpifattackandspecialattackcannotfall(void) // memento -{ - if (gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] == 0 - && gBattleMons[gBankTarget].statStages[STAT_STAGE_SPATK] == 0 - && gBattleCommunication[6] != 1) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gActiveBank = gBankAttacker; - gBattleMoveDamage = gBattleMons[gActiveBank].hp; - EmitHealthBarUpdate(0, 0x7FFF); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr += 5; - } -} - -static void atkCA_setforcedtarget(void) // follow me -{ - gSideTimers[GetBankSide(gBankAttacker)].followmeTimer = 1; - gSideTimers[GetBankSide(gBankAttacker)].followmeTarget = gBankAttacker; - gBattlescriptCurrInstr++; -} - -static void atkCB_setcharge(void) -{ - gStatuses3[gBankAttacker] |= STATUS3_CHARGED_UP; - gDisableStructs[gBankAttacker].chargeTimer1 = 2; - gDisableStructs[gBankAttacker].chargeTimer2 = 2; - gBattlescriptCurrInstr++; -} - -static void atkCC_callterrainattack(void) // nature power -{ - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gCurrentMove = sNaturePowerMoves[gBattleTerrain]; - gBankTarget = GetMoveTarget(gCurrentMove, 0); - BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); - gBattlescriptCurrInstr++; -} - -static void atkCD_cureifburnedparalysedorpoisoned(void) // refresh -{ - if (gBattleMons[gBankAttacker].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON)) - { - gBattleMons[gBankAttacker].status1 = 0; - gBattlescriptCurrInstr += 5; - gActiveBank = gBankAttacker; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); - MarkBufferBankForExecution(gActiveBank); - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkCE_settorment(void) -{ - if (gBattleMons[gBankTarget].status2 & STATUS2_TORMENT) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gBattleMons[gBankTarget].status2 |= STATUS2_TORMENT; - gBattlescriptCurrInstr += 5; - } -} - -static void atkCF_jumpifnodamage(void) -{ - if (gProtectStructs[gBankAttacker].physicalDmg || gProtectStructs[gBankAttacker].specialDmg) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); -} - -static void atkD0_settaunt(void) -{ - if (gDisableStructs[gBankTarget].tauntTimer1 == 0) - { - gDisableStructs[gBankTarget].tauntTimer1 = 2; - gDisableStructs[gBankTarget].tauntTimer2 = 2; - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkD1_set_helpinghand(void) -{ - gBankTarget = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && !(gAbsentBankFlags & gBitTable[gBankTarget]) - && !gProtectStructs[gBankAttacker].helpingHand - && !gProtectStructs[gBankTarget].helpingHand) - { - gProtectStructs[gBankTarget].helpingHand = 1; - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkD2_swap_items(void) // trick -{ - // opponent can't swap items with player in regular battles - if (gBattleTypeFlags & BATTLE_TYPE_x4000000 - || (GetBankSide(gBankAttacker) == SIDE_OPPONENT - && !(gBattleTypeFlags & (BATTLE_TYPE_LINK - | BATTLE_TYPE_EREADER_TRAINER - | BATTLE_TYPE_FRONTIER - | BATTLE_TYPE_SECRET_BASE - | BATTLE_TYPE_x2000000)))) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - u8 sideAttacker = GetBankSide(gBankAttacker); - u8 sideTarget = GetBankSide(gBankTarget); - - // you can't swap items if they were knocked off in regular battles - if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK - | BATTLE_TYPE_EREADER_TRAINER - | BATTLE_TYPE_FRONTIER - | BATTLE_TYPE_SECRET_BASE - | BATTLE_TYPE_x2000000)) - && (gWishFutureKnock.knockedOffPokes[sideAttacker] & gBitTable[gBattlePartyID[gBankAttacker]] - || gWishFutureKnock.knockedOffPokes[sideTarget] & gBitTable[gBattlePartyID[gBankTarget]])) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - // can't swap if two pokemon don't have an item - // or if either of them is an enigma berry or a mail - else if ((gBattleMons[gBankAttacker].item == 0 && gBattleMons[gBankTarget].item == 0) - || gBattleMons[gBankAttacker].item == ITEM_ENIGMA_BERRY - || gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY - || IS_ITEM_MAIL(gBattleMons[gBankAttacker].item) - || IS_ITEM_MAIL(gBattleMons[gBankTarget].item)) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - // check if ability prevents swapping - else if (gBattleMons[gBankTarget].ability == ABILITY_STICKY_HOLD) - { - gBattlescriptCurrInstr = BattleScript_StickyHoldActivates; - gLastUsedAbility = gBattleMons[gBankTarget].ability; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - // took a while, but all checks passed and items can be safely swapped - else - { - u16 oldItemAtk, *newItemAtk; - - newItemAtk = &gBattleStruct->changedItems[gBankAttacker]; - oldItemAtk = gBattleMons[gBankAttacker].item; - *newItemAtk = gBattleMons[gBankTarget].item; - - gBattleMons[gBankAttacker].item = 0; - gBattleMons[gBankTarget].item = oldItemAtk; - - gActiveBank = gBankAttacker; - EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, newItemAtk); - MarkBufferBankForExecution(gBankAttacker); - - gActiveBank = gBankTarget; - EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); - MarkBufferBankForExecution(gBankTarget); - - *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 0) = 0; - *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 1) = 0; - - *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankAttacker]) + 0) = 0; - *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankAttacker]) + 1) = 0; - - gBattlescriptCurrInstr += 5; - - PREPARE_ITEM_BUFFER(gBattleTextBuff1, *newItemAtk) - PREPARE_ITEM_BUFFER(gBattleTextBuff2, oldItemAtk) - - if (oldItemAtk != 0 && *newItemAtk != 0) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; // attacker's item -> <- target's item - else if (oldItemAtk == 0 && *newItemAtk != 0) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; // nothing -> <- target's item - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; // attacker's item -> <- nothing - } - } -} - -static void atkD3_copy_ability(void) // role play -{ - if (gBattleMons[gBankTarget].ability != 0 - && gBattleMons[gBankTarget].ability != ABILITY_WONDER_GUARD) - { - gBattleMons[gBankAttacker].ability = gBattleMons[gBankTarget].ability; - gLastUsedAbility = gBattleMons[gBankTarget].ability; - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkD4_wish_effect(void) -{ - switch (gBattlescriptCurrInstr[1]) - { - case 0: // use wish - if (gWishFutureKnock.wishCounter[gBankAttacker] == 0) - { - gWishFutureKnock.wishCounter[gBankAttacker] = 2; - gWishFutureKnock.wishUserID[gBankAttacker] = gBattlePartyID[gBankAttacker]; - gBattlescriptCurrInstr += 6; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - } - break; - case 1: // heal effect - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBankTarget, gWishFutureKnock.wishUserID[gBankTarget]) - - gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - - if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; - - break; - } -} - -static void atkD5_setroots(void) // ingrain -{ - if (gStatuses3[gBankAttacker] & STATUS3_ROOTED) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gStatuses3[gBankAttacker] |= STATUS3_ROOTED; - gBattlescriptCurrInstr += 5; - } -} - -static void atkD6_doubledamagedealtifdamaged(void) -{ - if ((gProtectStructs[gBankAttacker].physicalDmg - && gProtectStructs[gBankAttacker].physicalBank == gBankTarget) - || (gProtectStructs[gBankAttacker].specialDmg - && gProtectStructs[gBankAttacker].specialBank == gBankTarget)) - { - gBattleScripting.dmgMultiplier = 2; - } - - gBattlescriptCurrInstr++; -} - -static void atkD7_setyawn(void) -{ - if (gStatuses3[gBankTarget] & STATUS3_YAWN - || gBattleMons[gBankTarget].status1 & STATUS_ANY) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gStatuses3[gBankTarget] |= 0x1000; - gBattlescriptCurrInstr += 5; - } -} - -static void atkD8_setdamagetohealthdifference(void) -{ - if (gBattleMons[gBankTarget].hp <= gBattleMons[gBankAttacker].hp) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gBattleMoveDamage = gBattleMons[gBankTarget].hp - gBattleMons[gBankAttacker].hp; - gBattlescriptCurrInstr += 5; - } -} - -static void atkD9_scaledamagebyhealthratio(void) -{ - if (gDynamicBasePower == 0) - { - u8 power = gBattleMoves[gCurrentMove].power; - gDynamicBasePower = gBattleMons[gBankAttacker].hp * power / gBattleMons[gBankAttacker].maxHP; - if (gDynamicBasePower == 0) - gDynamicBasePower = 1; - } - gBattlescriptCurrInstr++; -} - -static void atkDA_abilityswap(void) // skill swap -{ - if ((gBattleMons[gBankAttacker].ability == 0 - && gBattleMons[gBankTarget].ability == 0) - || gBattleMons[gBankAttacker].ability == ABILITY_WONDER_GUARD - || gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD - || gBattleMoveFlags & MOVESTATUS_NOEFFECT) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - u8 abilityAtk = gBattleMons[gBankAttacker].ability; - gBattleMons[gBankAttacker].ability = gBattleMons[gBankTarget].ability; - gBattleMons[gBankTarget].ability = abilityAtk; - - gBattlescriptCurrInstr += 5; - } -} - -static void atkDB_imprisoneffect(void) -{ - if ((gStatuses3[gBankAttacker] & STATUS3_IMPRISONED_OTHERS)) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - u8 bank, sideAttacker; - - sideAttacker = GetBankSide(gBankAttacker); - PressurePPLoseOnUsingImprision(gBankAttacker); - for (bank = 0; bank < gNoOfAllBanks; bank++) - { - if (sideAttacker != GetBankSide(bank)) - { - s32 attackerMoveId; - for (attackerMoveId = 0; attackerMoveId < 4; attackerMoveId++) - { - s32 i; - for (i = 0; i < 4; i++) - { - if (gBattleMons[gBankAttacker].moves[attackerMoveId] == gBattleMons[bank].moves[i] - && gBattleMons[gBankAttacker].moves[attackerMoveId] != MOVE_NONE) - break; - } - if (i != 4) - break; - } - if (attackerMoveId != 4) - { - gStatuses3[gBankAttacker] |= STATUS3_IMPRISONED_OTHERS; - gBattlescriptCurrInstr += 5; - break; - } - } - } - if (bank == gNoOfAllBanks) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkDC_setgrudge(void) -{ - if (gStatuses3[gBankAttacker] & STATUS3_GRUDGE) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gStatuses3[gBankAttacker] |= STATUS3_GRUDGE; - gBattlescriptCurrInstr += 5; - } -} - -static void atkDD_weightdamagecalculation(void) -{ - s32 i; - for (i = 0; sWeightToDamageTable[i] != 0xFFFF; i += 2) - { - if (sWeightToDamageTable[i] > GetPokedexHeightWeight(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 1)) - break; - } - - if (sWeightToDamageTable[i] != 0xFFFF) - gDynamicBasePower = sWeightToDamageTable[i + 1]; - else - gDynamicBasePower = 120; - - gBattlescriptCurrInstr++; -} - -static void atkDE_asistattackselect(void) -{ - s32 chooseableMovesNo = 0; - struct Pokemon* party; - s32 monId, moveId; - u16* movesArray = gBattleStruct->assistPossibleMoves; - - if (GET_BANK_SIDE(gBankAttacker) != SIDE_PLAYER) - party = gEnemyParty; - else - party = gPlayerParty; - - for (monId = 0; monId < 6; monId++) - { - if (monId == gBattlePartyID[gBankAttacker]) - continue; - if (GetMonData(&party[monId], MON_DATA_SPECIES2) == SPECIES_NONE) - continue; - if (GetMonData(&party[monId], MON_DATA_SPECIES2) == SPECIES_EGG) - continue; - - for (moveId = 0; moveId < 4; moveId++) - { - s32 i = 0; - u16 move = GetMonData(&party[monId], MON_DATA_MOVE1 + moveId); - - if (IsInvalidForSleepTalkOrAssist(move)) - continue; - - for (; sMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END && move != sMovesForbiddenToCopy[i]; i++); - - if (sMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END) - continue; - if (move == MOVE_NONE) - continue; - - movesArray[chooseableMovesNo] = move; - chooseableMovesNo++; - } - } - if (chooseableMovesNo) - { - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gRandomMove = movesArray[((Random() & 0xFF) * chooseableMovesNo) >> 8]; - gBankTarget = GetMoveTarget(gRandomMove, 0); - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkDF_setmagiccoat(void) -{ - gBankTarget = gBankAttacker; - gSpecialStatuses[gBankAttacker].flag20 = 1; - if (gCurrentMoveTurn == gNoOfAllBanks - 1) // moves last turn - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gProtectStructs[gBankAttacker].bounceMove = 1; - gBattlescriptCurrInstr += 5; - } -} - -static void atkE0_setstealstatchange(void) // snatch -{ - gSpecialStatuses[gBankAttacker].flag20 = 1; - if (gCurrentMoveTurn == gNoOfAllBanks - 1) // moves last turn - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - gProtectStructs[gBankAttacker].stealMove = 1; - gBattlescriptCurrInstr += 5; - } -} - -static void atkE1_intimidate_string_loader(void) -{ - u8 side; - - gBattleScripting.bank = gBattleStruct->intimidateBank; - side = GetBankSide(gBattleScripting.bank); - - PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gBattleMons[gBattleScripting.bank].ability) - - for (;gBankTarget < gNoOfAllBanks; gBankTarget++) - { - if (GetBankSide(gBankTarget) == side) - continue; - if (!(gAbsentBankFlags & gBitTable[gBankTarget])) - break; - } - - if (gBankTarget >= gNoOfAllBanks) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; -} - -static void atkE2_switchout_abilities(void) -{ - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - switch (gBattleMons[gActiveBank].ability) - { - case ABILITY_NATURAL_CURE: - gBattleMons[gActiveBank].status1 = 0; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBank)], 4, &gBattleMons[gActiveBank].status1); - MarkBufferBankForExecution(gActiveBank); - break; - } - - gBattlescriptCurrInstr += 2; -} - -static void atkE3_jumpifhasnohp(void) -{ - gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); - - if (gBattleMons[gActiveBank].hp == 0) - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; -} - -static void atkE4_getsecretpowereffect(void) -{ - switch (gBattleTerrain) - { - case BATTLE_TERRAIN_GRASS: - gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_POISON; - break; - case BATTLE_TERRAIN_LONG_GRASS: - gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_SLEEP; - break; - case BATTLE_TERRAIN_SAND: - gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_ACC_MINUS_1; - break; - case BATTLE_TERRAIN_UNDERWATER: - gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_DEF_MINUS_1; - break; - case BATTLE_TERRAIN_WATER: - gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_ATK_MINUS_1; - break; - case BATTLE_TERRAIN_POND: - gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_SPD_MINUS_1; - break; - case BATTLE_TERRAIN_ROCK: - gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_CONFUSION; - break; - case BATTLE_TERRAIN_CAVE: - gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_FLINCH; - break; - default: - gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_PARALYSIS; - break; - } - gBattlescriptCurrInstr++; -} - -static void atkE5_pickup(void) -{ - if (!InBattlePike()) - { - s32 i; - u16 species, heldItem; - u8 ability; - - if (InBattlePyramid()) - { - for (i = 0; i < 6; i++) - { - species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); - heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); - - if (GetMonData(&gPlayerParty[i], MON_DATA_ALT_ABILITY)) - ability = gBaseStats[species].ability2; - else - ability = gBaseStats[species].ability1; - - if (ability == ABILITY_PICKUP - && species != 0 - && species != SPECIES_EGG - && heldItem == ITEM_NONE - && (Random() % 10) == 0) - { - heldItem = GetBattlePyramidPickupItemId(); - SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &heldItem); - } - } - } - else - { - for (i = 0; i < 6; i++) - { - species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); - heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); - - if (GetMonData(&gPlayerParty[i], MON_DATA_ALT_ABILITY)) - ability = gBaseStats[species].ability2; - else - ability = gBaseStats[species].ability1; - - if (ability == ABILITY_PICKUP - && species != 0 - && species != SPECIES_EGG - && heldItem == ITEM_NONE - && (Random() % 10) == 0) - { - s32 j; - s32 rand = Random() % 100; - u8 lvlDivBy10 = (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL) - 1) / 10; - if (lvlDivBy10 > 9) - lvlDivBy10 = 9; - - for (j = 0; j < 9; j++) - { - if (sPickupProbabilities[j] > rand) - { - SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sPickupItems[lvlDivBy10 + j]); - break; - } - else if (rand == 99 || rand == 98) - { - SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sRarePickupItems[lvlDivBy10 + (99 - rand)]); - break; - } - } - } - } - } - } - - gBattlescriptCurrInstr++; -} - -static void atkE6_castform_change_animation(void) -{ - gActiveBank = gBattleScripting.bank; - - if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE) - *(&gBattleStruct->formToChangeInto) |= 0x80; - - EmitBattleAnimation(0, B_ANIM_CASTFORM_CHANGE, gBattleStruct->formToChangeInto); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr++; -} - -static void atkE7_castform_data_change(void) -{ - u8 form; - - gBattlescriptCurrInstr++; - form = CastformDataTypeChange(gBattleScripting.bank); - if (form) - { - BattleScriptPushCursorAndCallback(BattleScript_CastformChange); - *(&gBattleStruct->formToChangeInto) = form - 1; - } -} - -static void atkE8_settypebasedhalvers(void) // water and mud sport -{ - bool8 worked = FALSE; - - if (gBattleMoves[gCurrentMove].effect == EFFECT_MUD_SPORT) - { - if (!(gStatuses3[gBankAttacker] & STATUS3_MUDSPORT)) - { - gStatuses3[gBankAttacker] |= STATUS3_MUDSPORT; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - worked = TRUE; - } - } - else // water sport - { - if (!(gStatuses3[gBankAttacker] & STATUS3_WATERSPORT)) - { - gStatuses3[gBankAttacker] |= STATUS3_WATERSPORT; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - worked = TRUE; - } - } - - if (worked) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); -} - -static void atkE9_setweatherballtype(void) -{ - if (WEATHER_HAS_EFFECT) - { - if (gBattleWeather & WEATHER_ANY) - gBattleScripting.dmgMultiplier = 2; - if (gBattleWeather & WEATHER_RAIN_ANY) - *(&gBattleStruct->dynamicMoveType) = TYPE_WATER | 0x80; - else if (gBattleWeather & WEATHER_SANDSTORM_ANY) - *(&gBattleStruct->dynamicMoveType) = TYPE_ROCK | 0x80; - else if (gBattleWeather & WEATHER_SUN_ANY) - *(&gBattleStruct->dynamicMoveType) = TYPE_FIRE | 0x80; - else if (gBattleWeather & WEATHER_HAIL_ANY) - *(&gBattleStruct->dynamicMoveType) = TYPE_ICE | 0x80; - else - *(&gBattleStruct->dynamicMoveType) = TYPE_NORMAL | 0x80; - } - - gBattlescriptCurrInstr++; -} - -static void atkEA_recycleitem(void) -{ - u16 *usedHeldItem; - - gActiveBank = gBankAttacker; - usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBank]; - if (*usedHeldItem != 0 && gBattleMons[gActiveBank].item == 0) - { - gLastUsedItem = *usedHeldItem; - *usedHeldItem = 0; - gBattleMons[gActiveBank].item = gLastUsedItem; - - EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBank].item); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkEB_settypetoterrain(void) -{ - if (gBattleMons[gBankAttacker].type1 != sTerrainToType[gBattleTerrain] - && gBattleMons[gBankAttacker].type2 != sTerrainToType[gBattleTerrain]) - { - gBattleMons[gBankAttacker].type1 = sTerrainToType[gBattleTerrain]; - gBattleMons[gBankAttacker].type2 = sTerrainToType[gBattleTerrain]; - - PREPARE_TYPE_BUFFER(gBattleTextBuff1, sTerrainToType[gBattleTerrain]) - - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkEC_pursuit_sth(void) -{ - gActiveBank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && !(gAbsentBankFlags & gBitTable[gActiveBank]) - && gActionForBanks[gActiveBank] == 0 - && gChosenMovesByBanks[gActiveBank] == MOVE_PURSUIT) - { - gUnknown_0202407A[gActiveBank] = 11; - gCurrentMove = MOVE_PURSUIT; - gBattlescriptCurrInstr += 5; - gBattleScripting.animTurn = 1; - gBattleScripting.field_20 = gBankAttacker; - gBankAttacker = gActiveBank; - } - else - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } -} - -static void atkED_802B4B4(void) -{ - gEffectBank = gBankAttacker; - - if (gBankAttacker == gBankTarget) - gBankAttacker = gBankTarget = gBattleScripting.bank; - else - gBankTarget = gBattleScripting.bank; - - gBattleScripting.bank = gEffectBank; - gBattlescriptCurrInstr++; -} - -static void atkEE_removelightscreenreflect(void) // brick break -{ - u8 opposingSide = GetBankSide(gBankAttacker) ^ BIT_SIDE; - - if (gSideTimers[opposingSide].reflectTimer || gSideTimers[opposingSide].lightscreenTimer) - { - gSideAffecting[opposingSide] &= ~(SIDE_STATUS_REFLECT); - gSideAffecting[opposingSide] &= ~(SIDE_STATUS_LIGHTSCREEN); - gSideTimers[opposingSide].reflectTimer = 0; - gSideTimers[opposingSide].lightscreenTimer = 0; - gBattleScripting.animTurn = 1; - gBattleScripting.animTargetsHit = 1; - } - else - { - gBattleScripting.animTurn = 0; - gBattleScripting.animTargetsHit = 0; - } - - gBattlescriptCurrInstr++; -} - -static void atkEF_pokeball_catch_calculation(void) -{ - u8 ballMultiplier = 0; - - if (gBattleExecBuffer) - return; - - gActiveBank = gBankAttacker; - gBankTarget = gBankAttacker ^ BIT_SIDE; - - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - { - EmitBallThrow(0, BALL_TRAINER_BLOCK); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr = BattleScript_TrainerBallBlock; - } - else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) - { - EmitBallThrow(0, BALL_3_SHAKES_SUCCESS); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr = BattleScript_WallyBallThrow; - } - else - { - u32 odds; - u8 catchRate; - - if (gLastUsedItem == ITEM_SAFARI_BALL) - catchRate = gBattleStruct->field_7C * 1275 / 100; - else - catchRate = gBaseStats[gBattleMons[gBankTarget].species].catchRate; - - if (gLastUsedItem > ITEM_SAFARI_BALL) - { - switch (gLastUsedItem) - { - case ITEM_NET_BALL: - if (gBattleMons[gBankTarget].type1 == TYPE_WATER - || gBattleMons[gBankTarget].type2 == TYPE_WATER - || gBattleMons[gBankTarget].type1 == TYPE_BUG - || gBattleMons[gBankTarget].type2 == TYPE_BUG) - ballMultiplier = 30; - else - ballMultiplier = 10; - break; - case ITEM_DIVE_BALL: - if (sav1_map_get_light_level() == 5) - ballMultiplier = 35; - else - ballMultiplier = 10; - break; - case ITEM_NEST_BALL: - if (gBattleMons[gBankTarget].level <= 39) - { - ballMultiplier = 40 - gBattleMons[gBankTarget].level; - if (ballMultiplier <= 9) - ballMultiplier = 10; - } - else - { - ballMultiplier = 10; - } - break; - case ITEM_REPEAT_BALL: - if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), FLAG_GET_CAUGHT)) - ballMultiplier = 30; - else - ballMultiplier = 10; - break; - case ITEM_TIMER_BALL: - ballMultiplier = gBattleResults.battleTurnCounter + 10; - if (ballMultiplier > 40) - ballMultiplier = 40; - break; - case ITEM_LUXURY_BALL: - case ITEM_PREMIER_BALL: - ballMultiplier = 10; - break; - } - } - else - ballMultiplier = sBallCatchBonuses[gLastUsedItem - 2]; - - odds = (catchRate * ballMultiplier / 10) - * (gBattleMons[gBankTarget].maxHP * 3 - gBattleMons[gBankTarget].hp * 2) - / (3 * gBattleMons[gBankTarget].maxHP); - - if (gBattleMons[gBankTarget].status1 & (STATUS_SLEEP | STATUS_FREEZE)) - odds *= 2; - if (gBattleMons[gBankTarget].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON)) - odds = (odds * 15) / 10; - - if (gLastUsedItem != ITEM_SAFARI_BALL) - { - if (gLastUsedItem == ITEM_MASTER_BALL) - { - gBattleResults.unk5_1 = 1; - } - else - { - if (gBattleResults.catchAttempts[gLastUsedItem - ITEM_ULTRA_BALL] < 0xFF) - gBattleResults.catchAttempts[gLastUsedItem - ITEM_ULTRA_BALL]++; - } - } - - if (odds > 254) // mon caught - { - EmitBallThrow(0, BALL_3_SHAKES_SUCCESS); - MarkBufferBankForExecution(gActiveBank); - gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; - SetMonData(&gEnemyParty[gBattlePartyID[gBankTarget]], MON_DATA_POKEBALL, &gLastUsedItem); - - if (CalculatePlayerPartyCount() == 6) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else // mon may be caught, calculate shakes - { - u8 shakes; - - odds = Sqrt(Sqrt(16711680 / odds)); - odds = 1048560 / odds; - - for (shakes = 0; shakes < 4 && Random() < odds; shakes++); - - if (gLastUsedItem == ITEM_MASTER_BALL) - shakes = BALL_3_SHAKES_SUCCESS; // why calculate the shakes before that check? - - EmitBallThrow(0, shakes); - MarkBufferBankForExecution(gActiveBank); - - if (shakes == BALL_3_SHAKES_SUCCESS) // mon caught, copy of the code above - { - gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; - SetMonData(&gEnemyParty[gBattlePartyID[gBankTarget]], MON_DATA_POKEBALL, &gLastUsedItem); - - if (CalculatePlayerPartyCount() == 6) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else // not caught - { - gBattleCommunication[MULTISTRING_CHOOSER] = shakes; - gBattlescriptCurrInstr = BattleScript_ShakeBallThrow; - } - } - } -} - -static void atkF0_give_caught_mon(void) -{ - if (GiveMonToPlayer(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]]) != MON_GIVEN_TO_PARTY) - { - if (!sub_813B21C()) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - StringCopy(gStringVar1, GetBoxNamePtr(VarGet(VAR_STORAGE_UNKNOWN))); - GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gStringVar2); - } - else - { - StringCopy(gStringVar1, GetBoxNamePtr(VarGet(VAR_STORAGE_UNKNOWN))); - GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gStringVar2); - StringCopy(gStringVar3, GetBoxNamePtr(get_unknown_box_id())); - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - - if (FlagGet(SYS_PC_LANETTE)) - gBattleCommunication[MULTISTRING_CHOOSER]++; - } - - gBattleResults.caughtMonSpecies = GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_SPECIES, NULL); - GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleResults.caughtMonNick); - gBattleResults.caughtMonBall = GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_POKEBALL, NULL); - - gBattlescriptCurrInstr++; -} - -static void atkF1_set_caught_mon_dex_flags(void) -{ - u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL); - u32 personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY, NULL); - - if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)) - { - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - else - { - HandleSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_SET_CAUGHT, personality); - gBattlescriptCurrInstr += 5; - } -} - -static void atkF2_display_dex_info(void) -{ - u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL); - - switch (gBattleCommunication[0]) - { - case 0: - BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); - gBattleCommunication[0]++; - break; - case 1: - if (!gPaletteFade.active) - { - FreeAllWindowBuffers(); - gBattleCommunication[TASK_ID] = CreateDexDisplayMonDataTask(SpeciesToNationalPokedexNum(species), - gBattleMons[gBankTarget].otId, - gBattleMons[gBankTarget].personality); - gBattleCommunication[0]++; - } - break; - case 2: - if (!gPaletteFade.active - && gMain.callback2 == BattleMainCB2 - && !gTasks[gBattleCommunication[TASK_ID]].isActive) - { - SetVBlankCallback(VBlankCB_Battle); - gBattleCommunication[0]++; - } - break; - case 3: - c2_berry_program_update_menu(); - sub_8035AA4(); - gBattle_BG3_X = 0x100; - gBattleCommunication[0]++; - break; - case 4: - if (!IsDma3ManagerBusyWithBgCopy()) - { - BeginNormalPaletteFade(0xFFFF, 0, 0x10, 0, 0); - ShowBg(0); - ShowBg(3); - gBattleCommunication[0]++; - } - break; - case 5: - if (!gPaletteFade.active) - gBattlescriptCurrInstr++; - break; - } -} - -void sub_8056A3C(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags) -{ - s32 destY, destX; - u16 var = 0; - - for (destY = yStart; destY <= yEnd; destY++) - { - for (destX = xStart; destX <= xEnd; destX++) - { - if (destY == yStart) - { - if (destX == xStart) - var = 0x1022; - else if (destX == xEnd) - var = 0x1024; - else - var = 0x1023; - } - else if (destY == yEnd) - { - if (destX == xStart) - var = 0x1028; - else if (destX == xEnd) - var = 0x102A; - else - var = 0x1029; - } - else - { - if (destX == xStart) - var = 0x1025; - else if (destX == xEnd) - var = 0x1027; - else - var = 0x1026; - } - - if (flags & 1) - var = 0; - - if (flags & 0x80) - CopyToBgTilemapBufferRect_ChangePalette(1, &var, destX, destY, 1, 1, 0x11); - else - CopyToBgTilemapBufferRect_ChangePalette(0, &var, destX, destY, 1, 1, 0x11); - } - } -} - -void BattleCreateCursorAt(u8 cursorPosition) -{ - u16 src[2]; - src[0] = 1; - src[1] = 2; - - CopyToBgTilemapBufferRect_ChangePalette(0, src, 0x19, 9 + (2 * cursorPosition), 1, 2, 0x11); - CopyBgTilemapBufferToVram(0); -} - -void BattleDestroyCursorAt(u8 cursorPosition) -{ - u16 src[2]; - src[0] = 0x1016; - src[1] = 0x1016; - - CopyToBgTilemapBufferRect_ChangePalette(0, src, 0x19, 9 + (2 * cursorPosition), 1, 2, 0x11); - CopyBgTilemapBufferToVram(0); -} - -static void atkF3_nickname_caught_poke(void) -{ - switch (gBattleCommunication[MULTIUSE_STATE]) - { - case 0: - sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); - sub_814F9EC(gText_BattleYesNoChoice, 0xC); - gBattleCommunication[MULTIUSE_STATE]++; - gBattleCommunication[CURSOR_POSITION] = 0; - BattleCreateCursorAt(0); - break; - case 1: - if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) - { - PlaySE(SE_SELECT); - BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); - gBattleCommunication[CURSOR_POSITION] = 0; - BattleCreateCursorAt(0); - } - if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) - { - PlaySE(SE_SELECT); - BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); - gBattleCommunication[CURSOR_POSITION] = 1; - BattleCreateCursorAt(1); - } - if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - if (gBattleCommunication[CURSOR_POSITION] == 0) - { - gBattleCommunication[MULTIUSE_STATE]++; - BeginFastPaletteFade(3); - } - else - { - gBattleCommunication[MULTIUSE_STATE] = 4; - } - } - else if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - gBattleCommunication[MULTIUSE_STATE] = 4; - } - break; - case 2: - if (!gPaletteFade.active) - { - GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleStruct->caughtMonNick); - FreeAllWindowBuffers(); - - DoNamingScreen(NAMING_SCREEN_CAUGHT_MON, gBattleStruct->caughtMonNick, - GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_SPECIES), - GetMonGender(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]]), - GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_PERSONALITY, NULL), - BattleMainCB2); - - gBattleCommunication[MULTIUSE_STATE]++; - } - break; - case 3: - if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active ) - { - SetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleStruct->caughtMonNick); - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - } - break; - case 4: - if (CalculatePlayerPartyCount() == 6) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - break; - } -} - -static void atkF4_subattackerhpbydmg(void) -{ - gBattleMons[gBankAttacker].hp -= gBattleMoveDamage; - gBattlescriptCurrInstr++; -} - -static void atkF5_removeattackerstatus1(void) -{ - gBattleMons[gBankAttacker].status1 = 0; - gBattlescriptCurrInstr++; -} - -static void atkF6_802BF48(void) -{ - gFightStateTracker = 0xC; -} - -static void atkF7_802BF54(void) -{ - gFightStateTracker = 0xC; - gCurrentMoveTurn = gNoOfAllBanks; -} - -static void atkF8_trainer_slide_back(void) -{ - gActiveBank = GetBankByIdentity(gBattlescriptCurrInstr[1]); - EmitTrainerSlideBack(0); - MarkBufferBankForExecution(gActiveBank); - - gBattlescriptCurrInstr += 2; -} diff --git a/src/battle_ai.c b/src/battle_ai.c deleted file mode 100644 index 8590b0f03..000000000 --- a/src/battle_ai.c +++ /dev/null @@ -1,2922 +0,0 @@ -#include "global.h" -#include "battle_ai.h" -#include "pokemon.h" -#include "battle.h" -#include "species.h" -#include "abilities.h" -#include "rng.h" -#include "item.h" -#include "battle_move_effects.h" - -#define AIScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) -#define AIScriptRead16(ptr) ((ptr)[0] | (ptr)[1] << 8) -#define AIScriptRead8(ptr) ((ptr)[0]) -#define AIScriptReadPtr(ptr) (u8*) AIScriptRead32(ptr) - -#define AI_ACTION_DONE 0x0001 -#define AI_ACTION_FLEE 0x0002 -#define AI_ACTION_WATCH 0x0004 -#define AI_ACTION_DO_NOT_ATTACK 0x0008 -#define AI_ACTION_UNK5 0x0010 -#define AI_ACTION_UNK6 0x0020 -#define AI_ACTION_UNK7 0x0040 -#define AI_ACTION_UNK8 0x0080 - -#define AI_THINKING_STRUCT ((struct AI_ThinkingStruct *)(gBattleResources->ai)) -#define BATTLE_HISTORY ((struct BattleHistory *)(gBattleResources->battleHistory)) - -enum -{ - AI_TARGET, - AI_USER, - AI_TARGET_PARTNER, - AI_USER_PARTNER -}; - -// AI states -enum -{ - AIState_SettingUp, - AIState_Processing, - AIState_FinishedProcessing, - AIState_DoNotProcess -}; - -/* -gAIScriptPtr is a pointer to the next battle AI cmd command to read. -when a command finishes processing, gAIScriptPtr is incremented by -the number of bytes that the current command had reserved for arguments -in order to read the next command correctly. refer to battle_ai_scripts.s for the -AI scripts. -*/ - -extern u32 gBattleTypeFlags; -extern u8 gActiveBank; -extern struct BattlePokemon gBattleMons[4]; -extern u16 gCurrentMove; -extern u8 gBankTarget; -extern u8 gAbsentBankFlags; -extern u16 gLastUsedMovesByBanks[4]; -extern u16 gTrainerBattleOpponent_A; -extern u16 gTrainerBattleOpponent_B; -extern u32 gStatuses3[4]; -extern u16 gSideAffecting[2]; -extern u16 gBattlePartyID[4]; -extern u16 gDynamicBasePower; -extern u8 gBattleMoveFlags; -extern s32 gBattleMoveDamage; -extern u8 gCritMultiplier; -extern u16 gBattleWeather; - -extern const struct BattleMove gBattleMoves[]; -extern const struct BaseStats gBaseStats[]; -extern const u32 gBitTable[]; -extern u8 * const gBattleAI_ScriptsTable[]; - -extern u8 b_first_side(u8, u8, u8); -extern void AI_CalcDmg(u8, u8); - -extern u8 CheckMoveLimitations(); -extern u32 GetAiScriptsInRecordedBattle(); -extern u32 GetAiScriptsInBattleFactory(); - -static u8 BattleAI_ChooseMoveOrAction_Singles(void); -static u8 BattleAI_ChooseMoveOrAction_Doubles(void); -static void RecordLastUsedMoveByTarget(void); -static void BattleAI_DoAIProcessing(void); -static void AIStackPushVar(const u8 *); -static bool8 AIStackPop(void); - -static void BattleAICmd_if_random_less_than(void); -static void BattleAICmd_if_random_greater_than(void); -static void BattleAICmd_if_random_equal(void); -static void BattleAICmd_if_random_not_equal(void); -static void BattleAICmd_score(void); -static void BattleAICmd_if_hp_less_than(void); -static void BattleAICmd_if_hp_more_than(void); -static void BattleAICmd_if_hp_equal(void); -static void BattleAICmd_if_hp_not_equal(void); -static void BattleAICmd_if_status(void); -static void BattleAICmd_if_not_status(void); -static void BattleAICmd_if_status2(void); -static void BattleAICmd_if_not_status2(void); -static void BattleAICmd_if_status3(void); -static void BattleAICmd_if_not_status3(void); -static void BattleAICmd_if_side_affecting(void); -static void BattleAICmd_if_not_side_affecting(void); -static void BattleAICmd_if_less_than(void); -static void BattleAICmd_if_more_than(void); -static void BattleAICmd_if_equal(void); -static void BattleAICmd_if_not_equal(void); -static void BattleAICmd_if_less_than_32(void); -static void BattleAICmd_if_more_than_32(void); -static void BattleAICmd_if_equal_32(void); -static void BattleAICmd_if_not_equal_32(void); -static void BattleAICmd_if_move(void); -static void BattleAICmd_if_not_move(void); -static void BattleAICmd_if_in_bytes(void); -static void BattleAICmd_if_not_in_bytes(void); -static void BattleAICmd_if_in_words(void); -static void BattleAICmd_if_not_in_words(void); -static void BattleAICmd_if_user_can_damage(void); -static void BattleAICmd_if_user_cant_damage(void); -static void BattleAICmd_get_turn_count(void); -static void BattleAICmd_get_type(void); -static void BattleAICmd_get_last_used_bank_move_power(void); -static void BattleAICmd_is_most_powerful_move(void); -static void BattleAICmd_get_last_used_bank_move(void); -static void BattleAICmd_if_arg_equal(void); -static void BattleAICmd_if_arg_not_equal(void); -static void BattleAICmd_if_would_go_first(void); -static void BattleAICmd_if_would_not_go_first(void); -static void BattleAICmd_nullsub_2A(void); -static void BattleAICmd_nullsub_2B(void); -static void BattleAICmd_count_alive_pokemon(void); -static void BattleAICmd_get_considered_move(void); -static void BattleAICmd_get_considered_move_effect(void); -static void BattleAICmd_get_ability(void); -static void BattleAICmd_get_highest_type_effectiveness(void); -static void BattleAICmd_if_type_effectiveness(void); -static void BattleAICmd_nullsub_32(void); -static void BattleAICmd_nullsub_33(void); -static void BattleAICmd_if_status_in_party(void); -static void BattleAICmd_if_status_not_in_party(void); -static void BattleAICmd_get_weather(void); -static void BattleAICmd_if_effect(void); -static void BattleAICmd_if_not_effect(void); -static void BattleAICmd_if_stat_level_less_than(void); -static void BattleAICmd_if_stat_level_more_than(void); -static void BattleAICmd_if_stat_level_equal(void); -static void BattleAICmd_if_stat_level_not_equal(void); -static void BattleAICmd_if_can_faint(void); -static void BattleAICmd_if_cant_faint(void); -static void BattleAICmd_if_has_move(void); -static void BattleAICmd_if_dont_have_move(void); -static void BattleAICmd_if_move_effect(void); -static void BattleAICmd_if_not_move_effect(void); -static void BattleAICmd_if_any_move_disabled_or_encored(void); -static void BattleAICmd_if_curr_move_disabled_or_encored(void); -static void BattleAICmd_flee(void); -static void BattleAICmd_if_random_100(void); -static void BattleAICmd_watch(void); -static void BattleAICmd_get_hold_effect(void); -static void BattleAICmd_get_gender(void); -static void BattleAICmd_is_first_turn(void); -static void BattleAICmd_get_stockpile_count(void); -static void BattleAICmd_is_double_battle(void); -static void BattleAICmd_get_used_held_item(void); -static void BattleAICmd_get_move_type_from_result(void); -static void BattleAICmd_get_move_power_from_result(void); -static void BattleAICmd_get_move_effect_from_result(void); -static void BattleAICmd_get_protect_count(void); -static void BattleAICmd_nullsub_52(void); -static void BattleAICmd_nullsub_53(void); -static void BattleAICmd_nullsub_54(void); -static void BattleAICmd_nullsub_55(void); -static void BattleAICmd_nullsub_56(void); -static void BattleAICmd_nullsub_57(void); -static void BattleAICmd_call(void); -static void BattleAICmd_jump(void); -static void BattleAICmd_end(void); -static void BattleAICmd_if_level_cond(void); -static void BattleAICmd_if_target_taunted(void); -static void BattleAICmd_if_target_not_taunted(void); -static void BattleAICmd_check_ability(void); -static void BattleAICmd_is_of_type(void); -static void BattleAICmd_if_target_is_ally(void); -static void BattleAICmd_if_flash_fired(void); -static void BattleAICmd_if_holds_item(void); - -// ewram - -EWRAM_DATA const u8 *gAIScriptPtr = NULL; -EWRAM_DATA static u8 sBank_AI = 0; - -// const rom data - -typedef void (*BattleAICmdFunc)(void); - -static const BattleAICmdFunc sBattleAICmdTable[] = -{ - BattleAICmd_if_random_less_than, // 0x0 - BattleAICmd_if_random_greater_than, // 0x1 - BattleAICmd_if_random_equal, // 0x2 - BattleAICmd_if_random_not_equal, // 0x3 - BattleAICmd_score, // 0x4 - BattleAICmd_if_hp_less_than, // 0x5 - BattleAICmd_if_hp_more_than, // 0x6 - BattleAICmd_if_hp_equal, // 0x7 - BattleAICmd_if_hp_not_equal, // 0x8 - BattleAICmd_if_status, // 0x9 - BattleAICmd_if_not_status, // 0xA - BattleAICmd_if_status2, // 0xB - BattleAICmd_if_not_status2, // 0xC - BattleAICmd_if_status3, // 0xD - BattleAICmd_if_not_status3, // 0xE - BattleAICmd_if_side_affecting, // 0xF - BattleAICmd_if_not_side_affecting, // 0x10 - BattleAICmd_if_less_than, // 0x11 - BattleAICmd_if_more_than, // 0x12 - BattleAICmd_if_equal, // 0x13 - BattleAICmd_if_not_equal, // 0x14 - BattleAICmd_if_less_than_32, // 0x15 - BattleAICmd_if_more_than_32, // 0x16 - BattleAICmd_if_equal_32, // 0x17 - BattleAICmd_if_not_equal_32, // 0x18 - BattleAICmd_if_move, // 0x19 - BattleAICmd_if_not_move, // 0x1A - BattleAICmd_if_in_bytes, // 0x1B - BattleAICmd_if_not_in_bytes, // 0x1C - BattleAICmd_if_in_words, // 0x1D - BattleAICmd_if_not_in_words, // 0x1E - BattleAICmd_if_user_can_damage, // 0x1F - BattleAICmd_if_user_cant_damage, // 0x20 - BattleAICmd_get_turn_count, // 0x21 - BattleAICmd_get_type, // 0x22 - BattleAICmd_get_last_used_bank_move_power, // 0x23 - BattleAICmd_is_most_powerful_move, // 0x24 - BattleAICmd_get_last_used_bank_move, // 0x25 - BattleAICmd_if_arg_equal, // 0x26 - BattleAICmd_if_arg_not_equal, // 0x27 - BattleAICmd_if_would_go_first, // 0x28 - BattleAICmd_if_would_not_go_first, // 0x29 - BattleAICmd_nullsub_2A, // 0x2A - BattleAICmd_nullsub_2B, // 0x2B - BattleAICmd_count_alive_pokemon, // 0x2C - BattleAICmd_get_considered_move, // 0x2D - BattleAICmd_get_considered_move_effect, // 0x2E - BattleAICmd_get_ability, // 0x2F - BattleAICmd_get_highest_type_effectiveness, // 0x30 - BattleAICmd_if_type_effectiveness, // 0x31 - BattleAICmd_nullsub_32, // 0x32 - BattleAICmd_nullsub_33, // 0x33 - BattleAICmd_if_status_in_party, // 0x34 - BattleAICmd_if_status_not_in_party, // 0x35 - BattleAICmd_get_weather, // 0x36 - BattleAICmd_if_effect, // 0x37 - BattleAICmd_if_not_effect, // 0x38 - BattleAICmd_if_stat_level_less_than, // 0x39 - BattleAICmd_if_stat_level_more_than, // 0x3A - BattleAICmd_if_stat_level_equal, // 0x3B - BattleAICmd_if_stat_level_not_equal, // 0x3C - BattleAICmd_if_can_faint, // 0x3D - BattleAICmd_if_cant_faint, // 0x3E - BattleAICmd_if_has_move, // 0x3F - BattleAICmd_if_dont_have_move, // 0x40 - BattleAICmd_if_move_effect, // 0x41 - BattleAICmd_if_not_move_effect, // 0x42 - BattleAICmd_if_any_move_disabled_or_encored, // 0x43 - BattleAICmd_if_curr_move_disabled_or_encored, // 0x44 - BattleAICmd_flee, // 0x45 - BattleAICmd_if_random_100, // 0x46 - BattleAICmd_watch, // 0x47 - BattleAICmd_get_hold_effect, // 0x48 - BattleAICmd_get_gender, // 0x49 - BattleAICmd_is_first_turn, // 0x4A - BattleAICmd_get_stockpile_count, // 0x4B - BattleAICmd_is_double_battle, // 0x4C - BattleAICmd_get_used_held_item, // 0x4D - BattleAICmd_get_move_type_from_result, // 0x4E - BattleAICmd_get_move_power_from_result, // 0x4F - BattleAICmd_get_move_effect_from_result, // 0x50 - BattleAICmd_get_protect_count, // 0x51 - BattleAICmd_nullsub_52, // 0x52 - BattleAICmd_nullsub_53, // 0x53 - BattleAICmd_nullsub_54, // 0x54 - BattleAICmd_nullsub_55, // 0x55 - BattleAICmd_nullsub_56, // 0x56 - BattleAICmd_nullsub_57, // 0x57 - BattleAICmd_call, // 0x58 - BattleAICmd_jump, // 0x59 - BattleAICmd_end, // 0x5A - BattleAICmd_if_level_cond, // 0x5B - BattleAICmd_if_target_taunted, // 0x5C - BattleAICmd_if_target_not_taunted, // 0x5D - BattleAICmd_if_target_is_ally, // 0x5E - BattleAICmd_is_of_type, // 0x5F - BattleAICmd_check_ability, // 0x60 - BattleAICmd_if_flash_fired, // 0x61 - BattleAICmd_if_holds_item, // 0x62 -}; - -static const u16 sDiscouragedPowerfulMoveEffects[] = -{ - EFFECT_EXPLOSION, - EFFECT_DREAM_EATER, - EFFECT_RAZOR_WIND, - EFFECT_SKY_ATTACK, - EFFECT_RECHARGE, - EFFECT_SKULL_BASH, - EFFECT_SOLARBEAM, - EFFECT_SPIT_UP, - EFFECT_FOCUS_PUNCH, - EFFECT_SUPERPOWER, - EFFECT_ERUPTION, - EFFECT_OVERHEAT, - 0xFFFF -}; - -void BattleAI_HandleItemUseBeforeAISetup(u8 defaultScoreMoves) -{ - s32 i; - u8 *data = (u8 *)gBattleResources->battleHistory; - - for (i = 0; i < sizeof(struct BattleHistory); i++) - data[i] = 0; - // items are allowed to use in ONLY trainer battles - if ((gBattleTypeFlags & - (BATTLE_TYPE_LINK | BATTLE_TYPE_SAFARI | BATTLE_TYPE_BATTLE_TOWER | - BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_FRONTIER - | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_x2000000 | BATTLE_TYPE_SECRET_BASE)) - == BATTLE_TYPE_TRAINER) - { - for (i = 0; i < 4; i++) - { - if (gTrainers[gTrainerBattleOpponent_A].items[i] != 0) - { - gBattleResources->battleHistory->TrainerItems[gBattleResources->battleHistory->itemsNo] = gTrainers[gTrainerBattleOpponent_A].items[i]; - gBattleResources->battleHistory->itemsNo++; - } - } - } - - BattleAI_SetupAIData(defaultScoreMoves); -} - -void BattleAI_SetupAIData(u8 defaultScoreMoves) -{ - s32 i; - u8 *data = (u8 *)AI_THINKING_STRUCT; - u8 moveLimitations; - - // clear AI data. - for (i = 0; i < sizeof(struct AI_ThinkingStruct); i++) - data[i] = 0; - - // conditional score reset, unlike Ruby. - for (i = 0; i < 4; i++) - { - if (defaultScoreMoves & 1) - AI_THINKING_STRUCT->score[i] = 100; - else - AI_THINKING_STRUCT->score[i] = 0; - defaultScoreMoves >>= 1; - } - - moveLimitations = CheckMoveLimitations(gActiveBank, 0, 0xFF); - - // ignore moves that aren't possible to use - for (i = 0; i < 4; i++) - { - if (gBitTable[i] & moveLimitations) - AI_THINKING_STRUCT->score[i] = 0; - - AI_THINKING_STRUCT->simulatedRNG[i] = 100 - (Random() % 16); - } - gBattleResources->AI_ScriptsStack->size = 0; - sBank_AI = gActiveBank; - // decide a random target bank in doubles - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - gBankTarget = (Random() & 2) + (GetBankSide(gActiveBank) ^ 1); - if (gAbsentBankFlags & gBitTable[gBankTarget]) - gBankTarget ^= 2; - } - // in singles there's only one choice - else - gBankTarget = sBank_AI ^ 1; - - if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) - AI_THINKING_STRUCT->aiFlags = GetAiScriptsInRecordedBattle(); - else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - AI_THINKING_STRUCT->aiFlags = 0x40000000; - else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) - AI_THINKING_STRUCT->aiFlags = 0x20000000; - else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) - AI_THINKING_STRUCT->aiFlags = 0x80000000; - else if (gBattleTypeFlags & BATTLE_TYPE_FACTORY) - AI_THINKING_STRUCT->aiFlags = GetAiScriptsInBattleFactory(); - else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_x4000000 | BATTLE_TYPE_SECRET_BASE)) - AI_THINKING_STRUCT->aiFlags = 7; // the smartest possible set - else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) - AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags | gTrainers[gTrainerBattleOpponent_B].aiFlags; - else - AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - AI_THINKING_STRUCT->aiFlags |= 0x80; // act smart in doubles and don't attack your partner -} - -u8 BattleAI_ChooseMoveOrAction(void) -{ - u16 savedCurrentMove = gCurrentMove; - u8 ret; - - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - ret = BattleAI_ChooseMoveOrAction_Singles(); - else - ret = BattleAI_ChooseMoveOrAction_Doubles(); - - gCurrentMove = savedCurrentMove; - return ret; -} - -static u8 BattleAI_ChooseMoveOrAction_Singles(void) -{ - u8 currentMoveArray[4]; - u8 consideredMoveArray[4]; - u8 numOfBestMoves; - s32 i; - - RecordLastUsedMoveByTarget(); - - while (AI_THINKING_STRUCT->aiFlags != 0) - { - if (AI_THINKING_STRUCT->aiFlags & 1) - { - AI_THINKING_STRUCT->aiState = AIState_SettingUp; - BattleAI_DoAIProcessing(); - } - AI_THINKING_STRUCT->aiFlags >>= 1; - AI_THINKING_STRUCT->aiLogicId++; - AI_THINKING_STRUCT->movesetIndex = 0; - } - - // special flags for safari - if (AI_THINKING_STRUCT->aiAction & AI_ACTION_FLEE) - return 4; - if (AI_THINKING_STRUCT->aiAction & AI_ACTION_WATCH) - return 5; - - numOfBestMoves = 1; - currentMoveArray[0] = AI_THINKING_STRUCT->score[0]; - consideredMoveArray[0] = 0; - - for (i = 1; i < 4; i++) - { - if (gBattleMons[sBank_AI].moves[i] != 0) // emerald adds an extra move ID check for some reason. - { - // in ruby, the order of these if statements are reversed. - if (currentMoveArray[0] == AI_THINKING_STRUCT->score[i]) - { - currentMoveArray[numOfBestMoves] = AI_THINKING_STRUCT->score[i]; - consideredMoveArray[numOfBestMoves++] = i; - } - if (currentMoveArray[0] < AI_THINKING_STRUCT->score[i]) - { - numOfBestMoves = 1; - currentMoveArray[0] = AI_THINKING_STRUCT->score[i]; - consideredMoveArray[0] = i; - } - } - } - return consideredMoveArray[Random() % numOfBestMoves]; -} - -#ifdef NONMATCHING -static u8 BattleAI_ChooseMoveOrAction_Doubles(void) -{ - s32 i; - s32 j; - s32 scriptsToRun; - s16 mostMovePoints; - s16 bestMovePointsForTarget[4]; - s8 mostViableTargetsArray[4]; - u8 actionOrMoveIndex[4]; - u8 mostViableMovesScores[4]; - u8 mostViableMovesIndices[4]; - s32 mostViableTargetsNo; - s32 mostViableMovesNo; - - for (i = 0; i < 4; i++) //08130D14 - { - if (i == sBank_AI || gBattleMons[i].hp == 0) - { - //_08130D2E - actionOrMoveIndex[i] = -1; - bestMovePointsForTarget[i] = -1; - } - //_08130D48 - else - { - if (gBattleTypeFlags & BATTLE_TYPE_PALACE) - BattleAI_SetupAIData(gBattleStruct->field_92 >> 4); - else - BattleAI_SetupAIData(0xF); - //_08130D76 - gBankTarget = i; - if ((i & 1) != (sBank_AI & 1)) - RecordLastUsedMoveByTarget(); - //_08130D90 - AI_THINKING_STRUCT->aiLogicId = 0; - AI_THINKING_STRUCT->movesetIndex = 0; - scriptsToRun = AI_THINKING_STRUCT->aiFlags; - while (scriptsToRun != 0) - { - if (scriptsToRun & 1) - { - AI_THINKING_STRUCT->aiState = AIState_SettingUp; - BattleAI_DoAIProcessing(); - } - scriptsToRun >>= 1; - AI_THINKING_STRUCT->aiLogicId++; - AI_THINKING_STRUCT->movesetIndex = 0; - } - //_08130DD8 - if (AI_THINKING_STRUCT->aiAction & AI_ACTION_FLEE) - actionOrMoveIndex[i] = 4; - else if (AI_THINKING_STRUCT->aiAction & AI_ACTION_WATCH) - actionOrMoveIndex[i] = 5; - else - { - //_08130E10 - mostViableMovesScores[0] = AI_THINKING_STRUCT->score[0]; - mostViableMovesIndices[0] = 0; - mostViableMovesNo = 1; - for (j = 1; j < 4; j++) - { - if (gBattleMons[sBank_AI].moves[j] != 0) - { - if (mostViableMovesScores[0] == AI_THINKING_STRUCT->score[j]) - { - mostViableMovesScores[mostViableMovesNo] = AI_THINKING_STRUCT->score[j]; - mostViableMovesIndices[mostViableMovesNo] = j; - mostViableMovesNo++; - } - if (mostViableMovesScores[0] < AI_THINKING_STRUCT->score[j]) - { - mostViableMovesScores[0] = AI_THINKING_STRUCT->score[j]; - mostViableMovesIndices[0] = j; - mostViableMovesNo = 1; - } - } - //_08130E72 - } - actionOrMoveIndex[i] = mostViableMovesIndices[Random() % mostViableMovesNo]; - bestMovePointsForTarget[i] = mostViableMovesScores[0]; - - // don't use a move against ally if it has less than 100 pts - if (i == (sBank_AI ^ 2) && bestMovePointsForTarget[i] < 100) - bestMovePointsForTarget[i] = -1; - } - } - //_08130EAE - } - - //08130EC4 - mostMovePoints = bestMovePointsForTarget[0]; - mostViableTargetsArray[0] = 0; - mostViableTargetsNo = 1; - for (i = 1; i < 4; i++) - { - //_08130EDA - if (mostMovePoints == bestMovePointsForTarget[i]) - { - mostViableTargetsArray[mostViableTargetsNo] = i; - mostViableTargetsNo++; - } - //_08130EEE - if (mostMovePoints < bestMovePointsForTarget[i]) - { - mostMovePoints = bestMovePointsForTarget[i]; - mostViableTargetsArray[0] = i; - mostViableTargetsNo = 1; - } - } - gBankTarget = mostViableTargetsArray[Random() % mostViableTargetsNo]; - return actionOrMoveIndex[gBankTarget]; -} -#else -__attribute__((naked)) -static u8 BattleAI_ChooseMoveOrAction_Doubles(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x24\n\ - movs r0, 0\n\ - mov r8, r0\n\ - mov r1, sp\n\ - adds r1, 0xC\n\ - str r1, [sp, 0x1C]\n\ - mov r2, sp\n\ - adds r2, 0x8\n\ - str r2, [sp, 0x18]\n\ - str r1, [sp, 0x20]\n\ - mov r10, sp\n\ -_08130D14:\n\ - ldr r0, =sBank_AI\n\ - ldrb r0, [r0]\n\ - cmp r8, r0\n\ - beq _08130D2E\n\ - movs r0, 0x58\n\ - mov r7, r8\n\ - muls r7, r0\n\ - adds r0, r7, 0\n\ - ldr r1, =gBattleMons\n\ - adds r0, r1\n\ - ldrh r0, [r0, 0x28]\n\ - cmp r0, 0\n\ - bne _08130D48\n\ -_08130D2E:\n\ - movs r0, 0xFF\n\ - ldr r2, [sp, 0x20]\n\ - strb r0, [r2]\n\ - ldr r0, =0x0000ffff\n\ - mov r7, r10\n\ - strh r0, [r7]\n\ - b _08130EAE\n\ - .pool\n\ -_08130D48:\n\ - ldr r0, =gBattleTypeFlags\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 10\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08130D70\n\ - ldr r0, =gBattleStruct\n\ - ldr r0, [r0]\n\ - adds r0, 0x92\n\ - ldrb r0, [r0]\n\ - lsrs r0, 4\n\ - bl BattleAI_SetupAIData\n\ - b _08130D76\n\ - .pool\n\ -_08130D70:\n\ - movs r0, 0xF\n\ - bl BattleAI_SetupAIData\n\ -_08130D76:\n\ - ldr r0, =gBankTarget\n\ - mov r1, r8\n\ - strb r1, [r0]\n\ - movs r1, 0x1\n\ - mov r2, r8\n\ - ands r2, r1\n\ - ldr r0, =sBank_AI\n\ - ldrb r0, [r0]\n\ - ands r1, r0\n\ - cmp r2, r1\n\ - beq _08130D90\n\ - bl RecordLastUsedMoveByTarget\n\ -_08130D90:\n\ - ldr r2, =gBattleResources\n\ - ldr r0, [r2]\n\ - ldr r0, [r0, 0x14]\n\ - movs r1, 0\n\ - strb r1, [r0, 0x11]\n\ - ldr r0, [r2]\n\ - ldr r0, [r0, 0x14]\n\ - strb r1, [r0, 0x1]\n\ - ldr r0, [r2]\n\ - ldr r0, [r0, 0x14]\n\ - ldr r4, [r0, 0xC]\n\ - mov r9, r2\n\ - cmp r4, 0\n\ - beq _08130DD8\n\ - mov r5, r9\n\ - movs r6, 0\n\ -_08130DB0:\n\ - movs r0, 0x1\n\ - ands r0, r4\n\ - cmp r0, 0\n\ - beq _08130DC2\n\ - ldr r0, [r5]\n\ - ldr r0, [r0, 0x14]\n\ - strb r6, [r0]\n\ - bl BattleAI_DoAIProcessing\n\ -_08130DC2:\n\ - asrs r4, 1\n\ - ldr r0, [r5]\n\ - ldr r1, [r0, 0x14]\n\ - ldrb r0, [r1, 0x11]\n\ - adds r0, 0x1\n\ - strb r0, [r1, 0x11]\n\ - ldr r0, [r5]\n\ - ldr r0, [r0, 0x14]\n\ - strb r6, [r0, 0x1]\n\ - cmp r4, 0\n\ - bne _08130DB0\n\ -_08130DD8:\n\ - mov r2, r9\n\ - ldr r0, [r2]\n\ - ldr r3, [r0, 0x14]\n\ - ldrb r1, [r3, 0x10]\n\ - movs r0, 0x2\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08130DFC\n\ - movs r0, 0x4\n\ - ldr r7, [sp, 0x20]\n\ - strb r0, [r7]\n\ - b _08130EAE\n\ - .pool\n\ -_08130DFC:\n\ - movs r0, 0x4\n\ - ands r0, r1\n\ - lsls r0, 24\n\ - lsrs r2, r0, 24\n\ - cmp r2, 0\n\ - beq _08130E10\n\ - movs r0, 0x5\n\ - ldr r1, [sp, 0x20]\n\ - strb r0, [r1]\n\ - b _08130EAE\n\ -_08130E10:\n\ - add r1, sp, 0x10\n\ - ldrb r0, [r3, 0x4]\n\ - strb r0, [r1]\n\ - add r0, sp, 0x14\n\ - strb r2, [r0]\n\ - movs r5, 0x1\n\ - movs r3, 0x1\n\ - adds r6, r1, 0\n\ - ldr r0, =sBank_AI\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - ldr r2, =gBattleMons + 0xC\n\ - adds r0, r2\n\ - adds r4, r0, 0x2\n\ - add r7, sp, 0x14\n\ -_08130E30:\n\ - ldrh r0, [r4]\n\ - cmp r0, 0\n\ - beq _08130E72\n\ - ldrb r1, [r6]\n\ - mov r2, r9\n\ - ldr r0, [r2]\n\ - ldr r0, [r0, 0x14]\n\ - adds r0, 0x4\n\ - adds r2, r0, r3\n\ - movs r0, 0\n\ - ldrsb r0, [r2, r0]\n\ - cmp r1, r0\n\ - bne _08130E56\n\ - adds r0, r6, r5\n\ - ldrb r1, [r2]\n\ - strb r1, [r0]\n\ - adds r0, r7, r5\n\ - strb r3, [r0]\n\ - adds r5, 0x1\n\ -_08130E56:\n\ - ldrb r1, [r6]\n\ - mov r2, r9\n\ - ldr r0, [r2]\n\ - ldr r0, [r0, 0x14]\n\ - adds r0, 0x4\n\ - adds r2, r0, r3\n\ - movs r0, 0\n\ - ldrsb r0, [r2, r0]\n\ - cmp r1, r0\n\ - bge _08130E72\n\ - ldrb r0, [r2]\n\ - strb r0, [r6]\n\ - strb r3, [r7]\n\ - movs r5, 0x1\n\ -_08130E72:\n\ - adds r4, 0x2\n\ - adds r3, 0x1\n\ - cmp r3, 0x3\n\ - ble _08130E30\n\ - bl Random\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - adds r1, r5, 0\n\ - bl __modsi3\n\ - add r0, sp\n\ - adds r0, 0x14\n\ - ldrb r0, [r0]\n\ - ldr r7, [sp, 0x20]\n\ - strb r0, [r7]\n\ - ldrb r2, [r6]\n\ - mov r0, r10\n\ - strh r2, [r0]\n\ - ldr r0, =sBank_AI\n\ - ldrb r1, [r0]\n\ - movs r0, 0x2\n\ - eors r0, r1\n\ - cmp r8, r0\n\ - bne _08130EAE\n\ - cmp r2, 0x63\n\ - bgt _08130EAE\n\ - ldr r0, =0x0000ffff\n\ - mov r1, r10\n\ - strh r0, [r1]\n\ -_08130EAE:\n\ - ldr r2, [sp, 0x20]\n\ - adds r2, 0x1\n\ - str r2, [sp, 0x20]\n\ - movs r7, 0x2\n\ - add r10, r7\n\ - movs r0, 0x1\n\ - add r8, r0\n\ - mov r1, r8\n\ - cmp r1, 0x3\n\ - bgt _08130EC4\n\ - b _08130D14\n\ -_08130EC4:\n\ - mov r0, sp\n\ - ldrh r5, [r0]\n\ - movs r0, 0\n\ - ldr r2, [sp, 0x18]\n\ - strb r0, [r2]\n\ - movs r4, 0x1\n\ - mov r8, r4\n\ - ldr r6, =gBankTarget\n\ - ldr r3, [sp, 0x18]\n\ - mov r1, sp\n\ - adds r1, 0x2\n\ -_08130EDA:\n\ - lsls r0, r5, 16\n\ - asrs r2, r0, 16\n\ - movs r7, 0\n\ - ldrsh r0, [r1, r7]\n\ - cmp r2, r0\n\ - bne _08130EEE\n\ - adds r0, r3, r4\n\ - mov r7, r8\n\ - strb r7, [r0]\n\ - adds r4, 0x1\n\ -_08130EEE:\n\ - movs r7, 0\n\ - ldrsh r0, [r1, r7]\n\ - cmp r2, r0\n\ - bge _08130EFE\n\ - ldrh r5, [r1]\n\ - mov r0, r8\n\ - strb r0, [r3]\n\ - movs r4, 0x1\n\ -_08130EFE:\n\ - adds r1, 0x2\n\ - movs r2, 0x1\n\ - add r8, r2\n\ - mov r7, r8\n\ - cmp r7, 0x3\n\ - ble _08130EDA\n\ - bl Random\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - adds r1, r4, 0\n\ - bl __modsi3\n\ - ldr r1, [sp, 0x18]\n\ - adds r0, r1, r0\n\ - ldrb r0, [r0]\n\ - strb r0, [r6]\n\ - ldrb r0, [r6]\n\ - ldr r2, [sp, 0x1C]\n\ - adds r0, r2, r0\n\ - ldrb r0, [r0]\n\ - add sp, 0x24\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r1}\n\ - bx r1\n\ - .pool\n\ - .syntax divided\n"); -} -#endif - -static void BattleAI_DoAIProcessing(void) -{ - while (AI_THINKING_STRUCT->aiState != AIState_FinishedProcessing) - { - switch (AI_THINKING_STRUCT->aiState) - { - case AIState_DoNotProcess: //Needed to match. - break; - case AIState_SettingUp: - gAIScriptPtr = gBattleAI_ScriptsTable[AI_THINKING_STRUCT->aiLogicId]; // set AI ptr to logic ID. - if (gBattleMons[sBank_AI].pp[AI_THINKING_STRUCT->movesetIndex] == 0) - { - AI_THINKING_STRUCT->moveConsidered = 0; - } - else - { - AI_THINKING_STRUCT->moveConsidered = gBattleMons[sBank_AI].moves[AI_THINKING_STRUCT->movesetIndex]; - } - AI_THINKING_STRUCT->aiState++; - break; - case AIState_Processing: - if (AI_THINKING_STRUCT->moveConsidered != 0) - sBattleAICmdTable[*gAIScriptPtr](); // run AI command. - else - { - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; - AI_THINKING_STRUCT->aiAction |= AI_ACTION_DONE; - } - if (AI_THINKING_STRUCT->aiAction & AI_ACTION_DONE) - { - AI_THINKING_STRUCT->movesetIndex++; - - if (AI_THINKING_STRUCT->movesetIndex < 4 && !(AI_THINKING_STRUCT->aiAction & AI_ACTION_DO_NOT_ATTACK)) - AI_THINKING_STRUCT->aiState = AIState_SettingUp; - else - AI_THINKING_STRUCT->aiState++; - - AI_THINKING_STRUCT->aiAction &= ~(AI_ACTION_DONE); - } - break; - } - } -} - -static void RecordLastUsedMoveByTarget(void) -{ - s32 i; - - for (i = 0; i < 4; i++) - { - if (gBattleResources->battleHistory->usedMoves[gBankTarget].moves[i] == gLastUsedMovesByBanks[gBankTarget]) - break; - if (gBattleResources->battleHistory->usedMoves[gBankTarget].moves[i] != gLastUsedMovesByBanks[gBankTarget] //HACK: This redundant condition is a hack to make the asm match. - && gBattleResources->battleHistory->usedMoves[gBankTarget].moves[i] == 0) - { - gBattleResources->battleHistory->usedMoves[gBankTarget].moves[i] = gLastUsedMovesByBanks[gBankTarget]; - break; - } - } -} - -void ClearBankMoveHistory(u8 bank) -{ - s32 i; - - for (i = 0; i < 4; i++) - gBattleResources->battleHistory->usedMoves[bank].moves[i] = 0; -} - -void RecordAbilityBattle(u8 bank, u8 abilityId) -{ - gBattleResources->battleHistory->abilities[bank] = abilityId; -} - -void ClearBankAbilityHistory(u8 bank) -{ - gBattleResources->battleHistory->abilities[bank] = 0; -} - -void RecordItemEffectBattle(u8 bank, u8 itemEffect) -{ - gBattleResources->battleHistory->itemEffects[bank] = itemEffect; -} - -void ClearBankItemEffectHistory(u8 bank) -{ - gBattleResources->battleHistory->itemEffects[bank] = 0; -} - -static void BattleAICmd_if_random_less_than(void) -{ - u16 random = Random(); - - if (random % 256 < gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_random_greater_than(void) -{ - u16 random = Random(); - - if (random % 256 > gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_random_equal(void) -{ - u16 random = Random(); - - if (random % 256 == gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_random_not_equal(void) -{ - u16 random = Random(); - - if (random % 256 != gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_score(void) -{ - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] += gAIScriptPtr[1]; // add the result to the array of the move consider's score. - - if (AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] < 0) // if the score is negative, flatten it to 0. - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; - - gAIScriptPtr += 2; // AI return. -} - -static void BattleAICmd_if_hp_less_than(void) -{ - u16 index; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) < gAIScriptPtr[2]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_hp_more_than(void) -{ - u16 index; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) > gAIScriptPtr[2]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_hp_equal(void) -{ - u16 index; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) == gAIScriptPtr[2]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_hp_not_equal(void) -{ - u16 index; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) != gAIScriptPtr[2]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_status(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - arg = AIScriptRead32(gAIScriptPtr + 2); - - if ((gBattleMons[index].status1 & arg) != 0) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_not_status(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - arg = AIScriptRead32(gAIScriptPtr + 2); - - if ((gBattleMons[index].status1 & arg) == 0) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_status2(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - arg = AIScriptRead32(gAIScriptPtr + 2); - - if ((gBattleMons[index].status2 & arg) != 0) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_not_status2(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - arg = AIScriptRead32(gAIScriptPtr + 2); - - if ((gBattleMons[index].status2 & arg) == 0) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_status3(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - arg = AIScriptRead32(gAIScriptPtr + 2); - - if ((gStatuses3[index] & arg) != 0) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_not_status3(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - arg = AIScriptRead32(gAIScriptPtr + 2); - - if ((gStatuses3[index] & arg) == 0) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_side_affecting(void) -{ - u16 index; - u32 arg1, arg2; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - arg1 = GetBankIdentity(index) & 1; - arg2 = AIScriptRead32(gAIScriptPtr + 2); - - if ((gSideAffecting[arg1] & arg2) != 0) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_not_side_affecting(void) -{ - u16 index; - u32 arg1, arg2; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - arg1 = GetBankIdentity(index) & 1; - arg2 = AIScriptRead32(gAIScriptPtr + 2); - - if ((gSideAffecting[arg1] & arg2) == 0) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_less_than(void) -{ - if (AI_THINKING_STRUCT->funcResult < gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_more_than(void) -{ - if (AI_THINKING_STRUCT->funcResult > gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_equal(void) -{ - if (AI_THINKING_STRUCT->funcResult == gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_not_equal(void) -{ - if (AI_THINKING_STRUCT->funcResult != gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_less_than_32(void) -{ - u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult < *temp) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_more_than_32(void) -{ - u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult > *temp) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_equal_32(void) -{ - u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult == *temp) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_not_equal_32(void) -{ - u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult != *temp) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_move(void) -{ - u16 move = AIScriptRead16(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->moveConsidered == move) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_not_move(void) -{ - u16 move = AIScriptRead16(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->moveConsidered != move) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_in_bytes(void) -{ - u8 *ptr = AIScriptReadPtr(gAIScriptPtr + 1); - - while (*ptr != 0xFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); - return; - } - ptr++; - } - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_not_in_bytes(void) -{ - u8 *ptr = AIScriptReadPtr(gAIScriptPtr + 1); - - while (*ptr != 0xFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr += 9; - return; - } - ptr++; - } - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); -} - -static void BattleAICmd_if_in_words(void) -{ - u16 *ptr = (u16 *)AIScriptReadPtr(gAIScriptPtr + 1); - - while (*ptr != 0xFFFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); - return; - } - ptr++; - } - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_not_in_words(void) -{ - u16 *ptr = (u16 *)AIScriptReadPtr(gAIScriptPtr + 1); - - while (*ptr != 0xFFFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr += 9; - return; - } - ptr++; - } - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); -} - -static void BattleAICmd_if_user_can_damage(void) -{ - s32 i; - - for (i = 0; i < 4; i++) - { - if (gBattleMons[sBank_AI].moves[i] != 0 - && gBattleMoves[gBattleMons[sBank_AI].moves[i]].power != 0) - break; - } - if (i == 4) - gAIScriptPtr += 5; - else - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); -} - -static void BattleAICmd_if_user_cant_damage(void) -{ - s32 i; - - for (i = 0; i < 4; i++) - { - if (gBattleMons[sBank_AI].moves[i] != 0 - && gBattleMoves[gBattleMons[sBank_AI].moves[i]].power != 0) - break; - } - if (i != 4) - gAIScriptPtr += 5; - else - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); -} - -static void BattleAICmd_get_turn_count(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleResults.battleTurnCounter; - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_type(void) -{ - u8 typeVar = gAIScriptPtr[1]; - - switch (typeVar) - { - case 1: // player primary type - AI_THINKING_STRUCT->funcResult = gBattleMons[sBank_AI].type1; - break; - case 0: // enemy primary type - AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type1; - break; - case 3: // player secondary type - AI_THINKING_STRUCT->funcResult = gBattleMons[sBank_AI].type2; - break; - case 2: // enemy secondary type - AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type2; - break; - case 4: // type of move being pointed to - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].type; - break; - } - gAIScriptPtr += 2; -} - -static u8 BattleAI_GetWantedBank(u8 index) -{ - switch (index) - { - case AI_USER: - return sBank_AI; - case AI_TARGET: - default: - return gBankTarget; - case AI_USER_PARTNER: - return sBank_AI ^ 2; - case AI_TARGET_PARTNER: - return gBankTarget ^ 2; - } -} - -static void BattleAICmd_is_of_type(void) -{ - u8 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]); - - if(gBattleMons[bank].type1 == gAIScriptPtr[2] || gBattleMons[bank].type2 == gAIScriptPtr[2]) - { - AI_THINKING_STRUCT->funcResult = 1; - } - else - { - AI_THINKING_STRUCT->funcResult = 0; - } - - gAIScriptPtr += 3; -} - -static void BattleAICmd_get_last_used_bank_move_power(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power; - gAIScriptPtr += 1; -} - -__attribute__((naked)) // not even going to try. if it doesnt match in ruby, it wont match in emerald (yet). -static void BattleAICmd_is_most_powerful_move(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x14\n\ - movs r3, 0\n\ - ldr r0, =sDiscouragedPowerfulMoveEffects\n\ - ldrh r1, [r0]\n\ - ldr r5, =0x0000ffff\n\ - ldr r6, =gBattleMoves\n\ - ldr r2, =gBattleResources\n\ - cmp r1, r5\n\ - beq _08131F86\n\ - ldr r0, [r2]\n\ - ldr r0, [r0, 0x14]\n\ - ldrh r1, [r0, 0x2]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldrb r4, [r0]\n\ - ldr r1, =sDiscouragedPowerfulMoveEffects\n\ -_08131F76:\n\ - ldrh r0, [r1]\n\ - cmp r4, r0\n\ - beq _08131F86\n\ - adds r1, 0x2\n\ - adds r3, 0x1\n\ - ldrh r0, [r1]\n\ - cmp r0, r5\n\ - bne _08131F76\n\ -_08131F86:\n\ - ldr r0, [r2]\n\ - ldr r0, [r0, 0x14]\n\ - ldrh r1, [r0, 0x2]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldrb r0, [r0, 0x1]\n\ - cmp r0, 0x1\n\ - bhi _08131F9C\n\ - b _08132126\n\ -_08131F9C:\n\ - lsls r0, r3, 1\n\ - ldr r1, =sDiscouragedPowerfulMoveEffects\n\ - adds r0, r1\n\ - ldrh r3, [r0]\n\ - ldr r0, =0x0000ffff\n\ - cmp r3, r0\n\ - beq _08131FAC\n\ - b _08132126\n\ -_08131FAC:\n\ - ldr r0, =gDynamicBasePower\n\ - movs r1, 0\n\ - strh r1, [r0]\n\ - ldr r0, =gBattleStruct\n\ - ldr r0, [r0]\n\ - strb r1, [r0, 0x13]\n\ - ldr r0, =gBattleScripting\n\ - movs r2, 0x1\n\ - strb r2, [r0, 0xE]\n\ - ldr r0, =gBattleMoveFlags\n\ - strb r1, [r0]\n\ - ldr r0, =gCritMultiplier\n\ - strb r2, [r0]\n\ - movs r6, 0\n\ - mov r9, r3\n\ - ldr r2, =sDiscouragedPowerfulMoveEffects\n\ - ldrh r2, [r2]\n\ - str r2, [sp, 0x10]\n\ -_08131FD0:\n\ - movs r3, 0\n\ - ldr r5, =gBattleMons\n\ - lsls r4, r6, 1\n\ - ldr r7, =sBank_AI\n\ - lsls r0, r6, 2\n\ - mov r8, r0\n\ - adds r1, r6, 0x1\n\ - mov r10, r1\n\ - ldr r2, [sp, 0x10]\n\ - cmp r2, r9\n\ - beq _08132014\n\ - ldr r2, =gBattleMoves\n\ - ldrb r1, [r7]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r4, r0\n\ - adds r1, r5, 0\n\ - adds r1, 0xC\n\ - adds r0, r1\n\ - ldrh r1, [r0]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r2, [r0]\n\ - ldr r1, =sDiscouragedPowerfulMoveEffects\n\ -_08132004:\n\ - ldrh r0, [r1]\n\ - cmp r2, r0\n\ - beq _08132014\n\ - adds r1, 0x2\n\ - adds r3, 0x1\n\ - ldrh r0, [r1]\n\ - cmp r0, r9\n\ - bne _08132004\n\ -_08132014:\n\ - ldrb r1, [r7]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r4, r0\n\ - adds r1, r5, 0\n\ - adds r1, 0xC\n\ - adds r1, r0, r1\n\ - ldrh r0, [r1]\n\ - cmp r0, 0\n\ - beq _081320C0\n\ - lsls r0, r3, 1\n\ - ldr r2, =sDiscouragedPowerfulMoveEffects\n\ - adds r0, r2\n\ - ldrh r0, [r0]\n\ - cmp r0, r9\n\ - bne _081320C0\n\ - ldr r0, =gBattleMoves\n\ - ldrh r2, [r1]\n\ - lsls r1, r2, 1\n\ - adds r1, r2\n\ - lsls r1, 2\n\ - adds r1, r0\n\ - ldrb r0, [r1, 0x1]\n\ - cmp r0, 0x1\n\ - bls _081320C0\n\ - ldr r5, =gCurrentMove\n\ - strh r2, [r5]\n\ - ldrb r0, [r7]\n\ - ldr r4, =gBankTarget\n\ - ldrb r1, [r4]\n\ - bl AI_CalcDmg\n\ - ldrh r0, [r5]\n\ - ldrb r1, [r7]\n\ - ldrb r2, [r4]\n\ - bl TypeCalc\n\ - mov r4, sp\n\ - add r4, r8\n\ - ldr r2, =gBattleMoveDamage\n\ - ldr r0, =gBattleResources\n\ - ldr r0, [r0]\n\ - ldr r0, [r0, 0x14]\n\ - adds r0, 0x18\n\ - adds r0, r6\n\ - ldrb r1, [r0]\n\ - ldr r0, [r2]\n\ - muls r0, r1\n\ - movs r1, 0x64\n\ - bl __divsi3\n\ - str r0, [r4]\n\ - cmp r0, 0\n\ - bne _081320C8\n\ - movs r0, 0x1\n\ - str r0, [r4]\n\ - b _081320C8\n\ - .pool\n\ -_081320C0:\n\ - mov r1, sp\n\ - add r1, r8\n\ - movs r0, 0\n\ - str r0, [r1]\n\ -_081320C8:\n\ - mov r6, r10\n\ - cmp r6, 0x3\n\ - bgt _081320D0\n\ - b _08131FD0\n\ -_081320D0:\n\ - movs r6, 0\n\ - ldr r2, =gBattleResources\n\ - ldr r0, [r2]\n\ - ldr r0, [r0, 0x14]\n\ - ldrb r0, [r0, 0x1]\n\ - lsls r0, 2\n\ - add r0, sp\n\ - ldr r1, [sp]\n\ - ldr r0, [r0]\n\ - ldr r5, =gAIScriptPtr\n\ - cmp r1, r0\n\ - bgt _08132106\n\ - adds r4, r2, 0\n\ - mov r3, sp\n\ -_081320EC:\n\ - adds r3, 0x4\n\ - adds r6, 0x1\n\ - cmp r6, 0x3\n\ - bgt _08132106\n\ - ldr r0, [r4]\n\ - ldr r0, [r0, 0x14]\n\ - ldrb r0, [r0, 0x1]\n\ - lsls r0, 2\n\ - add r0, sp\n\ - ldr r1, [r3]\n\ - ldr r0, [r0]\n\ - cmp r1, r0\n\ - ble _081320EC\n\ -_08132106:\n\ - cmp r6, 0x4\n\ - bne _0813211C\n\ - ldr r0, [r2]\n\ - ldr r1, [r0, 0x14]\n\ - movs r0, 0x2\n\ - str r0, [r1, 0x8]\n\ - b _08132130\n\ - .pool\n\ -_0813211C:\n\ - ldr r0, [r2]\n\ - ldr r1, [r0, 0x14]\n\ - movs r0, 0x1\n\ - str r0, [r1, 0x8]\n\ - b _08132130\n\ -_08132126:\n\ - ldr r0, [r2]\n\ - ldr r1, [r0, 0x14]\n\ - movs r0, 0\n\ - str r0, [r1, 0x8]\n\ - ldr r5, =gAIScriptPtr\n\ -_08132130:\n\ - ldr r0, [r5]\n\ - adds r0, 0x1\n\ - str r0, [r5]\n\ - add sp, 0x14\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .pool\n\ - .syntax divided"); -} - -static void BattleAICmd_get_last_used_bank_move(void) -{ - if (gAIScriptPtr[1] == AI_USER) - AI_THINKING_STRUCT->funcResult = gLastUsedMovesByBanks[sBank_AI]; - else - AI_THINKING_STRUCT->funcResult = gLastUsedMovesByBanks[gBankTarget]; - - gAIScriptPtr += 2; -} - -static void BattleAICmd_if_arg_equal(void) -{ - if (gAIScriptPtr[1] == AI_THINKING_STRUCT->funcResult) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_arg_not_equal(void) -{ - if (gAIScriptPtr[1] != AI_THINKING_STRUCT->funcResult) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_would_go_first(void) -{ - if (b_first_side(sBank_AI, gBankTarget, 1) == gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_would_not_go_first(void) -{ - if (b_first_side(sBank_AI, gBankTarget, 1) != gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_nullsub_2A(void) -{ -} - -static void BattleAICmd_nullsub_2B(void) -{ -} - -static void BattleAICmd_count_alive_pokemon(void) -{ - u8 index; - u8 bankOnField1, bankOnField2; - struct Pokemon *party; - int i; - - AI_THINKING_STRUCT->funcResult = 0; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - if (GetBankSide(index) == 0) - party = gPlayerParty; - else - party = gEnemyParty; - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - u32 status; - bankOnField1 = gBattlePartyID[index]; - status = GetBankIdentity(index) ^ 2; - bankOnField2 = gBattlePartyID[GetBankByIdentity(status)]; - } - else // in singles there's only one bank by side - { - bankOnField1 = gBattlePartyID[index]; - bankOnField2 = gBattlePartyID[index]; - } - - for (i = 0; i < 6; i++) - { - if (i != bankOnField1 && i != bankOnField2 - && GetMonData(&party[i], MON_DATA_HP) != 0 - && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_NONE - && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) - { - AI_THINKING_STRUCT->funcResult++; - } - } - - gAIScriptPtr += 2; -} - -static void BattleAICmd_get_considered_move(void) -{ - AI_THINKING_STRUCT->funcResult = AI_THINKING_STRUCT->moveConsidered; - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_considered_move_effect(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect; - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_ability(void) -{ - u8 index; - - if (gAIScriptPtr[1] == AI_USER) - index = sBank_AI; - else - index = gBankTarget; - - if(gActiveBank != index) - { - if(BATTLE_HISTORY->abilities[index] != 0) - { - AI_THINKING_STRUCT->funcResult = BATTLE_HISTORY->abilities[index]; - gAIScriptPtr += 2; - return; - } - - // abilities that prevent fleeing. - if (gBattleMons[index].ability == ABILITY_SHADOW_TAG - || gBattleMons[index].ability == ABILITY_MAGNET_PULL - || gBattleMons[index].ability == ABILITY_ARENA_TRAP) - { - AI_THINKING_STRUCT->funcResult = gBattleMons[index].ability; - gAIScriptPtr += 2; - return; - } - - if (gBaseStats[gBattleMons[index].species].ability1 != ABILITY_NONE) - { - if (gBaseStats[gBattleMons[index].species].ability2 != ABILITY_NONE) - { - // AI has no knowledge of opponent, so it guesses which ability. - if (Random() & 1) - { - AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability1; - } - else - { - AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability2; - } - } - else - { - AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability1; // it's definitely ability 1. - } - } - else - { - AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability. - } - } - else - { - // The AI knows its own ability. - AI_THINKING_STRUCT->funcResult = gBattleMons[index].ability; - } - gAIScriptPtr += 2; -} - -#ifdef NONMATCHING -static void BattleAICmd_check_ability(void) -{ - u8 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]); - u8 ability = gAIScriptPtr[2]; - - if (gAIScriptPtr[1] == AI_TARGET || gAIScriptPtr[1] == AI_TARGET_PARTNER) - { - if (BATTLE_HISTORY->abilities[bank] != 0) - { - ability = BATTLE_HISTORY->abilities[bank]; - AI_THINKING_STRUCT->funcResult = ability; - } - // abilities that prevent fleeing. - else if (gBattleMons[bank].ability == ABILITY_SHADOW_TAG - || gBattleMons[bank].ability == ABILITY_MAGNET_PULL - || gBattleMons[bank].ability == ABILITY_ARENA_TRAP) - { - ability = gBattleMons[bank].ability; - } - else if (gBaseStats[gBattleMons[bank].species].ability1 != ABILITY_NONE) - { - if (gBaseStats[gBattleMons[bank].species].ability2 != ABILITY_NONE) - { - if (gBaseStats[gBattleMons[bank].species].ability1 != ability - && gBaseStats[gBattleMons[bank].species].ability2 != ability) - { - ability = gBaseStats[gBattleMons[bank].species].ability1; - } - else - ability = 0; - } - else - { - ability = gBaseStats[gBattleMons[bank].species].ability1; - } - } - else - { - ability = gBaseStats[gBattleMons[bank].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability. - } - } - else - { - // The AI knows its own or partner's ability. - ability = gBattleMons[bank].ability; - } - if (ability == 0) - { - AI_THINKING_STRUCT->funcResult = 2; // unable to answer - } - else if (ability == gAIScriptPtr[2]) - { - AI_THINKING_STRUCT->funcResult = 1; // pokemon has the ability we wanted to check - } - else - { - AI_THINKING_STRUCT->funcResult = 0; // pokemon doesn't have the ability we wanted to check - } - gAIScriptPtr += 3; -} -#else -__attribute__((naked)) -static void BattleAICmd_check_ability(void) -{ - asm(".syntax unified\n\ - push {r4-r6,lr}\n\ - ldr r4, =gAIScriptPtr\n\ - ldr r0, [r4]\n\ - ldrb r0, [r0, 0x1]\n\ - bl BattleAI_GetWantedBank\n\ - lsls r0, 24\n\ - lsrs r5, r0, 24\n\ - ldr r0, [r4]\n\ - ldrb r3, [r0, 0x2]\n\ - ldrb r0, [r0, 0x1]\n\ - cmp r0, 0\n\ - beq _0813253A\n\ - cmp r0, 0x2\n\ - bne _081325BC\n\ -_0813253A:\n\ - ldr r0, =gBattleResources\n\ - ldr r4, [r0]\n\ - ldr r1, [r4, 0x18]\n\ - adds r1, 0x40\n\ - adds r2, r1, r5\n\ - ldrb r1, [r2]\n\ - adds r6, r0, 0\n\ - cmp r1, 0\n\ - beq _0813255C\n\ - adds r3, r1, 0\n\ - ldr r0, [r4, 0x14]\n\ - str r3, [r0, 0x8]\n\ - b _081325CA\n\ - .pool\n\ -_0813255C:\n\ - ldr r1, =gBattleMons\n\ - movs r0, 0x58\n\ - muls r0, r5\n\ - adds r4, r0, r1\n\ - adds r0, r4, 0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x17\n\ - beq _08132576\n\ - cmp r0, 0x2A\n\ - beq _08132576\n\ - cmp r0, 0x47\n\ - bne _08132588\n\ -_08132576:\n\ - movs r0, 0x58\n\ - muls r0, r5\n\ - adds r0, r1\n\ - adds r0, 0x20\n\ - ldrb r3, [r0]\n\ - b _081325CA\n\ - .pool\n\ -_08132588:\n\ - ldr r2, =gBaseStats\n\ - ldrh r1, [r4]\n\ - lsls r0, r1, 3\n\ - subs r0, r1\n\ - lsls r0, 2\n\ - adds r1, r0, r2\n\ - ldrb r4, [r1, 0x16]\n\ - cmp r4, 0\n\ - beq _081325B8\n\ - ldrb r2, [r1, 0x17]\n\ - cmp r2, 0\n\ - beq _081325B4\n\ - adds r0, r3, 0\n\ - cmp r4, r0\n\ - beq _081325CE\n\ - cmp r2, r0\n\ - beq _081325CE\n\ - adds r3, r4, 0\n\ - b _081325CA\n\ - .pool\n\ -_081325B4:\n\ - ldrb r3, [r1, 0x16]\n\ - b _081325CA\n\ -_081325B8:\n\ - ldrb r3, [r1, 0x17]\n\ - b _081325CA\n\ -_081325BC:\n\ - ldr r1, =gBattleMons\n\ - movs r0, 0x58\n\ - muls r0, r5\n\ - adds r0, r1\n\ - adds r0, 0x20\n\ - ldrb r3, [r0]\n\ - ldr r6, =gBattleResources\n\ -_081325CA:\n\ - cmp r3, 0\n\ - bne _081325E8\n\ -_081325CE:\n\ - ldr r0, [r6]\n\ - ldr r1, [r0, 0x14]\n\ - movs r0, 0x2\n\ - str r0, [r1, 0x8]\n\ - ldr r2, =gAIScriptPtr\n\ - b _08132608\n\ - .pool\n\ -_081325E8:\n\ - ldr r0, =gAIScriptPtr\n\ - ldr r1, [r0]\n\ - adds r2, r0, 0\n\ - ldrb r1, [r1, 0x2]\n\ - cmp r3, r1\n\ - bne _08132600\n\ - ldr r0, [r6]\n\ - ldr r1, [r0, 0x14]\n\ - movs r0, 0x1\n\ - b _08132606\n\ - .pool\n\ -_08132600:\n\ - ldr r0, [r6]\n\ - ldr r1, [r0, 0x14]\n\ - movs r0, 0\n\ -_08132606:\n\ - str r0, [r1, 0x8]\n\ -_08132608:\n\ - ldr r0, [r2]\n\ - adds r0, 0x3\n\ - str r0, [r2]\n\ - pop {r4-r6}\n\ - pop {r0}\n\ - bx r0\n\ - .pool\n\ - .syntax divided"); -} -#endif - -static void BattleAICmd_get_highest_type_effectiveness(void) -{ - s32 i; - u8* dynamicMoveType; - - gDynamicBasePower = 0; - dynamicMoveType = &gBattleStruct->dynamicMoveType; - *dynamicMoveType = 0; - gBattleScripting.dmgMultiplier = 1; - gBattleMoveFlags = 0; - gCritMultiplier = 1; - AI_THINKING_STRUCT->funcResult = 0; - - for (i = 0; i < 4; i++) - { - gBattleMoveDamage = 40; - gCurrentMove = gBattleMons[sBank_AI].moves[i]; - - if (gCurrentMove) - { - TypeCalc(gCurrentMove, sBank_AI, gBankTarget); - - // reduce by 1/3. - if (gBattleMoveDamage == 120) - gBattleMoveDamage = 80; - if (gBattleMoveDamage == 240) - gBattleMoveDamage = 160; - if (gBattleMoveDamage == 30) - gBattleMoveDamage = 20; - if (gBattleMoveDamage == 15) - gBattleMoveDamage = 10; - - if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) - gBattleMoveDamage = 0; - - if (AI_THINKING_STRUCT->funcResult < gBattleMoveDamage) - AI_THINKING_STRUCT->funcResult = gBattleMoveDamage; - } - } - gAIScriptPtr += 1; -} - -static void BattleAICmd_if_type_effectiveness(void) -{ - u8 damageVar; - - gDynamicBasePower = 0; - gBattleStruct->dynamicMoveType = 0; - gBattleScripting.dmgMultiplier = 1; - gBattleMoveFlags = 0; - gCritMultiplier = 1; - - gBattleMoveDamage = 40; - gCurrentMove = AI_THINKING_STRUCT->moveConsidered; - - TypeCalc(gCurrentMove, sBank_AI, gBankTarget); - - if (gBattleMoveDamage == 120) - gBattleMoveDamage = 80; - if (gBattleMoveDamage == 240) - gBattleMoveDamage = 160; - if (gBattleMoveDamage == 30) - gBattleMoveDamage = 20; - if (gBattleMoveDamage == 15) - gBattleMoveDamage = 10; - - if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) - gBattleMoveDamage = 0; - - // store gBattleMoveDamage in a u8 variable because gAIScriptPtr[1] is a u8. - damageVar = gBattleMoveDamage; - - if (damageVar == gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_nullsub_32(void) -{ -} - -static void BattleAICmd_nullsub_33(void) -{ -} - -static void BattleAICmd_if_status_in_party(void) -{ - struct Pokemon *party; - int i; - u32 statusToCompareTo; - u8 index; - - switch(gAIScriptPtr[1]) - { - case 1: - index = sBank_AI; - break; - default: - index = gBankTarget; - break; - } - - party = (GetBankSide(index) == 0) ? gPlayerParty : gEnemyParty; - - statusToCompareTo = AIScriptRead32(gAIScriptPtr + 2); - - for (i = 0; i < 6; i++) - { - u16 species = GetMonData(&party[i], MON_DATA_SPECIES); - u16 hp = GetMonData(&party[i], MON_DATA_HP); - u32 status = GetMonData(&party[i], MON_DATA_STATUS); - - if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo) - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); - return; - } - } - - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_status_not_in_party(void) -{ - struct Pokemon *party; - int i; - u32 statusToCompareTo; - u8 index; - - switch(gAIScriptPtr[1]) - { - case 1: - index = sBank_AI; - break; - default: - index = gBankTarget; - break; - } - - party = (GetBankSide(index) == 0) ? gPlayerParty : gEnemyParty; - - statusToCompareTo = AIScriptRead32(gAIScriptPtr + 2); - - for (i = 0; i < 6; i++) - { - u16 species = GetMonData(&party[i], MON_DATA_SPECIES); - u16 hp = GetMonData(&party[i], MON_DATA_HP); - u32 status = GetMonData(&party[i], MON_DATA_STATUS); - - if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo) - { - gAIScriptPtr += 10; // still bugged in Emerald - } - } - - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); -} - -static void BattleAICmd_get_weather(void) -{ - if (gBattleWeather & WEATHER_RAIN_ANY) - AI_THINKING_STRUCT->funcResult = 1; - if (gBattleWeather & WEATHER_SANDSTORM_ANY) - AI_THINKING_STRUCT->funcResult = 2; - if (gBattleWeather & WEATHER_SUN_ANY) - AI_THINKING_STRUCT->funcResult = 0; - if (gBattleWeather & WEATHER_HAIL_ANY) - AI_THINKING_STRUCT->funcResult = 3; - - gAIScriptPtr += 1; -} - -static void BattleAICmd_if_effect(void) -{ - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_not_effect(void) -{ - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect != gAIScriptPtr[1]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_stat_level_less_than(void) -{ - u32 bank; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - if (gBattleMons[bank].statStages[gAIScriptPtr[2]] < gAIScriptPtr[3]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void BattleAICmd_if_stat_level_more_than(void) -{ - u32 bank; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - if (gBattleMons[bank].statStages[gAIScriptPtr[2]] > gAIScriptPtr[3]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void BattleAICmd_if_stat_level_equal(void) -{ - u32 bank; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - if (gBattleMons[bank].statStages[gAIScriptPtr[2]] == gAIScriptPtr[3]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void BattleAICmd_if_stat_level_not_equal(void) -{ - u32 bank; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - if (gBattleMons[bank].statStages[gAIScriptPtr[2]] != gAIScriptPtr[3]) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void BattleAICmd_if_can_faint(void) -{ - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power < 2) - { - gAIScriptPtr += 5; - return; - } - - gDynamicBasePower = 0; - gBattleStruct->dynamicMoveType = 0; - gBattleScripting.dmgMultiplier = 1; - gBattleMoveFlags = 0; - gCritMultiplier = 1; - gCurrentMove = AI_THINKING_STRUCT->moveConsidered; - AI_CalcDmg(sBank_AI, gBankTarget); - TypeCalc(gCurrentMove, sBank_AI, gBankTarget); - - gBattleMoveDamage = gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[AI_THINKING_STRUCT->movesetIndex] / 100; - - // moves always do at least 1 damage. - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - if (gBattleMons[gBankTarget].hp <= gBattleMoveDamage) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void BattleAICmd_if_cant_faint(void) -{ - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power < 2) - { - gAIScriptPtr += 5; - return; - } - - gDynamicBasePower = 0; - gBattleStruct->dynamicMoveType = 0; - gBattleScripting.dmgMultiplier = 1; - gBattleMoveFlags = 0; - gCritMultiplier = 1; - gCurrentMove = AI_THINKING_STRUCT->moveConsidered; - AI_CalcDmg(sBank_AI, gBankTarget); - TypeCalc(gCurrentMove, sBank_AI, gBankTarget); - - gBattleMoveDamage = gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[AI_THINKING_STRUCT->movesetIndex] / 100; - - // this macro is missing the damage 0 = 1 assumption. - - if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void BattleAICmd_if_has_move(void) -{ - int i; - u16 *temp_ptr = (u16 *)(gAIScriptPtr + 2); - - switch(gAIScriptPtr[1]) - { - case AI_USER: - for (i = 0; i < 4; i++) - { - if (gBattleMons[sBank_AI].moves[i] == *temp_ptr) - break; - } - if (i == 4) - { - gAIScriptPtr += 8; - return; - } - else - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); - return; - } - case AI_USER_PARTNER: - if (gBattleMons[sBank_AI ^ 2].hp == 0) - { - gAIScriptPtr += 8; - return; - } - else - { - for (i = 0; i < 4; i++) - { - if (gBattleMons[sBank_AI ^ 2].moves[i] == *temp_ptr) - break; - } - } - if (i == 4) - { - gAIScriptPtr += 8; - return; - } - else - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); - return; - } - case AI_TARGET: - case AI_TARGET_PARTNER: - for (i = 0; i < 4; i++) - { - if (BATTLE_HISTORY->usedMoves[gBankTarget].moves[i] == *temp_ptr) - break; - } - if (i == 4) - { - gAIScriptPtr += 8; - return; - } - else - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); - return; - } - } -} - -static void BattleAICmd_if_dont_have_move(void) -{ - int i; - u16 *temp_ptr = (u16 *)(gAIScriptPtr + 2); - - switch(gAIScriptPtr[1]) - { - case AI_USER: - case AI_USER_PARTNER: // UB: no separate check for user partner - for (i = 0; i < 4; i++) - { - if (gBattleMons[sBank_AI].moves[i] == *temp_ptr) - break; - } - if (i != 4) - { - gAIScriptPtr += 8; - return; - } - else - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); - return; - } - case AI_TARGET: - case AI_TARGET_PARTNER: - for (i = 0; i < 4; i++) - { - if (BATTLE_HISTORY->usedMoves[gBankTarget].moves[i] == *temp_ptr) - break; - } - if (i != 4) - { - gAIScriptPtr += 8; - return; - } - else - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); - return; - } - } -} - -static void BattleAICmd_if_move_effect(void) -{ - int i; - - switch (gAIScriptPtr[1]) - { - case AI_USER: - case AI_USER_PARTNER: - for (i = 0; i < 4; i++) - { - if(gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[gBattleMons[sBank_AI].moves[i]].effect == gAIScriptPtr[2]) - break; - } - if (i == 4) - gAIScriptPtr += 7; - else - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - break; - case AI_TARGET: - case AI_TARGET_PARTNER: - for (i = 0; i < 4; i++) - { - if (gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[BATTLE_HISTORY->usedMoves[gBankTarget].moves[i]].effect == gAIScriptPtr[2]) - break; - } - if (i == 4) - gAIScriptPtr += 7; - else - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - break; - } -} - -static void BattleAICmd_if_not_move_effect(void) -{ - int i; - - switch (gAIScriptPtr[1]) - { - case AI_USER: - case AI_USER_PARTNER: - for (i = 0; i < 4; i++) - { - if(gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[gBattleMons[sBank_AI].moves[i]].effect == gAIScriptPtr[2]) - break; - } - if (i != 4) - gAIScriptPtr += 7; - else - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - break; - case AI_TARGET: - case AI_TARGET_PARTNER: - for (i = 0; i < 4; i++) - { - if (BATTLE_HISTORY->usedMoves[gBankTarget].moves[i] && gBattleMoves[BATTLE_HISTORY->usedMoves[gBankTarget].moves[i]].effect == gAIScriptPtr[2]) - break; - } - if (i != 4) - gAIScriptPtr += 7; - else - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - break; - } -} - -static void BattleAICmd_if_any_move_disabled_or_encored(void) -{ - u8 bank; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - if (gAIScriptPtr[2] == 0) - { - if (gDisableStructs[bank].disabledMove == 0) - { - gAIScriptPtr += 7; - return; - } - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - return; - } - else if (gAIScriptPtr[2] != 1) // ignore the macro if its not 0 or 1. - { - gAIScriptPtr += 7; - return; - } - else if (gDisableStructs[bank].encoredMove != 0) - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); - return; - } - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_curr_move_disabled_or_encored(void) -{ - switch (gAIScriptPtr[1]) - { - case 0: - if (gDisableStructs[gActiveBank].disabledMove == AI_THINKING_STRUCT->moveConsidered) - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - return; - } - gAIScriptPtr += 6; - return; - case 1: - if (gDisableStructs[gActiveBank].encoredMove == AI_THINKING_STRUCT->moveConsidered) - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - return; - } - gAIScriptPtr += 6; - return; - default: - gAIScriptPtr += 6; - return; - } -} - -static void BattleAICmd_flee(void) -{ - AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_FLEE | AI_ACTION_DO_NOT_ATTACK); // what matters is UNK2 being enabled. -} - -static void BattleAICmd_if_random_100(void) -{ - u8 safariFleeRate = gBattleStruct->field_7B * 5; // safari flee rate, from 0-20 - - if ((u8)(Random() % 100) < safariFleeRate) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void BattleAICmd_watch(void) -{ - AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_WATCH | AI_ACTION_DO_NOT_ATTACK); // what matters is UNK3 being enabled. -} - -static void BattleAICmd_get_hold_effect(void) -{ - u8 bank; - u16 status; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - if (gActiveBank != bank) - { - AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(BATTLE_HISTORY->itemEffects[bank]); - } - else - AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(gBattleMons[bank].item); - - gAIScriptPtr += 2; -} - -static void BattleAICmd_if_holds_item(void) -{ - u8 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]); - u16 item; - u8 var1, var2; - - if ((bank & 1) == (sBank_AI & 1)) - item = gBattleMons[bank].item; - else - item = BATTLE_HISTORY->itemEffects[bank]; - - // UB: doesn't properly read an unaligned u16 - var2 = gAIScriptPtr[2]; - var1 = gAIScriptPtr[3]; - - if ((var1 | var2) == item) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void BattleAICmd_get_gender(void) -{ - u8 bank; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - AI_THINKING_STRUCT->funcResult = GetGenderFromSpeciesAndPersonality(gBattleMons[bank].species, gBattleMons[bank].personality); - - gAIScriptPtr += 2; -} - -static void BattleAICmd_is_first_turn(void) -{ - u8 bank; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - AI_THINKING_STRUCT->funcResult = gDisableStructs[bank].isFirstTurn; - - gAIScriptPtr += 2; -} - -static void BattleAICmd_get_stockpile_count(void) -{ - u8 bank; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - AI_THINKING_STRUCT->funcResult = gDisableStructs[bank].stockpileCounter; - - gAIScriptPtr += 2; -} - -static void BattleAICmd_is_double_battle(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleTypeFlags & BATTLE_TYPE_DOUBLE; - - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_used_held_item(void) -{ - u8 bank; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - // This is likely a leftover from Ruby's code and its ugly ewram access - #ifdef NONMATCHING - AI_THINKING_STRUCT->funcResult = gBattleStruct->usedHeldItems[bank]; - #else - AI_THINKING_STRUCT->funcResult = *(u8*)((u8*)(gBattleStruct) + 0xB8 + (bank * 2)); - #endif // NONMATCHING - - gAIScriptPtr += 2; -} - -static void BattleAICmd_get_move_type_from_result(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].type; - - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_move_power_from_result(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].power; - - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_move_effect_from_result(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].effect; - - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_protect_count(void) -{ - u8 bank; - - if (gAIScriptPtr[1] == AI_USER) - bank = sBank_AI; - else - bank = gBankTarget; - - AI_THINKING_STRUCT->funcResult = gDisableStructs[bank].protectUses; - - gAIScriptPtr += 2; -} - -static void BattleAICmd_nullsub_52(void) -{ -} - -static void BattleAICmd_nullsub_53(void) -{ -} - -static void BattleAICmd_nullsub_54(void) -{ -} - -static void BattleAICmd_nullsub_55(void) -{ -} - -static void BattleAICmd_nullsub_56(void) -{ -} - -static void BattleAICmd_nullsub_57(void) -{ -} - -static void BattleAICmd_call(void) -{ - AIStackPushVar(gAIScriptPtr + 5); - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); -} - -static void BattleAICmd_jump(void) -{ - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); -} - -static void BattleAICmd_end(void) -{ - if (AIStackPop() == 0) - AI_THINKING_STRUCT->aiAction |= AI_ACTION_DONE; -} - -static void BattleAICmd_if_level_cond(void) -{ - switch (gAIScriptPtr[1]) - { - case 0: // greater than - if (gBattleMons[sBank_AI].level > gBattleMons[gBankTarget].level) - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - return; - } - gAIScriptPtr += 6; - return; - case 1: // less than - if (gBattleMons[sBank_AI].level < gBattleMons[gBankTarget].level) - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - return; - } - gAIScriptPtr += 6; - return; - case 2: // equal - if (gBattleMons[sBank_AI].level == gBattleMons[gBankTarget].level) - { - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - return; - } - gAIScriptPtr += 6; - return; - } -} - -static void BattleAICmd_if_target_taunted(void) -{ - if (gDisableStructs[gBankTarget].tauntTimer1 != 0) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void BattleAICmd_if_target_not_taunted(void) -{ - if (gDisableStructs[gBankTarget].tauntTimer1 == 0) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void BattleAICmd_if_target_is_ally(void) -{ - if((sBank_AI & 1) == (gBankTarget & 1)) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void BattleAICmd_if_flash_fired(void) -{ - u8 index = BattleAI_GetWantedBank(gAIScriptPtr[1]); - - if(gBattleResources->flags->flags[index] & UNKNOWN_FLAG_FLASH_FIRE) - gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void AIStackPushVar(const u8 *var) -{ - gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size++] = var; -} - -static void AIStackPushVar_cursor(void) -{ - gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size++] = gAIScriptPtr; -} - -static bool8 AIStackPop(void) -{ - if (gBattleResources->AI_ScriptsStack->size != 0) - { - --gBattleResources->AI_ScriptsStack->size; - gAIScriptPtr = gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size]; - return TRUE; - } - else - return FALSE; -} diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c new file mode 100644 index 000000000..dae43f13c --- /dev/null +++ b/src/battle_ai_script_commands.c @@ -0,0 +1,2922 @@ +#include "global.h" +#include "battle_ai_script_commands.h" +#include "pokemon.h" +#include "battle.h" +#include "species.h" +#include "abilities.h" +#include "rng.h" +#include "item.h" +#include "battle_move_effects.h" + +#define AIScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) +#define AIScriptRead16(ptr) ((ptr)[0] | (ptr)[1] << 8) +#define AIScriptRead8(ptr) ((ptr)[0]) +#define AIScriptReadPtr(ptr) (u8*) AIScriptRead32(ptr) + +#define AI_ACTION_DONE 0x0001 +#define AI_ACTION_FLEE 0x0002 +#define AI_ACTION_WATCH 0x0004 +#define AI_ACTION_DO_NOT_ATTACK 0x0008 +#define AI_ACTION_UNK5 0x0010 +#define AI_ACTION_UNK6 0x0020 +#define AI_ACTION_UNK7 0x0040 +#define AI_ACTION_UNK8 0x0080 + +#define AI_THINKING_STRUCT ((struct AI_ThinkingStruct *)(gBattleResources->ai)) +#define BATTLE_HISTORY ((struct BattleHistory *)(gBattleResources->battleHistory)) + +enum +{ + AI_TARGET, + AI_USER, + AI_TARGET_PARTNER, + AI_USER_PARTNER +}; + +// AI states +enum +{ + AIState_SettingUp, + AIState_Processing, + AIState_FinishedProcessing, + AIState_DoNotProcess +}; + +/* +gAIScriptPtr is a pointer to the next battle AI cmd command to read. +when a command finishes processing, gAIScriptPtr is incremented by +the number of bytes that the current command had reserved for arguments +in order to read the next command correctly. refer to battle_ai_scripts.s for the +AI scripts. +*/ + +extern u32 gBattleTypeFlags; +extern u8 gActiveBank; +extern struct BattlePokemon gBattleMons[4]; +extern u16 gCurrentMove; +extern u8 gBankTarget; +extern u8 gAbsentBankFlags; +extern u16 gLastUsedMovesByBanks[4]; +extern u16 gTrainerBattleOpponent_A; +extern u16 gTrainerBattleOpponent_B; +extern u32 gStatuses3[4]; +extern u16 gSideAffecting[2]; +extern u16 gBattlePartyID[4]; +extern u16 gDynamicBasePower; +extern u8 gBattleMoveFlags; +extern s32 gBattleMoveDamage; +extern u8 gCritMultiplier; +extern u16 gBattleWeather; + +extern const struct BattleMove gBattleMoves[]; +extern const struct BaseStats gBaseStats[]; +extern const u32 gBitTable[]; +extern u8 * const gBattleAI_ScriptsTable[]; + +extern u8 b_first_side(u8, u8, u8); +extern void AI_CalcDmg(u8, u8); + +extern u8 CheckMoveLimitations(); +extern u32 GetAiScriptsInRecordedBattle(); +extern u32 GetAiScriptsInBattleFactory(); + +static u8 BattleAI_ChooseMoveOrAction_Singles(void); +static u8 BattleAI_ChooseMoveOrAction_Doubles(void); +static void RecordLastUsedMoveByTarget(void); +static void BattleAI_DoAIProcessing(void); +static void AIStackPushVar(const u8 *); +static bool8 AIStackPop(void); + +static void BattleAICmd_if_random_less_than(void); +static void BattleAICmd_if_random_greater_than(void); +static void BattleAICmd_if_random_equal(void); +static void BattleAICmd_if_random_not_equal(void); +static void BattleAICmd_score(void); +static void BattleAICmd_if_hp_less_than(void); +static void BattleAICmd_if_hp_more_than(void); +static void BattleAICmd_if_hp_equal(void); +static void BattleAICmd_if_hp_not_equal(void); +static void BattleAICmd_if_status(void); +static void BattleAICmd_if_not_status(void); +static void BattleAICmd_if_status2(void); +static void BattleAICmd_if_not_status2(void); +static void BattleAICmd_if_status3(void); +static void BattleAICmd_if_not_status3(void); +static void BattleAICmd_if_side_affecting(void); +static void BattleAICmd_if_not_side_affecting(void); +static void BattleAICmd_if_less_than(void); +static void BattleAICmd_if_more_than(void); +static void BattleAICmd_if_equal(void); +static void BattleAICmd_if_not_equal(void); +static void BattleAICmd_if_less_than_32(void); +static void BattleAICmd_if_more_than_32(void); +static void BattleAICmd_if_equal_32(void); +static void BattleAICmd_if_not_equal_32(void); +static void BattleAICmd_if_move(void); +static void BattleAICmd_if_not_move(void); +static void BattleAICmd_if_in_bytes(void); +static void BattleAICmd_if_not_in_bytes(void); +static void BattleAICmd_if_in_words(void); +static void BattleAICmd_if_not_in_words(void); +static void BattleAICmd_if_user_can_damage(void); +static void BattleAICmd_if_user_cant_damage(void); +static void BattleAICmd_get_turn_count(void); +static void BattleAICmd_get_type(void); +static void BattleAICmd_get_last_used_bank_move_power(void); +static void BattleAICmd_is_most_powerful_move(void); +static void BattleAICmd_get_last_used_bank_move(void); +static void BattleAICmd_if_arg_equal(void); +static void BattleAICmd_if_arg_not_equal(void); +static void BattleAICmd_if_would_go_first(void); +static void BattleAICmd_if_would_not_go_first(void); +static void BattleAICmd_nullsub_2A(void); +static void BattleAICmd_nullsub_2B(void); +static void BattleAICmd_count_alive_pokemon(void); +static void BattleAICmd_get_considered_move(void); +static void BattleAICmd_get_considered_move_effect(void); +static void BattleAICmd_get_ability(void); +static void BattleAICmd_get_highest_type_effectiveness(void); +static void BattleAICmd_if_type_effectiveness(void); +static void BattleAICmd_nullsub_32(void); +static void BattleAICmd_nullsub_33(void); +static void BattleAICmd_if_status_in_party(void); +static void BattleAICmd_if_status_not_in_party(void); +static void BattleAICmd_get_weather(void); +static void BattleAICmd_if_effect(void); +static void BattleAICmd_if_not_effect(void); +static void BattleAICmd_if_stat_level_less_than(void); +static void BattleAICmd_if_stat_level_more_than(void); +static void BattleAICmd_if_stat_level_equal(void); +static void BattleAICmd_if_stat_level_not_equal(void); +static void BattleAICmd_if_can_faint(void); +static void BattleAICmd_if_cant_faint(void); +static void BattleAICmd_if_has_move(void); +static void BattleAICmd_if_dont_have_move(void); +static void BattleAICmd_if_move_effect(void); +static void BattleAICmd_if_not_move_effect(void); +static void BattleAICmd_if_any_move_disabled_or_encored(void); +static void BattleAICmd_if_curr_move_disabled_or_encored(void); +static void BattleAICmd_flee(void); +static void BattleAICmd_if_random_100(void); +static void BattleAICmd_watch(void); +static void BattleAICmd_get_hold_effect(void); +static void BattleAICmd_get_gender(void); +static void BattleAICmd_is_first_turn(void); +static void BattleAICmd_get_stockpile_count(void); +static void BattleAICmd_is_double_battle(void); +static void BattleAICmd_get_used_held_item(void); +static void BattleAICmd_get_move_type_from_result(void); +static void BattleAICmd_get_move_power_from_result(void); +static void BattleAICmd_get_move_effect_from_result(void); +static void BattleAICmd_get_protect_count(void); +static void BattleAICmd_nullsub_52(void); +static void BattleAICmd_nullsub_53(void); +static void BattleAICmd_nullsub_54(void); +static void BattleAICmd_nullsub_55(void); +static void BattleAICmd_nullsub_56(void); +static void BattleAICmd_nullsub_57(void); +static void BattleAICmd_call(void); +static void BattleAICmd_jump(void); +static void BattleAICmd_end(void); +static void BattleAICmd_if_level_cond(void); +static void BattleAICmd_if_target_taunted(void); +static void BattleAICmd_if_target_not_taunted(void); +static void BattleAICmd_check_ability(void); +static void BattleAICmd_is_of_type(void); +static void BattleAICmd_if_target_is_ally(void); +static void BattleAICmd_if_flash_fired(void); +static void BattleAICmd_if_holds_item(void); + +// ewram + +EWRAM_DATA const u8 *gAIScriptPtr = NULL; +EWRAM_DATA static u8 sBank_AI = 0; + +// const rom data + +typedef void (*BattleAICmdFunc)(void); + +static const BattleAICmdFunc sBattleAICmdTable[] = +{ + BattleAICmd_if_random_less_than, // 0x0 + BattleAICmd_if_random_greater_than, // 0x1 + BattleAICmd_if_random_equal, // 0x2 + BattleAICmd_if_random_not_equal, // 0x3 + BattleAICmd_score, // 0x4 + BattleAICmd_if_hp_less_than, // 0x5 + BattleAICmd_if_hp_more_than, // 0x6 + BattleAICmd_if_hp_equal, // 0x7 + BattleAICmd_if_hp_not_equal, // 0x8 + BattleAICmd_if_status, // 0x9 + BattleAICmd_if_not_status, // 0xA + BattleAICmd_if_status2, // 0xB + BattleAICmd_if_not_status2, // 0xC + BattleAICmd_if_status3, // 0xD + BattleAICmd_if_not_status3, // 0xE + BattleAICmd_if_side_affecting, // 0xF + BattleAICmd_if_not_side_affecting, // 0x10 + BattleAICmd_if_less_than, // 0x11 + BattleAICmd_if_more_than, // 0x12 + BattleAICmd_if_equal, // 0x13 + BattleAICmd_if_not_equal, // 0x14 + BattleAICmd_if_less_than_32, // 0x15 + BattleAICmd_if_more_than_32, // 0x16 + BattleAICmd_if_equal_32, // 0x17 + BattleAICmd_if_not_equal_32, // 0x18 + BattleAICmd_if_move, // 0x19 + BattleAICmd_if_not_move, // 0x1A + BattleAICmd_if_in_bytes, // 0x1B + BattleAICmd_if_not_in_bytes, // 0x1C + BattleAICmd_if_in_words, // 0x1D + BattleAICmd_if_not_in_words, // 0x1E + BattleAICmd_if_user_can_damage, // 0x1F + BattleAICmd_if_user_cant_damage, // 0x20 + BattleAICmd_get_turn_count, // 0x21 + BattleAICmd_get_type, // 0x22 + BattleAICmd_get_last_used_bank_move_power, // 0x23 + BattleAICmd_is_most_powerful_move, // 0x24 + BattleAICmd_get_last_used_bank_move, // 0x25 + BattleAICmd_if_arg_equal, // 0x26 + BattleAICmd_if_arg_not_equal, // 0x27 + BattleAICmd_if_would_go_first, // 0x28 + BattleAICmd_if_would_not_go_first, // 0x29 + BattleAICmd_nullsub_2A, // 0x2A + BattleAICmd_nullsub_2B, // 0x2B + BattleAICmd_count_alive_pokemon, // 0x2C + BattleAICmd_get_considered_move, // 0x2D + BattleAICmd_get_considered_move_effect, // 0x2E + BattleAICmd_get_ability, // 0x2F + BattleAICmd_get_highest_type_effectiveness, // 0x30 + BattleAICmd_if_type_effectiveness, // 0x31 + BattleAICmd_nullsub_32, // 0x32 + BattleAICmd_nullsub_33, // 0x33 + BattleAICmd_if_status_in_party, // 0x34 + BattleAICmd_if_status_not_in_party, // 0x35 + BattleAICmd_get_weather, // 0x36 + BattleAICmd_if_effect, // 0x37 + BattleAICmd_if_not_effect, // 0x38 + BattleAICmd_if_stat_level_less_than, // 0x39 + BattleAICmd_if_stat_level_more_than, // 0x3A + BattleAICmd_if_stat_level_equal, // 0x3B + BattleAICmd_if_stat_level_not_equal, // 0x3C + BattleAICmd_if_can_faint, // 0x3D + BattleAICmd_if_cant_faint, // 0x3E + BattleAICmd_if_has_move, // 0x3F + BattleAICmd_if_dont_have_move, // 0x40 + BattleAICmd_if_move_effect, // 0x41 + BattleAICmd_if_not_move_effect, // 0x42 + BattleAICmd_if_any_move_disabled_or_encored, // 0x43 + BattleAICmd_if_curr_move_disabled_or_encored, // 0x44 + BattleAICmd_flee, // 0x45 + BattleAICmd_if_random_100, // 0x46 + BattleAICmd_watch, // 0x47 + BattleAICmd_get_hold_effect, // 0x48 + BattleAICmd_get_gender, // 0x49 + BattleAICmd_is_first_turn, // 0x4A + BattleAICmd_get_stockpile_count, // 0x4B + BattleAICmd_is_double_battle, // 0x4C + BattleAICmd_get_used_held_item, // 0x4D + BattleAICmd_get_move_type_from_result, // 0x4E + BattleAICmd_get_move_power_from_result, // 0x4F + BattleAICmd_get_move_effect_from_result, // 0x50 + BattleAICmd_get_protect_count, // 0x51 + BattleAICmd_nullsub_52, // 0x52 + BattleAICmd_nullsub_53, // 0x53 + BattleAICmd_nullsub_54, // 0x54 + BattleAICmd_nullsub_55, // 0x55 + BattleAICmd_nullsub_56, // 0x56 + BattleAICmd_nullsub_57, // 0x57 + BattleAICmd_call, // 0x58 + BattleAICmd_jump, // 0x59 + BattleAICmd_end, // 0x5A + BattleAICmd_if_level_cond, // 0x5B + BattleAICmd_if_target_taunted, // 0x5C + BattleAICmd_if_target_not_taunted, // 0x5D + BattleAICmd_if_target_is_ally, // 0x5E + BattleAICmd_is_of_type, // 0x5F + BattleAICmd_check_ability, // 0x60 + BattleAICmd_if_flash_fired, // 0x61 + BattleAICmd_if_holds_item, // 0x62 +}; + +static const u16 sDiscouragedPowerfulMoveEffects[] = +{ + EFFECT_EXPLOSION, + EFFECT_DREAM_EATER, + EFFECT_RAZOR_WIND, + EFFECT_SKY_ATTACK, + EFFECT_RECHARGE, + EFFECT_SKULL_BASH, + EFFECT_SOLARBEAM, + EFFECT_SPIT_UP, + EFFECT_FOCUS_PUNCH, + EFFECT_SUPERPOWER, + EFFECT_ERUPTION, + EFFECT_OVERHEAT, + 0xFFFF +}; + +void BattleAI_HandleItemUseBeforeAISetup(u8 defaultScoreMoves) +{ + s32 i; + u8 *data = (u8 *)gBattleResources->battleHistory; + + for (i = 0; i < sizeof(struct BattleHistory); i++) + data[i] = 0; + // items are allowed to use in ONLY trainer battles + if ((gBattleTypeFlags & + (BATTLE_TYPE_LINK | BATTLE_TYPE_SAFARI | BATTLE_TYPE_BATTLE_TOWER | + BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_x2000000 | BATTLE_TYPE_SECRET_BASE)) + == BATTLE_TYPE_TRAINER) + { + for (i = 0; i < 4; i++) + { + if (gTrainers[gTrainerBattleOpponent_A].items[i] != 0) + { + gBattleResources->battleHistory->TrainerItems[gBattleResources->battleHistory->itemsNo] = gTrainers[gTrainerBattleOpponent_A].items[i]; + gBattleResources->battleHistory->itemsNo++; + } + } + } + + BattleAI_SetupAIData(defaultScoreMoves); +} + +void BattleAI_SetupAIData(u8 defaultScoreMoves) +{ + s32 i; + u8 *data = (u8 *)AI_THINKING_STRUCT; + u8 moveLimitations; + + // clear AI data. + for (i = 0; i < sizeof(struct AI_ThinkingStruct); i++) + data[i] = 0; + + // conditional score reset, unlike Ruby. + for (i = 0; i < 4; i++) + { + if (defaultScoreMoves & 1) + AI_THINKING_STRUCT->score[i] = 100; + else + AI_THINKING_STRUCT->score[i] = 0; + defaultScoreMoves >>= 1; + } + + moveLimitations = CheckMoveLimitations(gActiveBank, 0, 0xFF); + + // ignore moves that aren't possible to use + for (i = 0; i < 4; i++) + { + if (gBitTable[i] & moveLimitations) + AI_THINKING_STRUCT->score[i] = 0; + + AI_THINKING_STRUCT->simulatedRNG[i] = 100 - (Random() % 16); + } + gBattleResources->AI_ScriptsStack->size = 0; + sBank_AI = gActiveBank; + // decide a random target bank in doubles + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + gBankTarget = (Random() & 2) + (GetBankSide(gActiveBank) ^ 1); + if (gAbsentBankFlags & gBitTable[gBankTarget]) + gBankTarget ^= 2; + } + // in singles there's only one choice + else + gBankTarget = sBank_AI ^ 1; + + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + AI_THINKING_STRUCT->aiFlags = GetAiScriptsInRecordedBattle(); + else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + AI_THINKING_STRUCT->aiFlags = 0x40000000; + else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) + AI_THINKING_STRUCT->aiFlags = 0x20000000; + else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) + AI_THINKING_STRUCT->aiFlags = 0x80000000; + else if (gBattleTypeFlags & BATTLE_TYPE_FACTORY) + AI_THINKING_STRUCT->aiFlags = GetAiScriptsInBattleFactory(); + else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_x4000000 | BATTLE_TYPE_SECRET_BASE)) + AI_THINKING_STRUCT->aiFlags = 7; // the smartest possible set + else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags | gTrainers[gTrainerBattleOpponent_B].aiFlags; + else + AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + AI_THINKING_STRUCT->aiFlags |= 0x80; // act smart in doubles and don't attack your partner +} + +u8 BattleAI_ChooseMoveOrAction(void) +{ + u16 savedCurrentMove = gCurrentMove; + u8 ret; + + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + ret = BattleAI_ChooseMoveOrAction_Singles(); + else + ret = BattleAI_ChooseMoveOrAction_Doubles(); + + gCurrentMove = savedCurrentMove; + return ret; +} + +static u8 BattleAI_ChooseMoveOrAction_Singles(void) +{ + u8 currentMoveArray[4]; + u8 consideredMoveArray[4]; + u8 numOfBestMoves; + s32 i; + + RecordLastUsedMoveByTarget(); + + while (AI_THINKING_STRUCT->aiFlags != 0) + { + if (AI_THINKING_STRUCT->aiFlags & 1) + { + AI_THINKING_STRUCT->aiState = AIState_SettingUp; + BattleAI_DoAIProcessing(); + } + AI_THINKING_STRUCT->aiFlags >>= 1; + AI_THINKING_STRUCT->aiLogicId++; + AI_THINKING_STRUCT->movesetIndex = 0; + } + + // special flags for safari + if (AI_THINKING_STRUCT->aiAction & AI_ACTION_FLEE) + return 4; + if (AI_THINKING_STRUCT->aiAction & AI_ACTION_WATCH) + return 5; + + numOfBestMoves = 1; + currentMoveArray[0] = AI_THINKING_STRUCT->score[0]; + consideredMoveArray[0] = 0; + + for (i = 1; i < 4; i++) + { + if (gBattleMons[sBank_AI].moves[i] != 0) // emerald adds an extra move ID check for some reason. + { + // in ruby, the order of these if statements are reversed. + if (currentMoveArray[0] == AI_THINKING_STRUCT->score[i]) + { + currentMoveArray[numOfBestMoves] = AI_THINKING_STRUCT->score[i]; + consideredMoveArray[numOfBestMoves++] = i; + } + if (currentMoveArray[0] < AI_THINKING_STRUCT->score[i]) + { + numOfBestMoves = 1; + currentMoveArray[0] = AI_THINKING_STRUCT->score[i]; + consideredMoveArray[0] = i; + } + } + } + return consideredMoveArray[Random() % numOfBestMoves]; +} + +#ifdef NONMATCHING +static u8 BattleAI_ChooseMoveOrAction_Doubles(void) +{ + s32 i; + s32 j; + s32 scriptsToRun; + s16 mostMovePoints; + s16 bestMovePointsForTarget[4]; + s8 mostViableTargetsArray[4]; + u8 actionOrMoveIndex[4]; + u8 mostViableMovesScores[4]; + u8 mostViableMovesIndices[4]; + s32 mostViableTargetsNo; + s32 mostViableMovesNo; + + for (i = 0; i < 4; i++) //08130D14 + { + if (i == sBank_AI || gBattleMons[i].hp == 0) + { + //_08130D2E + actionOrMoveIndex[i] = -1; + bestMovePointsForTarget[i] = -1; + } + //_08130D48 + else + { + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + BattleAI_SetupAIData(gBattleStruct->field_92 >> 4); + else + BattleAI_SetupAIData(0xF); + //_08130D76 + gBankTarget = i; + if ((i & 1) != (sBank_AI & 1)) + RecordLastUsedMoveByTarget(); + //_08130D90 + AI_THINKING_STRUCT->aiLogicId = 0; + AI_THINKING_STRUCT->movesetIndex = 0; + scriptsToRun = AI_THINKING_STRUCT->aiFlags; + while (scriptsToRun != 0) + { + if (scriptsToRun & 1) + { + AI_THINKING_STRUCT->aiState = AIState_SettingUp; + BattleAI_DoAIProcessing(); + } + scriptsToRun >>= 1; + AI_THINKING_STRUCT->aiLogicId++; + AI_THINKING_STRUCT->movesetIndex = 0; + } + //_08130DD8 + if (AI_THINKING_STRUCT->aiAction & AI_ACTION_FLEE) + actionOrMoveIndex[i] = 4; + else if (AI_THINKING_STRUCT->aiAction & AI_ACTION_WATCH) + actionOrMoveIndex[i] = 5; + else + { + //_08130E10 + mostViableMovesScores[0] = AI_THINKING_STRUCT->score[0]; + mostViableMovesIndices[0] = 0; + mostViableMovesNo = 1; + for (j = 1; j < 4; j++) + { + if (gBattleMons[sBank_AI].moves[j] != 0) + { + if (mostViableMovesScores[0] == AI_THINKING_STRUCT->score[j]) + { + mostViableMovesScores[mostViableMovesNo] = AI_THINKING_STRUCT->score[j]; + mostViableMovesIndices[mostViableMovesNo] = j; + mostViableMovesNo++; + } + if (mostViableMovesScores[0] < AI_THINKING_STRUCT->score[j]) + { + mostViableMovesScores[0] = AI_THINKING_STRUCT->score[j]; + mostViableMovesIndices[0] = j; + mostViableMovesNo = 1; + } + } + //_08130E72 + } + actionOrMoveIndex[i] = mostViableMovesIndices[Random() % mostViableMovesNo]; + bestMovePointsForTarget[i] = mostViableMovesScores[0]; + + // don't use a move against ally if it has less than 100 pts + if (i == (sBank_AI ^ 2) && bestMovePointsForTarget[i] < 100) + bestMovePointsForTarget[i] = -1; + } + } + //_08130EAE + } + + //08130EC4 + mostMovePoints = bestMovePointsForTarget[0]; + mostViableTargetsArray[0] = 0; + mostViableTargetsNo = 1; + for (i = 1; i < 4; i++) + { + //_08130EDA + if (mostMovePoints == bestMovePointsForTarget[i]) + { + mostViableTargetsArray[mostViableTargetsNo] = i; + mostViableTargetsNo++; + } + //_08130EEE + if (mostMovePoints < bestMovePointsForTarget[i]) + { + mostMovePoints = bestMovePointsForTarget[i]; + mostViableTargetsArray[0] = i; + mostViableTargetsNo = 1; + } + } + gBankTarget = mostViableTargetsArray[Random() % mostViableTargetsNo]; + return actionOrMoveIndex[gBankTarget]; +} +#else +__attribute__((naked)) +static u8 BattleAI_ChooseMoveOrAction_Doubles(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x24\n\ + movs r0, 0\n\ + mov r8, r0\n\ + mov r1, sp\n\ + adds r1, 0xC\n\ + str r1, [sp, 0x1C]\n\ + mov r2, sp\n\ + adds r2, 0x8\n\ + str r2, [sp, 0x18]\n\ + str r1, [sp, 0x20]\n\ + mov r10, sp\n\ +_08130D14:\n\ + ldr r0, =sBank_AI\n\ + ldrb r0, [r0]\n\ + cmp r8, r0\n\ + beq _08130D2E\n\ + movs r0, 0x58\n\ + mov r7, r8\n\ + muls r7, r0\n\ + adds r0, r7, 0\n\ + ldr r1, =gBattleMons\n\ + adds r0, r1\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + bne _08130D48\n\ +_08130D2E:\n\ + movs r0, 0xFF\n\ + ldr r2, [sp, 0x20]\n\ + strb r0, [r2]\n\ + ldr r0, =0x0000ffff\n\ + mov r7, r10\n\ + strh r0, [r7]\n\ + b _08130EAE\n\ + .pool\n\ +_08130D48:\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 10\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08130D70\n\ + ldr r0, =gBattleStruct\n\ + ldr r0, [r0]\n\ + adds r0, 0x92\n\ + ldrb r0, [r0]\n\ + lsrs r0, 4\n\ + bl BattleAI_SetupAIData\n\ + b _08130D76\n\ + .pool\n\ +_08130D70:\n\ + movs r0, 0xF\n\ + bl BattleAI_SetupAIData\n\ +_08130D76:\n\ + ldr r0, =gBankTarget\n\ + mov r1, r8\n\ + strb r1, [r0]\n\ + movs r1, 0x1\n\ + mov r2, r8\n\ + ands r2, r1\n\ + ldr r0, =sBank_AI\n\ + ldrb r0, [r0]\n\ + ands r1, r0\n\ + cmp r2, r1\n\ + beq _08130D90\n\ + bl RecordLastUsedMoveByTarget\n\ +_08130D90:\n\ + ldr r2, =gBattleResources\n\ + ldr r0, [r2]\n\ + ldr r0, [r0, 0x14]\n\ + movs r1, 0\n\ + strb r1, [r0, 0x11]\n\ + ldr r0, [r2]\n\ + ldr r0, [r0, 0x14]\n\ + strb r1, [r0, 0x1]\n\ + ldr r0, [r2]\n\ + ldr r0, [r0, 0x14]\n\ + ldr r4, [r0, 0xC]\n\ + mov r9, r2\n\ + cmp r4, 0\n\ + beq _08130DD8\n\ + mov r5, r9\n\ + movs r6, 0\n\ +_08130DB0:\n\ + movs r0, 0x1\n\ + ands r0, r4\n\ + cmp r0, 0\n\ + beq _08130DC2\n\ + ldr r0, [r5]\n\ + ldr r0, [r0, 0x14]\n\ + strb r6, [r0]\n\ + bl BattleAI_DoAIProcessing\n\ +_08130DC2:\n\ + asrs r4, 1\n\ + ldr r0, [r5]\n\ + ldr r1, [r0, 0x14]\n\ + ldrb r0, [r1, 0x11]\n\ + adds r0, 0x1\n\ + strb r0, [r1, 0x11]\n\ + ldr r0, [r5]\n\ + ldr r0, [r0, 0x14]\n\ + strb r6, [r0, 0x1]\n\ + cmp r4, 0\n\ + bne _08130DB0\n\ +_08130DD8:\n\ + mov r2, r9\n\ + ldr r0, [r2]\n\ + ldr r3, [r0, 0x14]\n\ + ldrb r1, [r3, 0x10]\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08130DFC\n\ + movs r0, 0x4\n\ + ldr r7, [sp, 0x20]\n\ + strb r0, [r7]\n\ + b _08130EAE\n\ + .pool\n\ +_08130DFC:\n\ + movs r0, 0x4\n\ + ands r0, r1\n\ + lsls r0, 24\n\ + lsrs r2, r0, 24\n\ + cmp r2, 0\n\ + beq _08130E10\n\ + movs r0, 0x5\n\ + ldr r1, [sp, 0x20]\n\ + strb r0, [r1]\n\ + b _08130EAE\n\ +_08130E10:\n\ + add r1, sp, 0x10\n\ + ldrb r0, [r3, 0x4]\n\ + strb r0, [r1]\n\ + add r0, sp, 0x14\n\ + strb r2, [r0]\n\ + movs r5, 0x1\n\ + movs r3, 0x1\n\ + adds r6, r1, 0\n\ + ldr r0, =sBank_AI\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + ldr r2, =gBattleMons + 0xC\n\ + adds r0, r2\n\ + adds r4, r0, 0x2\n\ + add r7, sp, 0x14\n\ +_08130E30:\n\ + ldrh r0, [r4]\n\ + cmp r0, 0\n\ + beq _08130E72\n\ + ldrb r1, [r6]\n\ + mov r2, r9\n\ + ldr r0, [r2]\n\ + ldr r0, [r0, 0x14]\n\ + adds r0, 0x4\n\ + adds r2, r0, r3\n\ + movs r0, 0\n\ + ldrsb r0, [r2, r0]\n\ + cmp r1, r0\n\ + bne _08130E56\n\ + adds r0, r6, r5\n\ + ldrb r1, [r2]\n\ + strb r1, [r0]\n\ + adds r0, r7, r5\n\ + strb r3, [r0]\n\ + adds r5, 0x1\n\ +_08130E56:\n\ + ldrb r1, [r6]\n\ + mov r2, r9\n\ + ldr r0, [r2]\n\ + ldr r0, [r0, 0x14]\n\ + adds r0, 0x4\n\ + adds r2, r0, r3\n\ + movs r0, 0\n\ + ldrsb r0, [r2, r0]\n\ + cmp r1, r0\n\ + bge _08130E72\n\ + ldrb r0, [r2]\n\ + strb r0, [r6]\n\ + strb r3, [r7]\n\ + movs r5, 0x1\n\ +_08130E72:\n\ + adds r4, 0x2\n\ + adds r3, 0x1\n\ + cmp r3, 0x3\n\ + ble _08130E30\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + adds r1, r5, 0\n\ + bl __modsi3\n\ + add r0, sp\n\ + adds r0, 0x14\n\ + ldrb r0, [r0]\n\ + ldr r7, [sp, 0x20]\n\ + strb r0, [r7]\n\ + ldrb r2, [r6]\n\ + mov r0, r10\n\ + strh r2, [r0]\n\ + ldr r0, =sBank_AI\n\ + ldrb r1, [r0]\n\ + movs r0, 0x2\n\ + eors r0, r1\n\ + cmp r8, r0\n\ + bne _08130EAE\n\ + cmp r2, 0x63\n\ + bgt _08130EAE\n\ + ldr r0, =0x0000ffff\n\ + mov r1, r10\n\ + strh r0, [r1]\n\ +_08130EAE:\n\ + ldr r2, [sp, 0x20]\n\ + adds r2, 0x1\n\ + str r2, [sp, 0x20]\n\ + movs r7, 0x2\n\ + add r10, r7\n\ + movs r0, 0x1\n\ + add r8, r0\n\ + mov r1, r8\n\ + cmp r1, 0x3\n\ + bgt _08130EC4\n\ + b _08130D14\n\ +_08130EC4:\n\ + mov r0, sp\n\ + ldrh r5, [r0]\n\ + movs r0, 0\n\ + ldr r2, [sp, 0x18]\n\ + strb r0, [r2]\n\ + movs r4, 0x1\n\ + mov r8, r4\n\ + ldr r6, =gBankTarget\n\ + ldr r3, [sp, 0x18]\n\ + mov r1, sp\n\ + adds r1, 0x2\n\ +_08130EDA:\n\ + lsls r0, r5, 16\n\ + asrs r2, r0, 16\n\ + movs r7, 0\n\ + ldrsh r0, [r1, r7]\n\ + cmp r2, r0\n\ + bne _08130EEE\n\ + adds r0, r3, r4\n\ + mov r7, r8\n\ + strb r7, [r0]\n\ + adds r4, 0x1\n\ +_08130EEE:\n\ + movs r7, 0\n\ + ldrsh r0, [r1, r7]\n\ + cmp r2, r0\n\ + bge _08130EFE\n\ + ldrh r5, [r1]\n\ + mov r0, r8\n\ + strb r0, [r3]\n\ + movs r4, 0x1\n\ +_08130EFE:\n\ + adds r1, 0x2\n\ + movs r2, 0x1\n\ + add r8, r2\n\ + mov r7, r8\n\ + cmp r7, 0x3\n\ + ble _08130EDA\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + adds r1, r4, 0\n\ + bl __modsi3\n\ + ldr r1, [sp, 0x18]\n\ + adds r0, r1, r0\n\ + ldrb r0, [r0]\n\ + strb r0, [r6]\n\ + ldrb r0, [r6]\n\ + ldr r2, [sp, 0x1C]\n\ + adds r0, r2, r0\n\ + ldrb r0, [r0]\n\ + add sp, 0x24\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r1}\n\ + bx r1\n\ + .pool\n\ + .syntax divided\n"); +} +#endif + +static void BattleAI_DoAIProcessing(void) +{ + while (AI_THINKING_STRUCT->aiState != AIState_FinishedProcessing) + { + switch (AI_THINKING_STRUCT->aiState) + { + case AIState_DoNotProcess: //Needed to match. + break; + case AIState_SettingUp: + gAIScriptPtr = gBattleAI_ScriptsTable[AI_THINKING_STRUCT->aiLogicId]; // set AI ptr to logic ID. + if (gBattleMons[sBank_AI].pp[AI_THINKING_STRUCT->movesetIndex] == 0) + { + AI_THINKING_STRUCT->moveConsidered = 0; + } + else + { + AI_THINKING_STRUCT->moveConsidered = gBattleMons[sBank_AI].moves[AI_THINKING_STRUCT->movesetIndex]; + } + AI_THINKING_STRUCT->aiState++; + break; + case AIState_Processing: + if (AI_THINKING_STRUCT->moveConsidered != 0) + sBattleAICmdTable[*gAIScriptPtr](); // run AI command. + else + { + AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; + AI_THINKING_STRUCT->aiAction |= AI_ACTION_DONE; + } + if (AI_THINKING_STRUCT->aiAction & AI_ACTION_DONE) + { + AI_THINKING_STRUCT->movesetIndex++; + + if (AI_THINKING_STRUCT->movesetIndex < 4 && !(AI_THINKING_STRUCT->aiAction & AI_ACTION_DO_NOT_ATTACK)) + AI_THINKING_STRUCT->aiState = AIState_SettingUp; + else + AI_THINKING_STRUCT->aiState++; + + AI_THINKING_STRUCT->aiAction &= ~(AI_ACTION_DONE); + } + break; + } + } +} + +static void RecordLastUsedMoveByTarget(void) +{ + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleResources->battleHistory->usedMoves[gBankTarget].moves[i] == gLastUsedMovesByBanks[gBankTarget]) + break; + if (gBattleResources->battleHistory->usedMoves[gBankTarget].moves[i] != gLastUsedMovesByBanks[gBankTarget] //HACK: This redundant condition is a hack to make the asm match. + && gBattleResources->battleHistory->usedMoves[gBankTarget].moves[i] == 0) + { + gBattleResources->battleHistory->usedMoves[gBankTarget].moves[i] = gLastUsedMovesByBanks[gBankTarget]; + break; + } + } +} + +void ClearBankMoveHistory(u8 bank) +{ + s32 i; + + for (i = 0; i < 4; i++) + gBattleResources->battleHistory->usedMoves[bank].moves[i] = 0; +} + +void RecordAbilityBattle(u8 bank, u8 abilityId) +{ + gBattleResources->battleHistory->abilities[bank] = abilityId; +} + +void ClearBankAbilityHistory(u8 bank) +{ + gBattleResources->battleHistory->abilities[bank] = 0; +} + +void RecordItemEffectBattle(u8 bank, u8 itemEffect) +{ + gBattleResources->battleHistory->itemEffects[bank] = itemEffect; +} + +void ClearBankItemEffectHistory(u8 bank) +{ + gBattleResources->battleHistory->itemEffects[bank] = 0; +} + +static void BattleAICmd_if_random_less_than(void) +{ + u16 random = Random(); + + if (random % 256 < gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_random_greater_than(void) +{ + u16 random = Random(); + + if (random % 256 > gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_random_equal(void) +{ + u16 random = Random(); + + if (random % 256 == gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_random_not_equal(void) +{ + u16 random = Random(); + + if (random % 256 != gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_score(void) +{ + AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] += gAIScriptPtr[1]; // add the result to the array of the move consider's score. + + if (AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] < 0) // if the score is negative, flatten it to 0. + AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; + + gAIScriptPtr += 2; // AI return. +} + +static void BattleAICmd_if_hp_less_than(void) +{ + u16 index; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) < gAIScriptPtr[2]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_hp_more_than(void) +{ + u16 index; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) > gAIScriptPtr[2]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_hp_equal(void) +{ + u16 index; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) == gAIScriptPtr[2]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_hp_not_equal(void) +{ + u16 index; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) != gAIScriptPtr[2]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_status(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + arg = AIScriptRead32(gAIScriptPtr + 2); + + if ((gBattleMons[index].status1 & arg) != 0) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_not_status(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + arg = AIScriptRead32(gAIScriptPtr + 2); + + if ((gBattleMons[index].status1 & arg) == 0) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_status2(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + arg = AIScriptRead32(gAIScriptPtr + 2); + + if ((gBattleMons[index].status2 & arg) != 0) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_not_status2(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + arg = AIScriptRead32(gAIScriptPtr + 2); + + if ((gBattleMons[index].status2 & arg) == 0) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_status3(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + arg = AIScriptRead32(gAIScriptPtr + 2); + + if ((gStatuses3[index] & arg) != 0) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_not_status3(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + arg = AIScriptRead32(gAIScriptPtr + 2); + + if ((gStatuses3[index] & arg) == 0) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_side_affecting(void) +{ + u16 index; + u32 arg1, arg2; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + arg1 = GetBankIdentity(index) & 1; + arg2 = AIScriptRead32(gAIScriptPtr + 2); + + if ((gSideAffecting[arg1] & arg2) != 0) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_not_side_affecting(void) +{ + u16 index; + u32 arg1, arg2; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + arg1 = GetBankIdentity(index) & 1; + arg2 = AIScriptRead32(gAIScriptPtr + 2); + + if ((gSideAffecting[arg1] & arg2) == 0) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_less_than(void) +{ + if (AI_THINKING_STRUCT->funcResult < gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_more_than(void) +{ + if (AI_THINKING_STRUCT->funcResult > gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_equal(void) +{ + if (AI_THINKING_STRUCT->funcResult == gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_not_equal(void) +{ + if (AI_THINKING_STRUCT->funcResult != gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_less_than_32(void) +{ + u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->funcResult < *temp) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_more_than_32(void) +{ + u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->funcResult > *temp) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_equal_32(void) +{ + u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->funcResult == *temp) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_not_equal_32(void) +{ + u8 *temp = AIScriptReadPtr(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->funcResult != *temp) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_move(void) +{ + u16 move = AIScriptRead16(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->moveConsidered == move) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_not_move(void) +{ + u16 move = AIScriptRead16(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->moveConsidered != move) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_in_bytes(void) +{ + u8 *ptr = AIScriptReadPtr(gAIScriptPtr + 1); + + while (*ptr != 0xFF) + { + if (AI_THINKING_STRUCT->funcResult == *ptr) + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); + return; + } + ptr++; + } + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_not_in_bytes(void) +{ + u8 *ptr = AIScriptReadPtr(gAIScriptPtr + 1); + + while (*ptr != 0xFF) + { + if (AI_THINKING_STRUCT->funcResult == *ptr) + { + gAIScriptPtr += 9; + return; + } + ptr++; + } + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); +} + +static void BattleAICmd_if_in_words(void) +{ + u16 *ptr = (u16 *)AIScriptReadPtr(gAIScriptPtr + 1); + + while (*ptr != 0xFFFF) + { + if (AI_THINKING_STRUCT->funcResult == *ptr) + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); + return; + } + ptr++; + } + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_not_in_words(void) +{ + u16 *ptr = (u16 *)AIScriptReadPtr(gAIScriptPtr + 1); + + while (*ptr != 0xFFFF) + { + if (AI_THINKING_STRUCT->funcResult == *ptr) + { + gAIScriptPtr += 9; + return; + } + ptr++; + } + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5); +} + +static void BattleAICmd_if_user_can_damage(void) +{ + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[sBank_AI].moves[i] != 0 + && gBattleMoves[gBattleMons[sBank_AI].moves[i]].power != 0) + break; + } + if (i == 4) + gAIScriptPtr += 5; + else + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); +} + +static void BattleAICmd_if_user_cant_damage(void) +{ + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[sBank_AI].moves[i] != 0 + && gBattleMoves[gBattleMons[sBank_AI].moves[i]].power != 0) + break; + } + if (i != 4) + gAIScriptPtr += 5; + else + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); +} + +static void BattleAICmd_get_turn_count(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleResults.battleTurnCounter; + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_type(void) +{ + u8 typeVar = gAIScriptPtr[1]; + + switch (typeVar) + { + case 1: // player primary type + AI_THINKING_STRUCT->funcResult = gBattleMons[sBank_AI].type1; + break; + case 0: // enemy primary type + AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type1; + break; + case 3: // player secondary type + AI_THINKING_STRUCT->funcResult = gBattleMons[sBank_AI].type2; + break; + case 2: // enemy secondary type + AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type2; + break; + case 4: // type of move being pointed to + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].type; + break; + } + gAIScriptPtr += 2; +} + +static u8 BattleAI_GetWantedBank(u8 index) +{ + switch (index) + { + case AI_USER: + return sBank_AI; + case AI_TARGET: + default: + return gBankTarget; + case AI_USER_PARTNER: + return sBank_AI ^ 2; + case AI_TARGET_PARTNER: + return gBankTarget ^ 2; + } +} + +static void BattleAICmd_is_of_type(void) +{ + u8 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]); + + if(gBattleMons[bank].type1 == gAIScriptPtr[2] || gBattleMons[bank].type2 == gAIScriptPtr[2]) + { + AI_THINKING_STRUCT->funcResult = 1; + } + else + { + AI_THINKING_STRUCT->funcResult = 0; + } + + gAIScriptPtr += 3; +} + +static void BattleAICmd_get_last_used_bank_move_power(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power; + gAIScriptPtr += 1; +} + +__attribute__((naked)) // not even going to try. if it doesnt match in ruby, it wont match in emerald (yet). +static void BattleAICmd_is_most_powerful_move(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x14\n\ + movs r3, 0\n\ + ldr r0, =sDiscouragedPowerfulMoveEffects\n\ + ldrh r1, [r0]\n\ + ldr r5, =0x0000ffff\n\ + ldr r6, =gBattleMoves\n\ + ldr r2, =gBattleResources\n\ + cmp r1, r5\n\ + beq _08131F86\n\ + ldr r0, [r2]\n\ + ldr r0, [r0, 0x14]\n\ + ldrh r1, [r0, 0x2]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldrb r4, [r0]\n\ + ldr r1, =sDiscouragedPowerfulMoveEffects\n\ +_08131F76:\n\ + ldrh r0, [r1]\n\ + cmp r4, r0\n\ + beq _08131F86\n\ + adds r1, 0x2\n\ + adds r3, 0x1\n\ + ldrh r0, [r1]\n\ + cmp r0, r5\n\ + bne _08131F76\n\ +_08131F86:\n\ + ldr r0, [r2]\n\ + ldr r0, [r0, 0x14]\n\ + ldrh r1, [r0, 0x2]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldrb r0, [r0, 0x1]\n\ + cmp r0, 0x1\n\ + bhi _08131F9C\n\ + b _08132126\n\ +_08131F9C:\n\ + lsls r0, r3, 1\n\ + ldr r1, =sDiscouragedPowerfulMoveEffects\n\ + adds r0, r1\n\ + ldrh r3, [r0]\n\ + ldr r0, =0x0000ffff\n\ + cmp r3, r0\n\ + beq _08131FAC\n\ + b _08132126\n\ +_08131FAC:\n\ + ldr r0, =gDynamicBasePower\n\ + movs r1, 0\n\ + strh r1, [r0]\n\ + ldr r0, =gBattleStruct\n\ + ldr r0, [r0]\n\ + strb r1, [r0, 0x13]\n\ + ldr r0, =gBattleScripting\n\ + movs r2, 0x1\n\ + strb r2, [r0, 0xE]\n\ + ldr r0, =gBattleMoveFlags\n\ + strb r1, [r0]\n\ + ldr r0, =gCritMultiplier\n\ + strb r2, [r0]\n\ + movs r6, 0\n\ + mov r9, r3\n\ + ldr r2, =sDiscouragedPowerfulMoveEffects\n\ + ldrh r2, [r2]\n\ + str r2, [sp, 0x10]\n\ +_08131FD0:\n\ + movs r3, 0\n\ + ldr r5, =gBattleMons\n\ + lsls r4, r6, 1\n\ + ldr r7, =sBank_AI\n\ + lsls r0, r6, 2\n\ + mov r8, r0\n\ + adds r1, r6, 0x1\n\ + mov r10, r1\n\ + ldr r2, [sp, 0x10]\n\ + cmp r2, r9\n\ + beq _08132014\n\ + ldr r2, =gBattleMoves\n\ + ldrb r1, [r7]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r4, r0\n\ + adds r1, r5, 0\n\ + adds r1, 0xC\n\ + adds r0, r1\n\ + ldrh r1, [r0]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r2, [r0]\n\ + ldr r1, =sDiscouragedPowerfulMoveEffects\n\ +_08132004:\n\ + ldrh r0, [r1]\n\ + cmp r2, r0\n\ + beq _08132014\n\ + adds r1, 0x2\n\ + adds r3, 0x1\n\ + ldrh r0, [r1]\n\ + cmp r0, r9\n\ + bne _08132004\n\ +_08132014:\n\ + ldrb r1, [r7]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r4, r0\n\ + adds r1, r5, 0\n\ + adds r1, 0xC\n\ + adds r1, r0, r1\n\ + ldrh r0, [r1]\n\ + cmp r0, 0\n\ + beq _081320C0\n\ + lsls r0, r3, 1\n\ + ldr r2, =sDiscouragedPowerfulMoveEffects\n\ + adds r0, r2\n\ + ldrh r0, [r0]\n\ + cmp r0, r9\n\ + bne _081320C0\n\ + ldr r0, =gBattleMoves\n\ + ldrh r2, [r1]\n\ + lsls r1, r2, 1\n\ + adds r1, r2\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + cmp r0, 0x1\n\ + bls _081320C0\n\ + ldr r5, =gCurrentMove\n\ + strh r2, [r5]\n\ + ldrb r0, [r7]\n\ + ldr r4, =gBankTarget\n\ + ldrb r1, [r4]\n\ + bl AI_CalcDmg\n\ + ldrh r0, [r5]\n\ + ldrb r1, [r7]\n\ + ldrb r2, [r4]\n\ + bl TypeCalc\n\ + mov r4, sp\n\ + add r4, r8\n\ + ldr r2, =gBattleMoveDamage\n\ + ldr r0, =gBattleResources\n\ + ldr r0, [r0]\n\ + ldr r0, [r0, 0x14]\n\ + adds r0, 0x18\n\ + adds r0, r6\n\ + ldrb r1, [r0]\n\ + ldr r0, [r2]\n\ + muls r0, r1\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + str r0, [r4]\n\ + cmp r0, 0\n\ + bne _081320C8\n\ + movs r0, 0x1\n\ + str r0, [r4]\n\ + b _081320C8\n\ + .pool\n\ +_081320C0:\n\ + mov r1, sp\n\ + add r1, r8\n\ + movs r0, 0\n\ + str r0, [r1]\n\ +_081320C8:\n\ + mov r6, r10\n\ + cmp r6, 0x3\n\ + bgt _081320D0\n\ + b _08131FD0\n\ +_081320D0:\n\ + movs r6, 0\n\ + ldr r2, =gBattleResources\n\ + ldr r0, [r2]\n\ + ldr r0, [r0, 0x14]\n\ + ldrb r0, [r0, 0x1]\n\ + lsls r0, 2\n\ + add r0, sp\n\ + ldr r1, [sp]\n\ + ldr r0, [r0]\n\ + ldr r5, =gAIScriptPtr\n\ + cmp r1, r0\n\ + bgt _08132106\n\ + adds r4, r2, 0\n\ + mov r3, sp\n\ +_081320EC:\n\ + adds r3, 0x4\n\ + adds r6, 0x1\n\ + cmp r6, 0x3\n\ + bgt _08132106\n\ + ldr r0, [r4]\n\ + ldr r0, [r0, 0x14]\n\ + ldrb r0, [r0, 0x1]\n\ + lsls r0, 2\n\ + add r0, sp\n\ + ldr r1, [r3]\n\ + ldr r0, [r0]\n\ + cmp r1, r0\n\ + ble _081320EC\n\ +_08132106:\n\ + cmp r6, 0x4\n\ + bne _0813211C\n\ + ldr r0, [r2]\n\ + ldr r1, [r0, 0x14]\n\ + movs r0, 0x2\n\ + str r0, [r1, 0x8]\n\ + b _08132130\n\ + .pool\n\ +_0813211C:\n\ + ldr r0, [r2]\n\ + ldr r1, [r0, 0x14]\n\ + movs r0, 0x1\n\ + str r0, [r1, 0x8]\n\ + b _08132130\n\ +_08132126:\n\ + ldr r0, [r2]\n\ + ldr r1, [r0, 0x14]\n\ + movs r0, 0\n\ + str r0, [r1, 0x8]\n\ + ldr r5, =gAIScriptPtr\n\ +_08132130:\n\ + ldr r0, [r5]\n\ + adds r0, 0x1\n\ + str r0, [r5]\n\ + add sp, 0x14\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} + +static void BattleAICmd_get_last_used_bank_move(void) +{ + if (gAIScriptPtr[1] == AI_USER) + AI_THINKING_STRUCT->funcResult = gLastUsedMovesByBanks[sBank_AI]; + else + AI_THINKING_STRUCT->funcResult = gLastUsedMovesByBanks[gBankTarget]; + + gAIScriptPtr += 2; +} + +static void BattleAICmd_if_arg_equal(void) +{ + if (gAIScriptPtr[1] == AI_THINKING_STRUCT->funcResult) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_arg_not_equal(void) +{ + if (gAIScriptPtr[1] != AI_THINKING_STRUCT->funcResult) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_would_go_first(void) +{ + if (b_first_side(sBank_AI, gBankTarget, 1) == gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_would_not_go_first(void) +{ + if (b_first_side(sBank_AI, gBankTarget, 1) != gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_nullsub_2A(void) +{ +} + +static void BattleAICmd_nullsub_2B(void) +{ +} + +static void BattleAICmd_count_alive_pokemon(void) +{ + u8 index; + u8 bankOnField1, bankOnField2; + struct Pokemon *party; + int i; + + AI_THINKING_STRUCT->funcResult = 0; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + if (GetBankSide(index) == 0) + party = gPlayerParty; + else + party = gEnemyParty; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + u32 status; + bankOnField1 = gBattlePartyID[index]; + status = GetBankIdentity(index) ^ 2; + bankOnField2 = gBattlePartyID[GetBankByIdentity(status)]; + } + else // in singles there's only one bank by side + { + bankOnField1 = gBattlePartyID[index]; + bankOnField2 = gBattlePartyID[index]; + } + + for (i = 0; i < 6; i++) + { + if (i != bankOnField1 && i != bankOnField2 + && GetMonData(&party[i], MON_DATA_HP) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_NONE + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) + { + AI_THINKING_STRUCT->funcResult++; + } + } + + gAIScriptPtr += 2; +} + +static void BattleAICmd_get_considered_move(void) +{ + AI_THINKING_STRUCT->funcResult = AI_THINKING_STRUCT->moveConsidered; + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_considered_move_effect(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect; + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_ability(void) +{ + u8 index; + + if (gAIScriptPtr[1] == AI_USER) + index = sBank_AI; + else + index = gBankTarget; + + if(gActiveBank != index) + { + if(BATTLE_HISTORY->abilities[index] != 0) + { + AI_THINKING_STRUCT->funcResult = BATTLE_HISTORY->abilities[index]; + gAIScriptPtr += 2; + return; + } + + // abilities that prevent fleeing. + if (gBattleMons[index].ability == ABILITY_SHADOW_TAG + || gBattleMons[index].ability == ABILITY_MAGNET_PULL + || gBattleMons[index].ability == ABILITY_ARENA_TRAP) + { + AI_THINKING_STRUCT->funcResult = gBattleMons[index].ability; + gAIScriptPtr += 2; + return; + } + + if (gBaseStats[gBattleMons[index].species].ability1 != ABILITY_NONE) + { + if (gBaseStats[gBattleMons[index].species].ability2 != ABILITY_NONE) + { + // AI has no knowledge of opponent, so it guesses which ability. + if (Random() & 1) + { + AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability1; + } + else + { + AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability2; + } + } + else + { + AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability1; // it's definitely ability 1. + } + } + else + { + AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability. + } + } + else + { + // The AI knows its own ability. + AI_THINKING_STRUCT->funcResult = gBattleMons[index].ability; + } + gAIScriptPtr += 2; +} + +#ifdef NONMATCHING +static void BattleAICmd_check_ability(void) +{ + u8 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]); + u8 ability = gAIScriptPtr[2]; + + if (gAIScriptPtr[1] == AI_TARGET || gAIScriptPtr[1] == AI_TARGET_PARTNER) + { + if (BATTLE_HISTORY->abilities[bank] != 0) + { + ability = BATTLE_HISTORY->abilities[bank]; + AI_THINKING_STRUCT->funcResult = ability; + } + // abilities that prevent fleeing. + else if (gBattleMons[bank].ability == ABILITY_SHADOW_TAG + || gBattleMons[bank].ability == ABILITY_MAGNET_PULL + || gBattleMons[bank].ability == ABILITY_ARENA_TRAP) + { + ability = gBattleMons[bank].ability; + } + else if (gBaseStats[gBattleMons[bank].species].ability1 != ABILITY_NONE) + { + if (gBaseStats[gBattleMons[bank].species].ability2 != ABILITY_NONE) + { + if (gBaseStats[gBattleMons[bank].species].ability1 != ability + && gBaseStats[gBattleMons[bank].species].ability2 != ability) + { + ability = gBaseStats[gBattleMons[bank].species].ability1; + } + else + ability = 0; + } + else + { + ability = gBaseStats[gBattleMons[bank].species].ability1; + } + } + else + { + ability = gBaseStats[gBattleMons[bank].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability. + } + } + else + { + // The AI knows its own or partner's ability. + ability = gBattleMons[bank].ability; + } + if (ability == 0) + { + AI_THINKING_STRUCT->funcResult = 2; // unable to answer + } + else if (ability == gAIScriptPtr[2]) + { + AI_THINKING_STRUCT->funcResult = 1; // pokemon has the ability we wanted to check + } + else + { + AI_THINKING_STRUCT->funcResult = 0; // pokemon doesn't have the ability we wanted to check + } + gAIScriptPtr += 3; +} +#else +__attribute__((naked)) +static void BattleAICmd_check_ability(void) +{ + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + ldr r4, =gAIScriptPtr\n\ + ldr r0, [r4]\n\ + ldrb r0, [r0, 0x1]\n\ + bl BattleAI_GetWantedBank\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + ldr r0, [r4]\n\ + ldrb r3, [r0, 0x2]\n\ + ldrb r0, [r0, 0x1]\n\ + cmp r0, 0\n\ + beq _0813253A\n\ + cmp r0, 0x2\n\ + bne _081325BC\n\ +_0813253A:\n\ + ldr r0, =gBattleResources\n\ + ldr r4, [r0]\n\ + ldr r1, [r4, 0x18]\n\ + adds r1, 0x40\n\ + adds r2, r1, r5\n\ + ldrb r1, [r2]\n\ + adds r6, r0, 0\n\ + cmp r1, 0\n\ + beq _0813255C\n\ + adds r3, r1, 0\n\ + ldr r0, [r4, 0x14]\n\ + str r3, [r0, 0x8]\n\ + b _081325CA\n\ + .pool\n\ +_0813255C:\n\ + ldr r1, =gBattleMons\n\ + movs r0, 0x58\n\ + muls r0, r5\n\ + adds r4, r0, r1\n\ + adds r0, r4, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x17\n\ + beq _08132576\n\ + cmp r0, 0x2A\n\ + beq _08132576\n\ + cmp r0, 0x47\n\ + bne _08132588\n\ +_08132576:\n\ + movs r0, 0x58\n\ + muls r0, r5\n\ + adds r0, r1\n\ + adds r0, 0x20\n\ + ldrb r3, [r0]\n\ + b _081325CA\n\ + .pool\n\ +_08132588:\n\ + ldr r2, =gBaseStats\n\ + ldrh r1, [r4]\n\ + lsls r0, r1, 3\n\ + subs r0, r1\n\ + lsls r0, 2\n\ + adds r1, r0, r2\n\ + ldrb r4, [r1, 0x16]\n\ + cmp r4, 0\n\ + beq _081325B8\n\ + ldrb r2, [r1, 0x17]\n\ + cmp r2, 0\n\ + beq _081325B4\n\ + adds r0, r3, 0\n\ + cmp r4, r0\n\ + beq _081325CE\n\ + cmp r2, r0\n\ + beq _081325CE\n\ + adds r3, r4, 0\n\ + b _081325CA\n\ + .pool\n\ +_081325B4:\n\ + ldrb r3, [r1, 0x16]\n\ + b _081325CA\n\ +_081325B8:\n\ + ldrb r3, [r1, 0x17]\n\ + b _081325CA\n\ +_081325BC:\n\ + ldr r1, =gBattleMons\n\ + movs r0, 0x58\n\ + muls r0, r5\n\ + adds r0, r1\n\ + adds r0, 0x20\n\ + ldrb r3, [r0]\n\ + ldr r6, =gBattleResources\n\ +_081325CA:\n\ + cmp r3, 0\n\ + bne _081325E8\n\ +_081325CE:\n\ + ldr r0, [r6]\n\ + ldr r1, [r0, 0x14]\n\ + movs r0, 0x2\n\ + str r0, [r1, 0x8]\n\ + ldr r2, =gAIScriptPtr\n\ + b _08132608\n\ + .pool\n\ +_081325E8:\n\ + ldr r0, =gAIScriptPtr\n\ + ldr r1, [r0]\n\ + adds r2, r0, 0\n\ + ldrb r1, [r1, 0x2]\n\ + cmp r3, r1\n\ + bne _08132600\n\ + ldr r0, [r6]\n\ + ldr r1, [r0, 0x14]\n\ + movs r0, 0x1\n\ + b _08132606\n\ + .pool\n\ +_08132600:\n\ + ldr r0, [r6]\n\ + ldr r1, [r0, 0x14]\n\ + movs r0, 0\n\ +_08132606:\n\ + str r0, [r1, 0x8]\n\ +_08132608:\n\ + ldr r0, [r2]\n\ + adds r0, 0x3\n\ + str r0, [r2]\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} +#endif + +static void BattleAICmd_get_highest_type_effectiveness(void) +{ + s32 i; + u8* dynamicMoveType; + + gDynamicBasePower = 0; + dynamicMoveType = &gBattleStruct->dynamicMoveType; + *dynamicMoveType = 0; + gBattleScripting.dmgMultiplier = 1; + gBattleMoveFlags = 0; + gCritMultiplier = 1; + AI_THINKING_STRUCT->funcResult = 0; + + for (i = 0; i < 4; i++) + { + gBattleMoveDamage = 40; + gCurrentMove = gBattleMons[sBank_AI].moves[i]; + + if (gCurrentMove) + { + TypeCalc(gCurrentMove, sBank_AI, gBankTarget); + + // reduce by 1/3. + if (gBattleMoveDamage == 120) + gBattleMoveDamage = 80; + if (gBattleMoveDamage == 240) + gBattleMoveDamage = 160; + if (gBattleMoveDamage == 30) + gBattleMoveDamage = 20; + if (gBattleMoveDamage == 15) + gBattleMoveDamage = 10; + + if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) + gBattleMoveDamage = 0; + + if (AI_THINKING_STRUCT->funcResult < gBattleMoveDamage) + AI_THINKING_STRUCT->funcResult = gBattleMoveDamage; + } + } + gAIScriptPtr += 1; +} + +static void BattleAICmd_if_type_effectiveness(void) +{ + u8 damageVar; + + gDynamicBasePower = 0; + gBattleStruct->dynamicMoveType = 0; + gBattleScripting.dmgMultiplier = 1; + gBattleMoveFlags = 0; + gCritMultiplier = 1; + + gBattleMoveDamage = 40; + gCurrentMove = AI_THINKING_STRUCT->moveConsidered; + + TypeCalc(gCurrentMove, sBank_AI, gBankTarget); + + if (gBattleMoveDamage == 120) + gBattleMoveDamage = 80; + if (gBattleMoveDamage == 240) + gBattleMoveDamage = 160; + if (gBattleMoveDamage == 30) + gBattleMoveDamage = 20; + if (gBattleMoveDamage == 15) + gBattleMoveDamage = 10; + + if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) + gBattleMoveDamage = 0; + + // store gBattleMoveDamage in a u8 variable because gAIScriptPtr[1] is a u8. + damageVar = gBattleMoveDamage; + + if (damageVar == gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_nullsub_32(void) +{ +} + +static void BattleAICmd_nullsub_33(void) +{ +} + +static void BattleAICmd_if_status_in_party(void) +{ + struct Pokemon *party; + int i; + u32 statusToCompareTo; + u8 index; + + switch(gAIScriptPtr[1]) + { + case 1: + index = sBank_AI; + break; + default: + index = gBankTarget; + break; + } + + party = (GetBankSide(index) == 0) ? gPlayerParty : gEnemyParty; + + statusToCompareTo = AIScriptRead32(gAIScriptPtr + 2); + + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&party[i], MON_DATA_SPECIES); + u16 hp = GetMonData(&party[i], MON_DATA_HP); + u32 status = GetMonData(&party[i], MON_DATA_STATUS); + + if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo) + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); + return; + } + } + + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_status_not_in_party(void) +{ + struct Pokemon *party; + int i; + u32 statusToCompareTo; + u8 index; + + switch(gAIScriptPtr[1]) + { + case 1: + index = sBank_AI; + break; + default: + index = gBankTarget; + break; + } + + party = (GetBankSide(index) == 0) ? gPlayerParty : gEnemyParty; + + statusToCompareTo = AIScriptRead32(gAIScriptPtr + 2); + + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&party[i], MON_DATA_SPECIES); + u16 hp = GetMonData(&party[i], MON_DATA_HP); + u32 status = GetMonData(&party[i], MON_DATA_STATUS); + + if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo) + { + gAIScriptPtr += 10; // still bugged in Emerald + } + } + + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6); +} + +static void BattleAICmd_get_weather(void) +{ + if (gBattleWeather & WEATHER_RAIN_ANY) + AI_THINKING_STRUCT->funcResult = 1; + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + AI_THINKING_STRUCT->funcResult = 2; + if (gBattleWeather & WEATHER_SUN_ANY) + AI_THINKING_STRUCT->funcResult = 0; + if (gBattleWeather & WEATHER_HAIL_ANY) + AI_THINKING_STRUCT->funcResult = 3; + + gAIScriptPtr += 1; +} + +static void BattleAICmd_if_effect(void) +{ + if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_not_effect(void) +{ + if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect != gAIScriptPtr[1]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_stat_level_less_than(void) +{ + u32 bank; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + if (gBattleMons[bank].statStages[gAIScriptPtr[2]] < gAIScriptPtr[3]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); + else + gAIScriptPtr += 8; +} + +static void BattleAICmd_if_stat_level_more_than(void) +{ + u32 bank; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + if (gBattleMons[bank].statStages[gAIScriptPtr[2]] > gAIScriptPtr[3]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); + else + gAIScriptPtr += 8; +} + +static void BattleAICmd_if_stat_level_equal(void) +{ + u32 bank; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + if (gBattleMons[bank].statStages[gAIScriptPtr[2]] == gAIScriptPtr[3]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); + else + gAIScriptPtr += 8; +} + +static void BattleAICmd_if_stat_level_not_equal(void) +{ + u32 bank; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + if (gBattleMons[bank].statStages[gAIScriptPtr[2]] != gAIScriptPtr[3]) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); + else + gAIScriptPtr += 8; +} + +static void BattleAICmd_if_can_faint(void) +{ + if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power < 2) + { + gAIScriptPtr += 5; + return; + } + + gDynamicBasePower = 0; + gBattleStruct->dynamicMoveType = 0; + gBattleScripting.dmgMultiplier = 1; + gBattleMoveFlags = 0; + gCritMultiplier = 1; + gCurrentMove = AI_THINKING_STRUCT->moveConsidered; + AI_CalcDmg(sBank_AI, gBankTarget); + TypeCalc(gCurrentMove, sBank_AI, gBankTarget); + + gBattleMoveDamage = gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[AI_THINKING_STRUCT->movesetIndex] / 100; + + // moves always do at least 1 damage. + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + if (gBattleMons[gBankTarget].hp <= gBattleMoveDamage) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +static void BattleAICmd_if_cant_faint(void) +{ + if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power < 2) + { + gAIScriptPtr += 5; + return; + } + + gDynamicBasePower = 0; + gBattleStruct->dynamicMoveType = 0; + gBattleScripting.dmgMultiplier = 1; + gBattleMoveFlags = 0; + gCritMultiplier = 1; + gCurrentMove = AI_THINKING_STRUCT->moveConsidered; + AI_CalcDmg(sBank_AI, gBankTarget); + TypeCalc(gCurrentMove, sBank_AI, gBankTarget); + + gBattleMoveDamage = gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[AI_THINKING_STRUCT->movesetIndex] / 100; + + // this macro is missing the damage 0 = 1 assumption. + + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +static void BattleAICmd_if_has_move(void) +{ + int i; + u16 *temp_ptr = (u16 *)(gAIScriptPtr + 2); + + switch(gAIScriptPtr[1]) + { + case AI_USER: + for (i = 0; i < 4; i++) + { + if (gBattleMons[sBank_AI].moves[i] == *temp_ptr) + break; + } + if (i == 4) + { + gAIScriptPtr += 8; + return; + } + else + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); + return; + } + case AI_USER_PARTNER: + if (gBattleMons[sBank_AI ^ 2].hp == 0) + { + gAIScriptPtr += 8; + return; + } + else + { + for (i = 0; i < 4; i++) + { + if (gBattleMons[sBank_AI ^ 2].moves[i] == *temp_ptr) + break; + } + } + if (i == 4) + { + gAIScriptPtr += 8; + return; + } + else + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); + return; + } + case AI_TARGET: + case AI_TARGET_PARTNER: + for (i = 0; i < 4; i++) + { + if (BATTLE_HISTORY->usedMoves[gBankTarget].moves[i] == *temp_ptr) + break; + } + if (i == 4) + { + gAIScriptPtr += 8; + return; + } + else + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); + return; + } + } +} + +static void BattleAICmd_if_dont_have_move(void) +{ + int i; + u16 *temp_ptr = (u16 *)(gAIScriptPtr + 2); + + switch(gAIScriptPtr[1]) + { + case AI_USER: + case AI_USER_PARTNER: // UB: no separate check for user partner + for (i = 0; i < 4; i++) + { + if (gBattleMons[sBank_AI].moves[i] == *temp_ptr) + break; + } + if (i != 4) + { + gAIScriptPtr += 8; + return; + } + else + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); + return; + } + case AI_TARGET: + case AI_TARGET_PARTNER: + for (i = 0; i < 4; i++) + { + if (BATTLE_HISTORY->usedMoves[gBankTarget].moves[i] == *temp_ptr) + break; + } + if (i != 4) + { + gAIScriptPtr += 8; + return; + } + else + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); + return; + } + } +} + +static void BattleAICmd_if_move_effect(void) +{ + int i; + + switch (gAIScriptPtr[1]) + { + case AI_USER: + case AI_USER_PARTNER: + for (i = 0; i < 4; i++) + { + if(gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[gBattleMons[sBank_AI].moves[i]].effect == gAIScriptPtr[2]) + break; + } + if (i == 4) + gAIScriptPtr += 7; + else + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + break; + case AI_TARGET: + case AI_TARGET_PARTNER: + for (i = 0; i < 4; i++) + { + if (gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[BATTLE_HISTORY->usedMoves[gBankTarget].moves[i]].effect == gAIScriptPtr[2]) + break; + } + if (i == 4) + gAIScriptPtr += 7; + else + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + break; + } +} + +static void BattleAICmd_if_not_move_effect(void) +{ + int i; + + switch (gAIScriptPtr[1]) + { + case AI_USER: + case AI_USER_PARTNER: + for (i = 0; i < 4; i++) + { + if(gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[gBattleMons[sBank_AI].moves[i]].effect == gAIScriptPtr[2]) + break; + } + if (i != 4) + gAIScriptPtr += 7; + else + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + break; + case AI_TARGET: + case AI_TARGET_PARTNER: + for (i = 0; i < 4; i++) + { + if (BATTLE_HISTORY->usedMoves[gBankTarget].moves[i] && gBattleMoves[BATTLE_HISTORY->usedMoves[gBankTarget].moves[i]].effect == gAIScriptPtr[2]) + break; + } + if (i != 4) + gAIScriptPtr += 7; + else + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + break; + } +} + +static void BattleAICmd_if_any_move_disabled_or_encored(void) +{ + u8 bank; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + if (gAIScriptPtr[2] == 0) + { + if (gDisableStructs[bank].disabledMove == 0) + { + gAIScriptPtr += 7; + return; + } + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + return; + } + else if (gAIScriptPtr[2] != 1) // ignore the macro if its not 0 or 1. + { + gAIScriptPtr += 7; + return; + } + else if (gDisableStructs[bank].encoredMove != 0) + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3); + return; + } + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_curr_move_disabled_or_encored(void) +{ + switch (gAIScriptPtr[1]) + { + case 0: + if (gDisableStructs[gActiveBank].disabledMove == AI_THINKING_STRUCT->moveConsidered) + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + return; + } + gAIScriptPtr += 6; + return; + case 1: + if (gDisableStructs[gActiveBank].encoredMove == AI_THINKING_STRUCT->moveConsidered) + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + return; + } + gAIScriptPtr += 6; + return; + default: + gAIScriptPtr += 6; + return; + } +} + +static void BattleAICmd_flee(void) +{ + AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_FLEE | AI_ACTION_DO_NOT_ATTACK); // what matters is UNK2 being enabled. +} + +static void BattleAICmd_if_random_100(void) +{ + u8 safariFleeRate = gBattleStruct->field_7B * 5; // safari flee rate, from 0-20 + + if ((u8)(Random() % 100) < safariFleeRate) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +static void BattleAICmd_watch(void) +{ + AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_WATCH | AI_ACTION_DO_NOT_ATTACK); // what matters is UNK3 being enabled. +} + +static void BattleAICmd_get_hold_effect(void) +{ + u8 bank; + u16 status; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + if (gActiveBank != bank) + { + AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(BATTLE_HISTORY->itemEffects[bank]); + } + else + AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(gBattleMons[bank].item); + + gAIScriptPtr += 2; +} + +static void BattleAICmd_if_holds_item(void) +{ + u8 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]); + u16 item; + u8 var1, var2; + + if ((bank & 1) == (sBank_AI & 1)) + item = gBattleMons[bank].item; + else + item = BATTLE_HISTORY->itemEffects[bank]; + + // UB: doesn't properly read an unaligned u16 + var2 = gAIScriptPtr[2]; + var1 = gAIScriptPtr[3]; + + if ((var1 | var2) == item) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4); + else + gAIScriptPtr += 8; +} + +static void BattleAICmd_get_gender(void) +{ + u8 bank; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + AI_THINKING_STRUCT->funcResult = GetGenderFromSpeciesAndPersonality(gBattleMons[bank].species, gBattleMons[bank].personality); + + gAIScriptPtr += 2; +} + +static void BattleAICmd_is_first_turn(void) +{ + u8 bank; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + AI_THINKING_STRUCT->funcResult = gDisableStructs[bank].isFirstTurn; + + gAIScriptPtr += 2; +} + +static void BattleAICmd_get_stockpile_count(void) +{ + u8 bank; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + AI_THINKING_STRUCT->funcResult = gDisableStructs[bank].stockpileCounter; + + gAIScriptPtr += 2; +} + +static void BattleAICmd_is_double_battle(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleTypeFlags & BATTLE_TYPE_DOUBLE; + + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_used_held_item(void) +{ + u8 bank; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + // This is likely a leftover from Ruby's code and its ugly ewram access + #ifdef NONMATCHING + AI_THINKING_STRUCT->funcResult = gBattleStruct->usedHeldItems[bank]; + #else + AI_THINKING_STRUCT->funcResult = *(u8*)((u8*)(gBattleStruct) + 0xB8 + (bank * 2)); + #endif // NONMATCHING + + gAIScriptPtr += 2; +} + +static void BattleAICmd_get_move_type_from_result(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].type; + + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_move_power_from_result(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].power; + + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_move_effect_from_result(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].effect; + + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_protect_count(void) +{ + u8 bank; + + if (gAIScriptPtr[1] == AI_USER) + bank = sBank_AI; + else + bank = gBankTarget; + + AI_THINKING_STRUCT->funcResult = gDisableStructs[bank].protectUses; + + gAIScriptPtr += 2; +} + +static void BattleAICmd_nullsub_52(void) +{ +} + +static void BattleAICmd_nullsub_53(void) +{ +} + +static void BattleAICmd_nullsub_54(void) +{ +} + +static void BattleAICmd_nullsub_55(void) +{ +} + +static void BattleAICmd_nullsub_56(void) +{ +} + +static void BattleAICmd_nullsub_57(void) +{ +} + +static void BattleAICmd_call(void) +{ + AIStackPushVar(gAIScriptPtr + 5); + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); +} + +static void BattleAICmd_jump(void) +{ + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); +} + +static void BattleAICmd_end(void) +{ + if (AIStackPop() == 0) + AI_THINKING_STRUCT->aiAction |= AI_ACTION_DONE; +} + +static void BattleAICmd_if_level_cond(void) +{ + switch (gAIScriptPtr[1]) + { + case 0: // greater than + if (gBattleMons[sBank_AI].level > gBattleMons[gBankTarget].level) + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + return; + } + gAIScriptPtr += 6; + return; + case 1: // less than + if (gBattleMons[sBank_AI].level < gBattleMons[gBankTarget].level) + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + return; + } + gAIScriptPtr += 6; + return; + case 2: // equal + if (gBattleMons[sBank_AI].level == gBattleMons[gBankTarget].level) + { + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + return; + } + gAIScriptPtr += 6; + return; + } +} + +static void BattleAICmd_if_target_taunted(void) +{ + if (gDisableStructs[gBankTarget].tauntTimer1 != 0) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +static void BattleAICmd_if_target_not_taunted(void) +{ + if (gDisableStructs[gBankTarget].tauntTimer1 == 0) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +static void BattleAICmd_if_target_is_ally(void) +{ + if((sBank_AI & 1) == (gBankTarget & 1)) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +static void BattleAICmd_if_flash_fired(void) +{ + u8 index = BattleAI_GetWantedBank(gAIScriptPtr[1]); + + if(gBattleResources->flags->flags[index] & UNKNOWN_FLAG_FLASH_FIRE) + gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void AIStackPushVar(const u8 *var) +{ + gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size++] = var; +} + +static void AIStackPushVar_cursor(void) +{ + gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size++] = gAIScriptPtr; +} + +static bool8 AIStackPop(void) +{ + if (gBattleResources->AI_ScriptsStack->size != 0) + { + --gBattleResources->AI_ScriptsStack->size; + gAIScriptPtr = gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size]; + return TRUE; + } + else + return FALSE; +} diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c new file mode 100644 index 000000000..2e6b3dbae --- /dev/null +++ b/src/battle_script_commands.c @@ -0,0 +1,11415 @@ +#include "global.h" +#include "battle.h" +#include "battle_move_effects.h" +#include "battle_message.h" +#include "battle_ai_script_commands.h" +#include "moves.h" +#include "abilities.h" +#include "item.h" +#include "items.h" +#include "hold_effects.h" +#include "util.h" +#include "pokemon.h" +#include "calculate_base_damage.h" +#include "rng.h" +#include "battle_controllers.h" +#include "species.h" +#include "songs.h" +#include "text.h" +#include "sound.h" +#include "pokedex.h" +#include "recorded_battle.h" +#include "window.h" +#include "reshow_battle_screen.h" +#include "main.h" +#include "palette.h" +#include "money.h" +#include "bg.h" +#include "string_util.h" +#include "pokemon_icon.h" +#include "pokemon_item_effects.h" +#include "m4a.h" +#include "mail.h" +#include "event_data.h" +#include "pokemon_storage_system.h" +#include "task.h" +#include "naming_screen.h" + +// variables + +extern u8 gCritMultiplier; +extern s32 gBattleMoveDamage; +extern u32 gStatuses3[BATTLE_BANKS_COUNT]; +extern u32 gBattleTypeFlags; +extern struct BattleEnigmaBerry gEnigmaBerries[BATTLE_BANKS_COUNT]; +extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT]; +extern u8 gActiveBank; +extern u32 gBattleExecBuffer; +extern u8 gNoOfAllBanks; +extern u16 gBattlePartyID[BATTLE_BANKS_COUNT]; +extern u8 gTurnOrder[BATTLE_BANKS_COUNT]; +extern u8 gUnknown_0202407A[BATTLE_BANKS_COUNT]; +extern u16 gCurrentMove; +extern u8 gLastUsedAbility; +extern u16 gBattleWeather; +extern u8 gStringBank; +extern u8 gEffectBank; +extern u8 gAbsentBankFlags; +extern u8 gMultiHitCounter; +extern u16 gChosenMovesByBanks[BATTLE_BANKS_COUNT]; +extern u16 gSideAffecting[2]; +extern u16 gPauseCounterBattle; +extern u16 gPaydayMoney; +extern u16 gRandomTurnNumber; +extern u8 gBattleOutcome; +extern u8 gBattleTerrain; +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern const u8* gBattlescriptCurrInstr; +extern u8 gCurrMovePos; +extern u8 gFightStateTracker; +extern u32 gHitMarker; +extern u8 gBattleMoveFlags; +extern u8 gBattleCommunication[]; +extern u16 gUnknown_02024250[4]; +extern u16 gUnknown_02024258[4]; +extern u16 gUnknown_02024260[4]; +extern u8 gUnknown_02024270[4]; +extern u8 gStringBank; +extern u16 gDynamicBasePower; +extern u16 gLastUsedItem; +extern u16 gBattleMovePower; +extern s32 gHpDealt; +extern s32 gTakenDmg[BATTLE_BANKS_COUNT]; +extern u8 gTakenDmgBanks[BATTLE_BANKS_COUNT]; +extern u8 gSentPokesToOpponent[2]; +extern u8 gBank1; +extern u16 gExpShareExp; +extern u8 gLeveledUpInBattle; +extern void (*gBattleMainFunc)(void); +extern u8 gPlayerPartyCount; +extern u16 gMoveToLearn; +extern u16 gRandomMove; +extern u8 gBankInMenu; +extern u8 gActionForBanks[BATTLE_BANKS_COUNT]; +extern u8 gCurrentMoveTurn; +extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200]; +extern u16 gLockedMoves[BATTLE_BANKS_COUNT]; +extern u16 gPartnerTrainerId; +extern u16 gLastUsedMove; +extern u16 gUnknownMovesUsedByBanks[BATTLE_BANKS_COUNT]; +extern u16 gLastUsedMovesByBanks[BATTLE_BANKS_COUNT]; +extern u16 gTrainerBattleOpponent_A; +extern u16 gTrainerBattleOpponent_B; +extern u8 gUnknown_020241E9; +extern u16 gBattle_BG1_X; +extern u16 gBattle_BG1_Y; +extern u16 gBattle_BG2_X; +extern u16 gBattle_BG2_Y; +extern u16 gBattle_BG3_X; +extern struct MusicPlayerInfo gMPlay_BGM; + +struct TrainerMoney +{ + u8 classId; + u8 value; +}; + +extern const struct BattleMove gBattleMoves[]; +extern const struct BaseStats gBaseStats[]; +extern const u8 gTypeEffectiveness[]; +extern const u16 gMissStringIds[]; +extern const u16 gTrappingMoves[]; +extern const struct TrainerMoney gTrainerMoneyTable[]; +extern const u8* const gBattleScriptsForMoveEffects[]; + +// functions +extern void sub_81A5718(u8 bank); // battle frontier 2 +extern void sub_81A56B4(void); // battle frontier 2 +extern void sub_81BFA38(struct Pokemon* party, u8 monPartyId, u8 monCount, void (*callback)(void), u16 move); // pokemon summary screen +extern u8 sub_81C1B94(void); // pokemon summary screen +extern void IncrementGameStat(u8 statId); // rom_4 +extern void sub_81D388C(struct Pokemon* mon, void* statStoreLocation); // pokenav.s +extern void sub_81D3640(u8 arg0, void* statStoreLocation1, void* statStoreLocation2, u8 arg3, u8 arg4, u8 arg5); // pokenav.s +extern void sub_81D3784(u8 arg0, void* statStoreLocation1, u8 arg2, u8 arg3, u8 arg4); // pokenav.s +extern u8* GetMonNickname(struct Pokemon* mon, u8* dst); // party_menu +extern u8 sub_81A5258(u8* arg0); // battle frontier 2 +extern void sub_81A5BF8(void); // battle frontier 2 +extern void sub_81A5D44(void); // battle frontier 2 +extern void sub_81B8E80(u8 bank, u8, u8); // party menu +extern bool8 sub_81B1250(void); // ? +extern u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale); // battle interface +extern bool8 InBattlePike(void); +extern bool8 InBattlePyramid(void); +extern u16 GetBattlePyramidPickupItemId(void); +extern u8 sav1_map_get_light_level(void); +extern u8 sub_813B21C(void); +extern u16 get_unknown_box_id(void); +extern void c2_berry_program_update_menu(void); +extern void sub_8035AA4(void); + +// BattleScripts +extern const u8 BattleScript_MoveEnd[]; +extern const u8 BattleScript_NoPPForMove[]; +extern const u8 BattleScript_MagicCoatBounce[]; +extern const u8 BattleScript_TookAttack[]; +extern const u8 BattleScript_SnatchedMove[]; +extern const u8 BattleScript_Pausex20[]; +extern const u8 BattleScript_SubstituteFade[]; +extern const u8 BattleScript_HangedOnMsg[]; +extern const u8 BattleScript_OneHitKOMsg[]; +extern const u8 BattleScript_EnduredMsg[]; +extern const u8 BattleScript_PSNPrevention[]; +extern const u8 BattleScript_BRNPrevention[]; +extern const u8 BattleScript_PRLZPrevention[]; +extern const u8 BattleScript_FlinchPrevention[]; +extern const u8 BattleScript_StatUp[]; +extern const u8 BattleScript_StatDown[]; +extern const u8 BattleScript_NoItemSteal[]; +extern const u8 BattleScript_ItemSteal[]; +extern const u8 BattleScript_RapidSpinAway[]; +extern const u8 BattleScript_TargetPRLZHeal[]; +extern const u8 BattleScript_KnockedOff[]; +extern const u8 BattleScript_StickyHoldActivates[]; +extern const u8 BattleScript_AllStatsUp[]; +extern const u8 BattleScript_AtkDefDown[]; +extern const u8 BattleScript_SAtkDown2[]; +extern const u8 BattleScript_LevelUp[]; +extern const u8 BattleScript_WrapFree[]; +extern const u8 BattleScript_LeechSeedFree[]; +extern const u8 BattleScript_SpikesFree[]; +extern const u8 BattleScript_ButItFailed[]; +extern const u8 BattleScript_ObliviousPreventsAttraction[]; +extern const u8 BattleScript_MistProtected[]; +extern const u8 BattleScript_AbilityNoStatLoss[]; +extern const u8 BattleScript_AbilityNoSpecificStatLoss[]; +extern const u8 BattleScript_TrainerBallBlock[]; +extern const u8 BattleScript_WallyBallThrow[]; +extern const u8 BattleScript_SuccessBallThrow[]; +extern const u8 BattleScript_ShakeBallThrow[]; +extern const u8 BattleScript_FaintAttacker[]; +extern const u8 BattleScript_FaintTarget[]; +extern const u8 BattleScript_DestinyBondTakesLife[]; +extern const u8 BattleScript_GrudgeTakesPp[]; +extern const u8 BattleScript_RageIsBuilding[]; +extern const u8 BattleScript_DefrostedViaFireMove[]; +extern const u8 gUnknown_082DB87D[]; +extern const u8 gUnknown_082DAE90[]; +extern const u8 gUnknown_082DAE59[]; +extern const u8 gUnknown_082DAEC7[]; +extern const u8 BattleScript_MoveEffectSleep[]; +extern const u8 BattleScript_MoveEffectPoison[]; +extern const u8 BattleScript_MoveEffectBurn[]; +extern const u8 BattleScript_MoveEffectFreeze[]; +extern const u8 BattleScript_MoveEffectParalysis[]; +extern const u8 BattleScript_MoveEffectToxic[]; +extern const u8 BattleScript_MoveEffectConfusion[]; +extern const u8 BattleScript_MoveEffectUproar[]; +extern const u8 BattleScript_MoveEffectPayDay[]; +extern const u8 BattleScript_MoveEffectWrap[]; +extern const u8 BattleScript_MoveEffectRecoil33[]; +extern const u8 BattleScript_DampStopsExplosion[]; +extern const u8 BattleScript_MistProtected[]; +extern const u8 BattleScript_AbilityNoStatLoss[]; +extern const u8 BattleScript_AbilityNoSpecificStatLoss[]; +extern const u8 BattleScript_ButItFailed[]; +extern const u8 gUnknown_082DADD8[]; +extern const u8 BattleScript_PrintPayDayMoneyString[]; +extern const u8 BattleScript_SturdyPreventsOHKO[]; +extern const u8 BattleScript_ObliviousPreventsAttraction[]; +extern const u8 BattleScript_PauseEffectivenessSoundResultMsgEndMove[]; +extern const u8 BattleScript_CastformChange[]; +extern const u8 BattleScript_TrainerBallBlock[]; +extern const u8 BattleScript_WallyBallThrow[]; +extern const u8 BattleScript_SuccessBallThrow[]; +extern const u8 BattleScript_ShakeBallThrow[]; +extern const u8 BattleScript_PresentDamageTarget[]; +extern const u8 BattleScript_AlreadyAtFullHp[]; +extern const u8 BattleScript_PresentHealTarget[]; +extern const u8 BattleScript_WrapFree[]; +extern const u8 BattleScript_LeechSeedFree[]; +extern const u8 BattleScript_SpikesFree[]; + +// strings +extern const u8 gText_BattleYesNoChoice[]; + +// read via orr +#define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) +#define BSScriptRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8)) +#define BSScriptReadPtr(ptr) ((void *)BSScriptRead32(ptr)) + +// read via add +#define BS2ScriptRead32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24)) +#define BS2ScriptRead16(ptr) ((ptr)[0] + ((ptr)[1] << 8)) +#define BS2ScriptReadPtr(ptr) ((void *)BS2ScriptRead32(ptr)) + +#define TARGET_PROTECT_AFFECTED ((gProtectStructs[gBankTarget].protected && gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED)) + +#define TARGET_TURN_DAMAGED (((gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special))) + +// this file's functions +static bool8 IsTwoTurnsMove(u16 move); +static void DestinyBondFlagUpdate(void); +static u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. +static void CheckWonderGuardAndLevitate(void); +static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8, const u8* BS_ptr); +static bool32 IsMonGettingExpSentOut(void); +static void sub_804F17C(void); +static bool8 sub_804F1CC(void); +static void sub_804F100(void); +static void sub_804F144(void); +static bool8 sub_804F344(void); +static void PutMonIconOnLvlUpBox(void); +static void PutLevelAndGenderOnLvlUpBox(void); + +static void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite); + +static void atk00_attackcanceler(void); +static void atk01_accuracycheck(void); +static void atk02_attackstring(void); +static void atk03_ppreduce(void); +static void atk04_critcalc(void); +static void atk05_damagecalc1(void); +static void atk06_typecalc(void); +static void atk07_dmg_adjustment(void); +static void atk08_dmg_adjustment2(void); +static void atk09_attackanimation(void); +static void atk0A_waitanimation(void); +static void atk0B_healthbarupdate(void); +static void atk0C_datahpupdate(void); +static void atk0D_critmessage(void); +static void atk0E_effectiveness_sound(void); +static void atk0F_resultmessage(void); +static void atk10_printstring(void); +static void atk11_printstring_playeronly(void); +static void atk12_waitmessage(void); +static void atk13_printfromtable(void); +static void atk14_printfromtable_playeronly(void); +static void atk15_seteffectwithchance(void); +static void atk16_seteffectprimary(void); +static void atk17_seteffectsecondary(void); +static void atk18_status_effect_clear(void); +static void atk19_faint_pokemon(void); +static void atk1A_faint_animation(void); +static void atk1B_faint_effects_clear(void); +static void atk1C_jumpifstatus(void); +static void atk1D_jumpifstatus2(void); +static void atk1E_jumpifability(void); +static void atk1F_jumpifsideaffecting(void); +static void atk20_jumpifstat(void); +static void atk21_jumpifstatus3(void); +static void atk22_jumpiftype(void); +static void atk23_getexp(void); +static void atk24(void); +static void atk25_move_values_cleanup(void); +static void atk26_set_multihit(void); +static void atk27_decrement_multihit(void); +static void atk28_goto(void); +static void atk29_jumpifbyte(void); +static void atk2A_jumpifhalfword(void); +static void atk2B_jumpifword(void); +static void atk2C_jumpifarrayequal(void); +static void atk2D_jumpifarraynotequal(void); +static void atk2E_setbyte(void); +static void atk2F_addbyte(void); +static void atk30_subbyte(void); +static void atk31_copyarray(void); +static void atk32_copyarray_withindex(void); +static void atk33_orbyte(void); +static void atk34_orhalfword(void); +static void atk35_orword(void); +static void atk36_bicbyte(void); +static void atk37_bichalfword(void); +static void atk38_bicword(void); +static void atk39_pause(void); +static void atk3A_waitstate(void); +static void atk3B_healthbar_update(void); +static void atk3C_return(void); +static void atk3D_end(void); +static void atk3E_end2(void); +static void atk3F_end3(void); +static void atk40_jump_if_move_affected_by_protect(void); +static void atk41_call(void); +static void atk42_jumpiftype2(void); +static void atk43_jumpifabilitypresent(void); +static void atk44(void); +static void atk45_playanimation(void); +static void atk46_playanimation2(void); +static void atk47_setgraphicalstatchangevalues(void); +static void atk48_playstatchangeanimation(void); +static void atk49_moveend(void); +static void atk4A_typecalc2(void); +static void atk4B_return_atk_to_ball(void); +static void atk4C_copy_poke_data(void); +static void atk4D_switch_data_update(void); +static void atk4E_switchin_anim(void); +static void atk4F_jump_if_cannot_switch(void); +static void atk50_openpartyscreen(void); +static void atk51_switch_handle_order(void); +static void atk52_switch_in_effects(void); +static void atk53_trainer_slide(void); +static void atk54_effectiveness_sound(void); +static void atk55_play_sound(void); +static void atk56_fainting_cry(void); +static void atk57(void); +static void atk58_return_to_ball(void); +static void atk59_learnmove_inbattle(void); +static void atk5A_yesnoboxlearnmove(void); +static void atk5B_yesnoboxstoplearningmove(void); +static void atk5C_hitanimation(void); +static void atk5D_getmoneyreward(void); +static void atk5E_8025A70(void); +static void atk5F_8025B24(void); +static void atk60_increment_gamestat(void); +static void atk61_8025BA4(void); +static void atk62_08025C6C(void); +static void atk63_jumptorandomattack(void); +static void atk64_statusanimation(void); +static void atk65_status2animation(void); +static void atk66_chosenstatusanimation(void); +static void atk67_yesnobox(void); +static void atk68_80246A0(void); +static void atk69_dmg_adjustment3(void); +static void atk6A_removeitem(void); +static void atk6B_atknameinbuff1(void); +static void atk6C_draw_lvlupbox(void); +static void atk6D_reset_sentpokes_value(void); +static void atk6E_set_atk_to_player0(void); +static void atk6F_set_visible(void); +static void atk70_record_last_used_ability(void); +static void atk71_buffer_move_to_learn(void); +static void atk72_jump_if_can_run_frombattle(void); +static void atk73_hp_thresholds(void); +static void atk74_hp_thresholds2(void); +static void atk75_item_effect_on_opponent(void); +static void atk76_various(void); +static void atk77_set_protect_like(void); +static void atk78_faintifabilitynotdamp(void); +static void atk79_setatkhptozero(void); +static void atk7A_jumpwhiletargetvalid(void); +static void atk7B_healhalfHP_if_possible(void); +static void atk7C_trymirrormove(void); +static void atk7D_set_rain(void); +static void atk7E_setreflect(void); +static void atk7F_setseeded(void); +static void atk80_manipulatedamage(void); +static void atk81_setrest(void); +static void atk82_jumpifnotfirstturn(void); +static void atk83_nop(void); +static void atk84_jump_if_cant_sleep(void); +static void atk85_stockpile(void); +static void atk86_stockpiletobasedamage(void); +static void atk87_stockpiletohpheal(void); +static void atk88_negativedamage(void); +static void atk89_statbuffchange(void); +static void atk8A_normalisebuffs(void); +static void atk8B_setbide(void); +static void atk8C_confuseifrepeatingattackends(void); +static void atk8D_setmultihit_counter(void); +static void atk8E_init_multihit_string(void); +static void atk8F_forcerandomswitch(void); +static void atk90_conversion_type_change(void); +static void atk91_givepaydaymoney(void); +static void atk92_setlightscreen(void); +static void atk93_ko_move(void); +static void atk94_damagetohalftargethp(void); +static void atk95_setsandstorm(void); +static void atk96_weatherdamage(void); +static void atk97_try_infatuation(void); +static void atk98_status_icon_update(void); +static void atk99_setmist(void); +static void atk9A_set_focusenergy(void); +static void atk9B_transformdataexecution(void); +static void atk9C_set_substitute(void); +static void atk9D_mimicattackcopy(void); +static void atk9E_metronome(void); +static void atk9F_dmgtolevel(void); +static void atkA0_psywavedamageeffect(void); +static void atkA1_counterdamagecalculator(void); +static void atkA2_mirrorcoatdamagecalculator(void); +static void atkA3_disablelastusedattack(void); +static void atkA4_setencore(void); +static void atkA5_painsplitdmgcalc(void); +static void atkA6_settypetorandomresistance(void); +static void atkA7_setalwayshitflag(void); +static void atkA8_copymovepermanently(void); +static void atkA9_sleeptalk_choose_move(void); +static void atkAA_set_destinybond(void); +static void atkAB_DestinyBondFlagUpdate(void); +static void atkAC_remaininghptopower(void); +static void atkAD_spite_ppreduce(void); +static void atkAE_heal_party_status(void); +static void atkAF_cursetarget(void); +static void atkB0_set_spikes(void); +static void atkB1_set_foresight(void); +static void atkB2_setperishsong(void); +static void atkB3_rolloutdamagecalculation(void); +static void atkB4_jumpifconfusedandstatmaxed(void); +static void atkB5_furycuttercalc(void); +static void atkB6_happinesstodamagecalculation(void); +static void atkB7_presentdamagecalculation(void); +static void atkB8_set_safeguard(void); +static void atkB9_magnitudedamagecalculation(void); +static void atkBA_jumpifnopursuitswitchdmg(void); +static void atkBB_setsunny(void); +static void atkBC_maxattackhalvehp(void); +static void atkBD_copyfoestats(void); +static void atkBE_rapidspinfree(void); +static void atkBF_set_defense_curl(void); +static void atkC0_recoverbasedonsunlight(void); +static void atkC1_hidden_power(void); +static void atkC2_selectnexttarget(void); +static void atkC3_setfutureattack(void); +static void atkC4_beat_up(void); +static void atkC5_setsemiinvulnerablebit(void); +static void atkC6_clearsemiinvulnerablebit(void); +static void atkC7_setminimize(void); +static void atkC8_sethail(void); +static void atkC9_jumpifattackandspecialattackcannotfall(void); +static void atkCA_setforcedtarget(void); +static void atkCB_setcharge(void); +static void atkCC_callterrainattack(void); +static void atkCD_cureifburnedparalysedorpoisoned(void); +static void atkCE_settorment(void); +static void atkCF_jumpifnodamage(void); +static void atkD0_settaunt(void); +static void atkD1_set_helpinghand(void); +static void atkD2_swap_items(void); +static void atkD3_copy_ability(void); +static void atkD4_wish_effect(void); +static void atkD5_setroots(void); +static void atkD6_doubledamagedealtifdamaged(void); +static void atkD7_setyawn(void); +static void atkD8_setdamagetohealthdifference(void); +static void atkD9_scaledamagebyhealthratio(void); +static void atkDA_abilityswap(void); +static void atkDB_imprisoneffect(void); +static void atkDC_setgrudge(void); +static void atkDD_weightdamagecalculation(void); +static void atkDE_asistattackselect(void); +static void atkDF_setmagiccoat(void); +static void atkE0_setstealstatchange(void); +static void atkE1_intimidate_string_loader(void); +static void atkE2_switchout_abilities(void); +static void atkE3_jumpifhasnohp(void); +static void atkE4_getsecretpowereffect(void); +static void atkE5_pickup(void); +static void atkE6_castform_change_animation(void); +static void atkE7_castform_data_change(void); +static void atkE8_settypebasedhalvers(void); +static void atkE9_setweatherballtype(void); +static void atkEA_recycleitem(void); +static void atkEB_settypetoterrain(void); +static void atkEC_pursuit_sth(void); +static void atkED_802B4B4(void); +static void atkEE_removelightscreenreflect(void); +static void atkEF_pokeball_catch_calculation(void); +static void atkF0_give_caught_mon(void); +static void atkF1_set_caught_mon_dex_flags(void); +static void atkF2_display_dex_info(void); +static void atkF3_nickname_caught_poke(void); +static void atkF4_subattackerhpbydmg(void); +static void atkF5_removeattackerstatus1(void); +static void atkF6_802BF48(void); +static void atkF7_802BF54(void); +static void atkF8_trainer_slide_back(void); + +void (* const gBattleScriptingCommandsTable[])(void) = +{ + atk00_attackcanceler, + atk01_accuracycheck, + atk02_attackstring, + atk03_ppreduce, + atk04_critcalc, + atk05_damagecalc1, + atk06_typecalc, + atk07_dmg_adjustment, + atk08_dmg_adjustment2, + atk09_attackanimation, + atk0A_waitanimation, + atk0B_healthbarupdate, + atk0C_datahpupdate, + atk0D_critmessage, + atk0E_effectiveness_sound, + atk0F_resultmessage, + atk10_printstring, + atk11_printstring_playeronly, + atk12_waitmessage, + atk13_printfromtable, + atk14_printfromtable_playeronly, + atk15_seteffectwithchance, + atk16_seteffectprimary, + atk17_seteffectsecondary, + atk18_status_effect_clear, + atk19_faint_pokemon, + atk1A_faint_animation, + atk1B_faint_effects_clear, + atk1C_jumpifstatus, + atk1D_jumpifstatus2, + atk1E_jumpifability, + atk1F_jumpifsideaffecting, + atk20_jumpifstat, + atk21_jumpifstatus3, + atk22_jumpiftype, + atk23_getexp, + atk24, + atk25_move_values_cleanup, + atk26_set_multihit, + atk27_decrement_multihit, + atk28_goto, + atk29_jumpifbyte, + atk2A_jumpifhalfword, + atk2B_jumpifword, + atk2C_jumpifarrayequal, + atk2D_jumpifarraynotequal, + atk2E_setbyte, + atk2F_addbyte, + atk30_subbyte, + atk31_copyarray, + atk32_copyarray_withindex, + atk33_orbyte, + atk34_orhalfword, + atk35_orword, + atk36_bicbyte, + atk37_bichalfword, + atk38_bicword, + atk39_pause, + atk3A_waitstate, + atk3B_healthbar_update, + atk3C_return, + atk3D_end, + atk3E_end2, + atk3F_end3, + atk40_jump_if_move_affected_by_protect, + atk41_call, + atk42_jumpiftype2, + atk43_jumpifabilitypresent, + atk44, + atk45_playanimation, + atk46_playanimation2, + atk47_setgraphicalstatchangevalues, + atk48_playstatchangeanimation, + atk49_moveend, + atk4A_typecalc2, + atk4B_return_atk_to_ball, + atk4C_copy_poke_data, + atk4D_switch_data_update, + atk4E_switchin_anim, + atk4F_jump_if_cannot_switch, + atk50_openpartyscreen, + atk51_switch_handle_order, + atk52_switch_in_effects, + atk53_trainer_slide, + atk54_effectiveness_sound, + atk55_play_sound, + atk56_fainting_cry, + atk57, + atk58_return_to_ball, + atk59_learnmove_inbattle, + atk5A_yesnoboxlearnmove, + atk5B_yesnoboxstoplearningmove, + atk5C_hitanimation, + atk5D_getmoneyreward, + atk5E_8025A70, + atk5F_8025B24, + atk60_increment_gamestat, + atk61_8025BA4, + atk62_08025C6C, + atk63_jumptorandomattack, + atk64_statusanimation, + atk65_status2animation, + atk66_chosenstatusanimation, + atk67_yesnobox, + atk68_80246A0, + atk69_dmg_adjustment3, + atk6A_removeitem, + atk6B_atknameinbuff1, + atk6C_draw_lvlupbox, + atk6D_reset_sentpokes_value, + atk6E_set_atk_to_player0, + atk6F_set_visible, + atk70_record_last_used_ability, + atk71_buffer_move_to_learn, + atk72_jump_if_can_run_frombattle, + atk73_hp_thresholds, + atk74_hp_thresholds2, + atk75_item_effect_on_opponent, + atk76_various, + atk77_set_protect_like, + atk78_faintifabilitynotdamp, + atk79_setatkhptozero, + atk7A_jumpwhiletargetvalid, + atk7B_healhalfHP_if_possible, + atk7C_trymirrormove, + atk7D_set_rain, + atk7E_setreflect, + atk7F_setseeded, + atk80_manipulatedamage, + atk81_setrest, + atk82_jumpifnotfirstturn, + atk83_nop, + atk84_jump_if_cant_sleep, + atk85_stockpile, + atk86_stockpiletobasedamage, + atk87_stockpiletohpheal, + atk88_negativedamage, + atk89_statbuffchange, + atk8A_normalisebuffs, + atk8B_setbide, + atk8C_confuseifrepeatingattackends, + atk8D_setmultihit_counter, + atk8E_init_multihit_string, + atk8F_forcerandomswitch, + atk90_conversion_type_change, + atk91_givepaydaymoney, + atk92_setlightscreen, + atk93_ko_move, + atk94_damagetohalftargethp, + atk95_setsandstorm, + atk96_weatherdamage, + atk97_try_infatuation, + atk98_status_icon_update, + atk99_setmist, + atk9A_set_focusenergy, + atk9B_transformdataexecution, + atk9C_set_substitute, + atk9D_mimicattackcopy, + atk9E_metronome, + atk9F_dmgtolevel, + atkA0_psywavedamageeffect, + atkA1_counterdamagecalculator, + atkA2_mirrorcoatdamagecalculator, + atkA3_disablelastusedattack, + atkA4_setencore, + atkA5_painsplitdmgcalc, + atkA6_settypetorandomresistance, + atkA7_setalwayshitflag, + atkA8_copymovepermanently, + atkA9_sleeptalk_choose_move, + atkAA_set_destinybond, + atkAB_DestinyBondFlagUpdate, + atkAC_remaininghptopower, + atkAD_spite_ppreduce, + atkAE_heal_party_status, + atkAF_cursetarget, + atkB0_set_spikes, + atkB1_set_foresight, + atkB2_setperishsong, + atkB3_rolloutdamagecalculation, + atkB4_jumpifconfusedandstatmaxed, + atkB5_furycuttercalc, + atkB6_happinesstodamagecalculation, + atkB7_presentdamagecalculation, + atkB8_set_safeguard, + atkB9_magnitudedamagecalculation, + atkBA_jumpifnopursuitswitchdmg, + atkBB_setsunny, + atkBC_maxattackhalvehp, + atkBD_copyfoestats, + atkBE_rapidspinfree, + atkBF_set_defense_curl, + atkC0_recoverbasedonsunlight, + atkC1_hidden_power, + atkC2_selectnexttarget, + atkC3_setfutureattack, + atkC4_beat_up, + atkC5_setsemiinvulnerablebit, + atkC6_clearsemiinvulnerablebit, + atkC7_setminimize, + atkC8_sethail, + atkC9_jumpifattackandspecialattackcannotfall, + atkCA_setforcedtarget, + atkCB_setcharge, + atkCC_callterrainattack, + atkCD_cureifburnedparalysedorpoisoned, + atkCE_settorment, + atkCF_jumpifnodamage, + atkD0_settaunt, + atkD1_set_helpinghand, + atkD2_swap_items, + atkD3_copy_ability, + atkD4_wish_effect, + atkD5_setroots, + atkD6_doubledamagedealtifdamaged, + atkD7_setyawn, + atkD8_setdamagetohealthdifference, + atkD9_scaledamagebyhealthratio, + atkDA_abilityswap, + atkDB_imprisoneffect, + atkDC_setgrudge, + atkDD_weightdamagecalculation, + atkDE_asistattackselect, + atkDF_setmagiccoat, + atkE0_setstealstatchange, + atkE1_intimidate_string_loader, + atkE2_switchout_abilities, + atkE3_jumpifhasnohp, + atkE4_getsecretpowereffect, + atkE5_pickup, + atkE6_castform_change_animation, + atkE7_castform_data_change, + atkE8_settypebasedhalvers, + atkE9_setweatherballtype, + atkEA_recycleitem, + atkEB_settypetoterrain, + atkEC_pursuit_sth, + atkED_802B4B4, + atkEE_removelightscreenreflect, + atkEF_pokeball_catch_calculation, + atkF0_give_caught_mon, + atkF1_set_caught_mon_dex_flags, + atkF2_display_dex_info, + atkF3_nickname_caught_poke, + atkF4_subattackerhpbydmg, + atkF5_removeattackerstatus1, + atkF6_802BF48, + atkF7_802BF54, + atkF8_trainer_slide_back +}; + +struct StatFractions +{ + u8 dividend; + u8 divisor; +}; + +static const struct StatFractions sAccuracyStageRatios[] = +{ + { 33, 100}, // -6 + { 36, 100}, // -5 + { 43, 100}, // -4 + { 50, 100}, // -3 + { 60, 100}, // -2 + { 75, 100}, // -1 + { 1, 1}, // 0 + {133, 100}, // +1 + {166, 100}, // +2 + { 2, 1}, // +3 + {233, 100}, // +4 + {133, 50}, // +5 + { 3, 1}, // +6 +}; + +// The chance is 1/N for each stage. +static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2}; + +static const u32 sStatusFlagsForMoveEffects[] = +{ + 0x00000000, + STATUS_SLEEP, + STATUS_POISON, + STATUS_BURN, + STATUS_FREEZE, + STATUS_PARALYSIS, + STATUS_TOXIC_POISON, + STATUS2_CONFUSION, + STATUS2_FLINCHED, + 0x00000000, + STATUS2_UPROAR, + 0x00000000, + STATUS2_MULTIPLETURNS, + STATUS2_WRAPPED, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + STATUS2_RECHARGE, + 0x00000000, + 0x00000000, + STATUS2_ESCAPE_PREVENTION, + 0x08000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + STATUS2_LOCK_CONFUSE, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; + +static const u8* const sMoveEffectBS_Ptrs[] = +{ + BattleScript_MoveEffectSleep, // 0 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SLEEP + BattleScript_MoveEffectPoison, // MOVE_EFFECT_POISON + BattleScript_MoveEffectBurn, // MOVE_EFFECT_BURN + BattleScript_MoveEffectFreeze, // MOVE_EFFECT_FREEZE + BattleScript_MoveEffectParalysis, // MOVE_EFFECT_PARALYSIS + BattleScript_MoveEffectToxic, // MOVE_EFFECT_TOXIC + BattleScript_MoveEffectConfusion, // MOVE_EFFECT_CONFUSION + BattleScript_MoveEffectSleep, // MOVE_EFFECT_FLINCH + BattleScript_MoveEffectSleep, // MOVE_EFFECT_TRI_ATTACK + BattleScript_MoveEffectUproar, // MOVE_EFFECT_UPROAR + BattleScript_MoveEffectPayDay, // MOVE_EFFECT_PAYDAY + BattleScript_MoveEffectSleep, // MOVE_EFFECT_CHARGING + BattleScript_MoveEffectWrap, // MOVE_EFFECT_WRAP + BattleScript_MoveEffectRecoil33, // MOVE_EFFECT_RECOIL_25 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_DEF_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SPD_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_ATK_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_DEF_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ACC_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_EVS_PLUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_DEF_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SPD_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_ATK_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_DEF_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ACC_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_EVS_MINUS_1 + BattleScript_MoveEffectSleep, // MOVE_EFFECT_RECHARGE + BattleScript_MoveEffectSleep, // MOVE_EFFECT_RAGE + BattleScript_MoveEffectSleep, // MOVE_EFFECT_STEAL_ITEM + BattleScript_MoveEffectSleep, // MOVE_EFFECT_PREVENT_ESCAPE + BattleScript_MoveEffectSleep, // MOVE_EFFECT_NIGHTMARE + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ALL_STATS_UP + BattleScript_MoveEffectSleep, // MOVE_EFFECT_RAPIDSPIN + BattleScript_MoveEffectSleep, // MOVE_EFFECT_REMOVE_PARALYSIS + BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_DEF_DOWN + BattleScript_MoveEffectRecoil33, // MOVE_EFFECT_RECOIL_33_PARALYSIS +}; + +static const struct WindowTemplate sUnusedWinTemplate = {0, 1, 3, 7, 0xF, 0x1F, 0x3F}; + +static const u16 sUnknown_0831C2C8[] = INCBIN_U16("graphics/battle_interface/unk_battlebox.gbapal"); +static const u8 sUnknown_0831C2E8[] = INCBIN_U8("graphics/battle_interface/unk_battlebox.4bpp.lz"); + +// unused +static const u8 sRubyLevelUpStatBoxStats[] = +{ + MON_DATA_MAX_HP, MON_DATA_SPATK, MON_DATA_ATK, + MON_DATA_SPDEF, MON_DATA_DEF, MON_DATA_SPD +}; + +#define MON_ICON_LVLUP_BOX_TAG 0xD75A + +static const struct OamData sOamData_MonIconOnLvlUpBox = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 2, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const struct SpriteTemplate sSpriteTemplate_MonIconOnLvlUpBox = +{ + .tileTag = MON_ICON_LVLUP_BOX_TAG, + .paletteTag = MON_ICON_LVLUP_BOX_TAG, + .oam = &sOamData_MonIconOnLvlUpBox, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_MonIconOnLvlUpBox +}; + +static const u16 sProtectSuccessRates[] = {USHRT_MAX, USHRT_MAX / 2, USHRT_MAX / 4, USHRT_MAX / 8}; + +#define MIMIC_FORBIDDEN_END 0xFFFE +#define METRONOME_FORBIDDEN_END 0xFFFF +#define ASSIST_FORBIDDEN_END 0xFFFF + +static const u16 sMovesForbiddenToCopy[] = +{ + MOVE_METRONOME, + MOVE_STRUGGLE, + MOVE_SKETCH, + MOVE_MIMIC, + MIMIC_FORBIDDEN_END, + MOVE_COUNTER, + MOVE_MIRROR_COAT, + MOVE_PROTECT, + MOVE_DETECT, + MOVE_ENDURE, + MOVE_DESTINY_BOND, + MOVE_SLEEP_TALK, + MOVE_THIEF, + MOVE_FOLLOW_ME, + MOVE_SNATCH, + MOVE_HELPING_HAND, + MOVE_COVET, + MOVE_TRICK, + MOVE_FOCUS_PUNCH, + METRONOME_FORBIDDEN_END +}; + +static const u8 sFlailHpScaleToPowerTable[] = +{ + 1, 200, + 4, 150, + 9, 100, + 16, 80, + 32, 40, + 48, 20 +}; + +static const u16 sNaturePowerMoves[] = +{ + MOVE_STUN_SPORE, + MOVE_RAZOR_LEAF, + MOVE_EARTHQUAKE, + MOVE_HYDRO_PUMP, + MOVE_SURF, + MOVE_BUBBLE_BEAM, + MOVE_ROCK_SLIDE, + MOVE_SHADOW_BALL, + MOVE_SWIFT, + MOVE_SWIFT +}; + +// format: min. weight (hectograms), base power +static const u16 sWeightToDamageTable[] = +{ + 100, 20, + 250, 40, + 500, 60, + 1000, 80, + 2000, 100, + 0xFFFF, 0xFFFF +}; + +static const u16 sPickupItems[] = +{ + ITEM_POTION, + ITEM_ANTIDOTE, + ITEM_SUPER_POTION, + ITEM_GREAT_BALL, + ITEM_REPEL, + ITEM_ESCAPE_ROPE, + ITEM_X_ATTACK, + ITEM_FULL_HEAL, + ITEM_ULTRA_BALL, + ITEM_HYPER_POTION, + ITEM_RARE_CANDY, + ITEM_PROTEIN, + ITEM_REVIVE, + ITEM_HP_UP, + ITEM_FULL_RESTORE, + ITEM_MAX_REVIVE, + ITEM_PP_UP, + ITEM_MAX_ELIXIR, +}; + +static const u16 sRarePickupItems[] = +{ + ITEM_HYPER_POTION, + ITEM_NUGGET, + ITEM_KINGS_ROCK, + ITEM_FULL_RESTORE, + ITEM_ETHER, + ITEM_WHITE_HERB, + ITEM_TM44, + ITEM_ELIXIR, + ITEM_TM01, + ITEM_LEFTOVERS, + ITEM_TM26, +}; + +static const u8 sPickupProbabilities[] = +{ + 30, 40, 50, 60, 70, 80, 90, 94, 98 +}; + +static const u8 sTerrainToType[] = +{ + TYPE_GRASS, // tall grass + TYPE_GRASS, // long grass + TYPE_GROUND, // sand + TYPE_WATER, // underwater + TYPE_WATER, // water + TYPE_WATER, // pond water + TYPE_ROCK, // rock + TYPE_ROCK, // cave + TYPE_NORMAL, // building + TYPE_NORMAL, // plain +}; + +static const u8 sBallCatchBonuses[] = +{ + 20, 15, 10, 15 // Ultra, Great, Poke, Safari +}; + +// could be a 2d array or a struct +const ALIGNED(4) u8 gUnknown_0831C494[] = +{ + 0x3d, 0x44, 0x3d, 0x44, 0x14, 0x2d, 0x54, 0x5c, + 0x46, 0x55, 0x20, 0x5c, 0x26, 0x45, 0x46, 0x55, + 0x14, 0x5a, 0x46, 0x5c, 0x1e, 0x32, 0x20, 0x5a, + 0x38, 0x4e, 0x38, 0x4e, 0x19, 0x28, 0x4b, 0x5a, + 0x45, 0x4b, 0x1c, 0x53, 0x23, 0x2d, 0x1d, 0x23, + 0x3e, 0x48, 0x1e, 0x32, 0x3a, 0x5f, 0x58, 0x5e, + 0x22, 0x2d, 0x1d, 0x28, 0x23, 0x28, 0x23, 0x5f, + 0x38, 0x4e, 0x38, 0x4e, 0x23, 0x50, 0x22, 0x5e, + 0x2c, 0x5e, 0x22, 0x28, 0x38, 0x4e, 0x38, 0x4e, + 0x1e, 0x58, 0x1e, 0x58, 0x1e, 0x2b, 0x1b, 0x21, + 0x28, 0x5a, 0x19, 0x57, 0x12, 0x58, 0x5a, 0x5f, + 0x58, 0x5e, 0x16, 0x2a, 0x2a, 0x5c, 0x2a, 0x2f, + 0x38, 0x4e, 0x38, 0x4e +}; + +static const u8 sUnknown_0831C4F8[] = +{ + 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x00, + 0x01, 0x02, 0x02, 0x00, 0x03, 0x01, 0x03, 0x01, + 0x02, 0x03, 0x03, 0x02, 0x01, 0x00, 0x02, 0x02, + 0x03, 0x00, 0x00, 0x00 +}; + +static void atk00_attackcanceler(void) +{ + s32 i; + + if (gBattleOutcome) + { + gFightStateTracker = 0xC; + return; + } + if (gBattleMons[gBankAttacker].hp == 0 && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) + { + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gBattlescriptCurrInstr = BattleScript_MoveEnd; + return; + } + if (AtkCanceller_UnableToUseMove()) + return; + if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBankTarget, 0, 0, 0)) + return; + if (!gBattleMons[gBankAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE && !(gHitMarker & 0x800200) + && !(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) + { + gBattlescriptCurrInstr = BattleScript_NoPPForMove; + gBattleMoveFlags |= MOVESTATUS_MISSED; + return; + } + + gHitMarker &= ~(HITMARKER_x800000); + + if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) + { + i = IsPokeDisobedient(); // why use the 'i' variable...? + switch (i) + { + case 0: + break; + case 2: + gHitMarker |= HITMARKER_OBEYS; + return; + default: + gBattleMoveFlags |= MOVESTATUS_MISSED; + return; + } + } + + gHitMarker |= HITMARKER_OBEYS; + + if (gProtectStructs[gBankTarget].bounceMove && gBattleMoves[gCurrentMove].flags & FLAG_MAGICCOAT_AFFECTED) + { + PressurePPLose(gBankAttacker, gBankTarget, MOVE_MAGIC_COAT); + gProtectStructs[gBankTarget].bounceMove = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MagicCoatBounce; + return; + } + + for (i = 0; i < gNoOfAllBanks; i++) + { + if ((gProtectStructs[gTurnOrder[i]].stealMove) && gBattleMoves[gCurrentMove].flags & FLAG_SNATCH_AFFECTED) + { + PressurePPLose(gBankAttacker, gTurnOrder[i], MOVE_SNATCH); + gProtectStructs[gTurnOrder[i]].stealMove = 0; + gBattleScripting.bank = gTurnOrder[i]; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SnatchedMove; + return; + } + } + + if (gSpecialStatuses[gBankTarget].lightningRodRedirected) + { + gSpecialStatuses[gBankTarget].lightningRodRedirected = 0; + gLastUsedAbility = ABILITY_LIGHTNING_ROD; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_TookAttack; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else if (TARGET_PROTECT_AFFECTED + && (gCurrentMove != MOVE_CURSE || (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST)) + && ((!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)))) + { + CancelMultiTurnMoves(gBankAttacker); + gBattleMoveFlags |= MOVESTATUS_MISSED; + gUnknown_02024250[gBankTarget] = 0; + gUnknown_02024258[gBankTarget] = 0; + gBattleCommunication[6] = 1; + gBattlescriptCurrInstr++; + } + else + { + gBattlescriptCurrInstr++; + } +} + +static void JumpIfMoveFailed(u8 adder, u16 move) +{ + const void* BS_ptr = gBattlescriptCurrInstr + adder; + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) + { + gUnknown_02024250[gBankTarget] = 0; + gUnknown_02024258[gBankTarget] = 0; + BS_ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + DestinyBondFlagUpdate(); + if (AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBankTarget, 0, 0, move)) + return; + } + gBattlescriptCurrInstr = BS_ptr; +} + +static void atk40_jump_if_move_affected_by_protect(void) +{ + if (TARGET_PROTECT_AFFECTED) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + JumpIfMoveFailed(5, 0); + gBattleCommunication[6] = 1; + } + else + { + gBattlescriptCurrInstr += 5; + } +} + +bool8 JumpIfMoveAffectedByProtect(u16 move) +{ + bool8 affected = FALSE; + if (TARGET_PROTECT_AFFECTED) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + JumpIfMoveFailed(7, move); + gBattleCommunication[6] = 1; + affected = TRUE; + } + return affected; +} + +bool8 AccuracyCalcHelper(u16 move) +{ + if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker) + { + JumpIfMoveFailed(7, move); + return TRUE; + } + + if (!(gHitMarker & HITMARKER_IGNORE_ON_AIR) && gStatuses3[gBankTarget] & STATUS3_ON_AIR) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + JumpIfMoveFailed(7, move); + return TRUE; + } + + gHitMarker &= ~HITMARKER_IGNORE_ON_AIR; + + if (!(gHitMarker & HITMARKER_IGNORE_UNDERGROUND) && gStatuses3[gBankTarget] & STATUS3_UNDERGROUND) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + JumpIfMoveFailed(7, move); + return TRUE; + } + + gHitMarker &= ~HITMARKER_IGNORE_UNDERGROUND; + + if (!(gHitMarker & HITMARKER_IGNORE_UNDERWATER) && gStatuses3[gBankTarget] & STATUS3_UNDERWATER) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + JumpIfMoveFailed(7, move); + return TRUE; + } + + gHitMarker &= ~HITMARKER_IGNORE_UNDERWATER; + + if ((WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY) && gBattleMoves[move].effect == EFFECT_THUNDER) + || (gBattleMoves[move].effect == EFFECT_ALWAYS_HIT || gBattleMoves[move].effect == EFFECT_VITAL_THROW)) + { + JumpIfMoveFailed(7, move); + return TRUE; + } + + return FALSE; +} + +static void atk01_accuracycheck(void) +{ + u16 move = BS2ScriptRead16(gBattlescriptCurrInstr + 5); + + if (move == 0xFFFE || move == 0xFFFF) + { + if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && move == 0xFFFF && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker) + gBattlescriptCurrInstr += 7; + else if (gStatuses3[gBankTarget] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else if (!JumpIfMoveAffectedByProtect(0)) + gBattlescriptCurrInstr += 7; + } + else + { + u8 type, moveAcc, holdEffect, quality; + s8 buff; + u16 calc; + + if (move == 0) + move = gCurrentMove; + + GET_MOVE_TYPE(move, type); + + if (JumpIfMoveAffectedByProtect(move)) + return; + if (AccuracyCalcHelper(move)) + return; + + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + { + u8 acc = gBattleMons[gBankAttacker].statStages[STAT_STAGE_ACC]; + buff = acc; + } + else + { + u8 acc = gBattleMons[gBankAttacker].statStages[STAT_STAGE_ACC]; + buff = acc + 6 - gBattleMons[gBankTarget].statStages[STAT_STAGE_EVASION]; + } + + if (buff < 0) + buff = 0; + if (buff > 0xC) + buff = 0xC; + + moveAcc = gBattleMoves[move].accuracy; + // check Thunder on sunny weather + if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY && gBattleMoves[move].effect == EFFECT_THUNDER) + moveAcc = 50; + + calc = sAccuracyStageRatios[buff].dividend * moveAcc; + calc /= sAccuracyStageRatios[buff].divisor; + + if (gBattleMons[gBankAttacker].ability == ABILITY_COMPOUND_EYES) + calc = (calc * 130) / 100; // 1.3 compound eyes boost + if (WEATHER_HAS_EFFECT && gBattleMons[gBankTarget].ability == ABILITY_SAND_VEIL && gBattleWeather & WEATHER_SANDSTORM_ANY) + calc = (calc * 80) / 100; // 1.2 sand veil loss + if (gBattleMons[gBankAttacker].ability == ABILITY_HUSTLE && type < 9) + calc = (calc * 80) / 100; // 1.2 hustle loss + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect; + quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_EVASION_UP) + calc = (calc * (100 - quality)) / 100; + + // final calculation + if ((Random() % 100 + 1) > calc) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && + (gBattleMoves[move].target == MOVE_TARGET_BOTH || gBattleMoves[move].target == MOVE_TARGET_FOES_AND_ALLY)) + gBattleCommunication[6] = 2; + else + gBattleCommunication[6] = 0; + + CheckWonderGuardAndLevitate(); + } + JumpIfMoveFailed(7, move); + } +} + +static void atk02_attackstring(void) +{ + if (gBattleExecBuffer) + return; + if (!(gHitMarker & (HITMARKER_NO_ATTACKSTRING | HITMARKER_ATTACKSTRING_PRINTED))) + { + PrepareStringBattle(4, gBankAttacker); + gHitMarker |= HITMARKER_ATTACKSTRING_PRINTED; + } + gBattlescriptCurrInstr++; + gBattleCommunication[MSG_DISPLAY] = 0; +} + +static void atk03_ppreduce(void) +{ + s32 ppToDeduct = 1; + + if (gBattleExecBuffer) + return; + + if (!gSpecialStatuses[gBankAttacker].flag20) + { + switch (gBattleMoves[gCurrentMove].target) + { + case MOVE_TARGET_FOES_AND_ALLY: + ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_ON_FIELD, gBankAttacker, ABILITY_PRESSURE, 0, 0); + break; + case MOVE_TARGET_BOTH: + case MOVE_TARGET_OPPONENTS_FIELD: + ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIDE, gBankAttacker, ABILITY_PRESSURE, 0, 0); + break; + default: + if (gBankAttacker != gBankTarget && gBattleMons[gBankTarget].ability == ABILITY_PRESSURE) + ppToDeduct++; + break; + } + } + + if (!(gHitMarker & (HITMARKER_NO_PPDEDUCT | HITMARKER_NO_ATTACKSTRING)) && gBattleMons[gBankAttacker].pp[gCurrMovePos]) + { + gProtectStructs[gBankAttacker].notFirstStrike = 1; + + if (gBattleMons[gBankAttacker].pp[gCurrMovePos] > ppToDeduct) + gBattleMons[gBankAttacker].pp[gCurrMovePos] -= ppToDeduct; + else + gBattleMons[gBankAttacker].pp[gCurrMovePos] = 0; + + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED) + && !((gDisableStructs[gBankAttacker].unk18_b) & gBitTable[gCurrMovePos])) + { + gActiveBank = gBankAttacker; + EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + gCurrMovePos, 0, 1, &gBattleMons[gBankAttacker].pp[gCurrMovePos]); + MarkBufferBankForExecution(gBankAttacker); + } + } + + gHitMarker &= ~(HITMARKER_NO_PPDEDUCT); + gBattlescriptCurrInstr++; +} + +static void atk04_critcalc(void) +{ + u8 holdEffect; + u16 item, critChance; + + item = gBattleMons[gBankAttacker].item; + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gEnigmaBerries[gBankAttacker].holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + gStringBank = gBankAttacker; + + critChance = 2 * ((gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0) + + (gBattleMoves[gCurrentMove].effect == EFFECT_HIGH_CRITICAL) + + (gBattleMoves[gCurrentMove].effect == EFFECT_SKY_ATTACK) + + (gBattleMoves[gCurrentMove].effect == EFFECT_BLAZE_KICK) + + (gBattleMoves[gCurrentMove].effect == EFFECT_POISON_TAIL) + + (holdEffect == HOLD_EFFECT_SCOPE_LENS) + + 2 * (holdEffect == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBankAttacker].species == SPECIES_CHANSEY) + + 2 * (holdEffect == HOLD_EFFECT_STICK && gBattleMons[gBankAttacker].species == SPECIES_FARFETCHD); + + if (critChance > 4) + critChance = 4; + + if ((gBattleMons[gBankTarget].ability != ABILITY_BATTLE_ARMOR && gBattleMons[gBankTarget].ability != ABILITY_SHELL_ARMOR) + && !(gStatuses3[gBankAttacker] & STATUS3_CANT_SCORE_A_CRIT) + && !(gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE)) + && !(Random() % sCriticalHitChance[critChance])) + gCritMultiplier = 2; + else + gCritMultiplier = 1; + + gBattlescriptCurrInstr++; +} + +static void atk05_damagecalc1(void) +{ + u16 sideStatus = gSideAffecting[GET_BANK_SIDE(gBankTarget)]; + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, + sideStatus, gDynamicBasePower, + gBattleStruct->dynamicMoveType, gBankAttacker, gBankTarget); + gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting.dmgMultiplier; + + if (gStatuses3[gBankAttacker] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + gBattleMoveDamage *= 2; + if (gProtectStructs[gBankAttacker].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; + + gBattlescriptCurrInstr++; +} + +void AI_CalcDmg(u8 bankAtk, u8 bankDef) +{ + u16 sideStatus = gSideAffecting[GET_BANK_SIDE(bankDef)]; + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[bankAtk], &gBattleMons[bankDef], gCurrentMove, + sideStatus, gDynamicBasePower, + gBattleStruct->dynamicMoveType, bankAtk, bankDef); + gDynamicBasePower = 0; + gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting.dmgMultiplier; + + if (gStatuses3[bankAtk] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + gBattleMoveDamage *= 2; + if (gProtectStructs[bankAtk].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; +} + +static void ModulateDmgByType(u8 multiplier) +{ + gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; + if (gBattleMoveDamage == 0 && multiplier != 0) + gBattleMoveDamage = 1; + + switch (multiplier) + { + case TYPE_MUL_NO_EFFECT: + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + gBattleMoveFlags &= ~MOVESTATUS_NOTVERYEFFECTIVE; + gBattleMoveFlags &= ~MOVESTATUS_SUPEREFFECTIVE; + break; + case TYPE_MUL_NOT_EFFECTIVE: + if (gBattleMoves[gCurrentMove].power && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + if (gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE) + gBattleMoveFlags &= ~MOVESTATUS_SUPEREFFECTIVE; + else + gBattleMoveFlags |= MOVESTATUS_NOTVERYEFFECTIVE; + } + break; + case TYPE_MUL_SUPER_EFFECTIVE: + if (gBattleMoves[gCurrentMove].power && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + if (gBattleMoveFlags & MOVESTATUS_NOTVERYEFFECTIVE) + gBattleMoveFlags &= ~MOVESTATUS_NOTVERYEFFECTIVE; + else + gBattleMoveFlags |= MOVESTATUS_SUPEREFFECTIVE; + } + break; + } +} + +#define TYPE_FORESIGHT 0xFE +#define TYPE_ENDTABLE 0xFF + +static void atk06_typecalc(void) +{ + s32 i = 0; + u8 moveType; + + if (gCurrentMove == MOVE_STRUGGLE) + { + gBattlescriptCurrInstr++; + return; + } + + GET_MOVE_TYPE(gCurrentMove, moveType); + + // check stab + if (gBattleMons[gBankAttacker].type1 == moveType || gBattleMons[gBankAttacker].type2 == moveType) + { + gBattleMoveDamage = gBattleMoveDamage * 15; + gBattleMoveDamage = gBattleMoveDamage / 10; + } + + if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) + { + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gBattleMoveFlags |= (MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED); + gUnknown_02024250[gBankTarget] = 0; + gUnknown_02024258[gBankTarget] = 0; + gBattleCommunication[6] = moveType; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else + { + while (gTypeEffectiveness[i] != TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + break; + i += 3; + continue; + } + else if (gTypeEffectiveness[i] == moveType) + { + // check type1 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1) + ModulateDmgByType(gTypeEffectiveness[i + 2]); + // check type2 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && + gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2) + ModulateDmgByType(gTypeEffectiveness[i + 2]); + } + i += 3; + } + } + + if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2 + && (!(gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE) || ((gBattleMoveFlags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) + && gBattleMoves[gCurrentMove].power) + { + gLastUsedAbility = ABILITY_WONDER_GUARD; + gBattleMoveFlags |= MOVESTATUS_MISSED; + gUnknown_02024250[gBankTarget] = 0; + gUnknown_02024258[gBankTarget] = 0; + gBattleCommunication[6] = 3; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) + gProtectStructs[gBankAttacker].notEffective = 1; + + gBattlescriptCurrInstr++; +} + +static void CheckWonderGuardAndLevitate(void) +{ + u8 flags = 0; + s32 i = 0; + u8 moveType; + + if (gCurrentMove == MOVE_STRUGGLE || !gBattleMoves[gCurrentMove].power) + return; + + GET_MOVE_TYPE(gCurrentMove, moveType); + + if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) + { + gLastUsedAbility = ABILITY_LEVITATE; + gBattleCommunication[6] = moveType; + RecordAbilityBattle(gBankTarget, ABILITY_LEVITATE); + return; + } + + while (gTypeEffectiveness[i] != TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + break; + i += 3; + continue; + } + if (gTypeEffectiveness[i] == moveType) + { + // check no effect + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 0) + { + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + gProtectStructs[gBankAttacker].notEffective = 1; + } + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && + gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 && + gTypeEffectiveness[i + 2] == TYPE_MUL_NO_EFFECT) + { + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + gProtectStructs[gBankAttacker].notEffective = 1; + } + + // check super effective + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 20) + flags |= 1; + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == TYPE_MUL_SUPER_EFFECTIVE) + flags |= 1; + + // check not very effective + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 5) + flags |= 2; + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == TYPE_MUL_NOT_EFFECTIVE) + flags |= 2; + } + i += 3; + } + + if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2) + { + if (((flags & 2) || !(flags & 1)) && gBattleMoves[gCurrentMove].power) + { + gLastUsedAbility = ABILITY_WONDER_GUARD; + gBattleCommunication[6] = 3; + RecordAbilityBattle(gBankTarget, ABILITY_WONDER_GUARD); + } + } +} + +static void ModulateDmgByType2(u8 multiplier, u16 move, u8* flags) // same as ModulateDmgByType except different arguments +{ + gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; + if (gBattleMoveDamage == 0 && multiplier != 0) + gBattleMoveDamage = 1; + + switch (multiplier) + { + case TYPE_MUL_NO_EFFECT: + *flags |= MOVESTATUS_NOTAFFECTED; + *flags &= ~MOVESTATUS_NOTVERYEFFECTIVE; + *flags &= ~MOVESTATUS_SUPEREFFECTIVE; + break; + case TYPE_MUL_NOT_EFFECTIVE: + if (gBattleMoves[move].power && !(*flags & MOVESTATUS_NOEFFECT)) + { + if (*flags & MOVESTATUS_SUPEREFFECTIVE) + *flags &= ~MOVESTATUS_SUPEREFFECTIVE; + else + *flags |= MOVESTATUS_NOTVERYEFFECTIVE; + } + break; + case TYPE_MUL_SUPER_EFFECTIVE: + if (gBattleMoves[move].power && !(*flags & MOVESTATUS_NOEFFECT)) + { + if (*flags & MOVESTATUS_NOTVERYEFFECTIVE) + *flags &= ~MOVESTATUS_NOTVERYEFFECTIVE; + else + *flags |= MOVESTATUS_SUPEREFFECTIVE; + } + break; + } +} + +u8 TypeCalc(u16 move, u8 bankAtk, u8 bankDef) +{ + s32 i = 0; + u8 flags = 0; + u8 moveType; + + if (move == MOVE_STRUGGLE) + return 0; + + moveType = gBattleMoves[move].type; + + // check stab + if (gBattleMons[bankAtk].type1 == moveType || gBattleMons[bankAtk].type2 == moveType) + { + gBattleMoveDamage = gBattleMoveDamage * 15; + gBattleMoveDamage = gBattleMoveDamage / 10; + } + + if (gBattleMons[bankDef].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) + { + flags |= (MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED); + } + else + { + while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[bankDef].status2 & STATUS2_FORESIGHT) + break; + i += 3; + continue; + } + + else if (gTypeEffectiveness[i] == moveType) + { + // check type1 + if (gTypeEffectiveness[i + 1] == gBattleMons[bankDef].type1) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + // check type2 + if (gTypeEffectiveness[i + 1] == gBattleMons[bankDef].type2 && + gBattleMons[bankDef].type1 != gBattleMons[bankDef].type2) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + } + i += 3; + } + } + + if (gBattleMons[bankDef].ability == ABILITY_WONDER_GUARD && !(flags & MOVESTATUS_MISSED) + && AttacksThisTurn(bankAtk, move) == 2 + && (!(flags & MOVESTATUS_SUPEREFFECTIVE) || ((flags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) + && gBattleMoves[move].power) + { + flags |= MOVESTATUS_MISSED; + } + return flags; +} + +u8 AI_TypeCalc(u16 move, u16 species, u8 ability) +{ + s32 i = 0; + u8 flags = 0; + u8 type1 = gBaseStats[species].type1, type2 = gBaseStats[species].type2; + u8 moveType; + + if (move == MOVE_STRUGGLE) + return 0; + + moveType = gBattleMoves[move].type; + + if (ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) + { + flags = MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED; + } + else + { + while (gTypeEffectiveness[i] != TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + i += 3; + continue; + } + if (gTypeEffectiveness[i] == moveType) + { + // check type1 + if (gTypeEffectiveness[i + 1] == type1) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + // check type2 + if (gTypeEffectiveness[i + 1] == type2 && type1 != type2) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + } + i += 3; + } + } + if (ability == ABILITY_WONDER_GUARD + && (!(flags & MOVESTATUS_SUPEREFFECTIVE) || ((flags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) + && gBattleMoves[move].power) + flags |= MOVESTATUS_NOTAFFECTED; + return flags; +} + +// Multiplies the damage by a random factor between 85% to 100% inclusive +static inline void ApplyRandomDmgMultiplier(void) +{ + u16 rand = Random(); + u16 randPercent = 100 - (rand % 16); + + if (gBattleMoveDamage != 0) + { + gBattleMoveDamage *= randPercent; + gBattleMoveDamage /= 100; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } +} + +static void Unused_ApplyRandomDmgMultiplier(void) +{ + ApplyRandomDmgMultiplier(); +} + +static void atk07_dmg_adjustment(void) +{ + u8 holdEffect, quality; + + ApplyRandomDmgMultiplier(); + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + { + RecordItemEffectBattle(gBankTarget, holdEffect); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + goto END; + if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE && !gProtectStructs[gBankTarget].endured + && !gSpecialStatuses[gBankTarget].focusBanded) + goto END; + + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + goto END; + + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + + if (gProtectStructs[gBankTarget].endured) + { + gBattleMoveFlags |= MOVESTATUS_ENDURED; + } + else if (gSpecialStatuses[gBankTarget].focusBanded) + { + gBattleMoveFlags |= MOVESTATUS_HUNGON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + + END: + gBattlescriptCurrInstr++; +} + +static void atk08_dmg_adjustment2(void) // The same as 0x7 except it doesn't check for false swipe move effect. +{ + u8 holdEffect, quality; + + ApplyRandomDmgMultiplier(); + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + { + RecordItemEffectBattle(gBankTarget, holdEffect); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + goto END; + if (!gProtectStructs[gBankTarget].endured && !gSpecialStatuses[gBankTarget].focusBanded) + goto END; + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + goto END; + + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + + if (gProtectStructs[gBankTarget].endured) + { + gBattleMoveFlags |= MOVESTATUS_ENDURED; + } + else if (gSpecialStatuses[gBankTarget].focusBanded) + { + gBattleMoveFlags |= MOVESTATUS_HUNGON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + + END: + gBattlescriptCurrInstr++; +} + +static void atk09_attackanimation(void) +{ + if (gBattleExecBuffer) + return; + + if ((gHitMarker & HITMARKER_NO_ANIMATIONS) && (gCurrentMove != MOVE_TRANSFORM && gCurrentMove != MOVE_SUBSTITUTE)) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_Pausex20; + gBattleScripting.animTurn++; + gBattleScripting.animTargetsHit++; + } + else + { + if ((gBattleMoves[gCurrentMove].target & MOVE_TARGET_BOTH + || gBattleMoves[gCurrentMove].target & MOVE_TARGET_FOES_AND_ALLY + || gBattleMoves[gCurrentMove].target & MOVE_TARGET_DEPENDS) + && gBattleScripting.animTargetsHit) + { + gBattlescriptCurrInstr++; + return; + } + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + u8 multihit; + + gActiveBank = gBankAttacker; + + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + multihit = gMultiHitCounter; + else if (gMultiHitCounter != 0 && gMultiHitCounter != 1) + { + if (gBattleMons[gBankTarget].hp <= gBattleMoveDamage) + multihit = 1; + else + multihit = gMultiHitCounter; + } + else + multihit = gMultiHitCounter; + + EmitMoveAnimation(0, gCurrentMove, gBattleScripting.animTurn, gBattleMovePower, gBattleMoveDamage, gBattleMons[gBankAttacker].friendship, &gDisableStructs[gBankAttacker], multihit); + gBattleScripting.animTurn += 1; + gBattleScripting.animTargetsHit += 1; + MarkBufferBankForExecution(gBankAttacker); + gBattlescriptCurrInstr++; + } + else + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_Pausex20; + } + } +} + +static void atk0A_waitanimation(void) +{ + if (gBattleExecBuffer == 0) + gBattlescriptCurrInstr++; +} + +static void atk0B_healthbarupdate(void) +{ + if (gBattleExecBuffer) + return; + + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) + { + PrepareStringBattle(0x80, gActiveBank); + } + else + { + s16 healthValue; + + s32 currDmg = gBattleMoveDamage; + s32 maxPossibleDmgValue = 10000; // not present in R/S, ensures that huge damage values don't change sign + + if (currDmg <= maxPossibleDmgValue) + healthValue = currDmg; + else + healthValue = maxPossibleDmgValue; + + EmitHealthBarUpdate(0, healthValue); + MarkBufferBankForExecution(gActiveBank); + + if (GetBankSide(gActiveBank) == SIDE_PLAYER && gBattleMoveDamage > 0) + gBattleResults.unk5_0 = 1; + } + } + + gBattlescriptCurrInstr += 2; +} + +static void atk0C_datahpupdate(void) +{ + u32 moveType; + + if (gBattleExecBuffer) + return; + + if (gBattleStruct->dynamicMoveType == 0) + moveType = gBattleMoves[gCurrentMove].type; + else if (!(gBattleStruct->dynamicMoveType & 0x40)) + moveType = gBattleStruct->dynamicMoveType & 0x3F; + else + moveType = gBattleMoves[gCurrentMove].type; + + if (!(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) + { + if (gDisableStructs[gActiveBank].substituteHP >= gBattleMoveDamage) + { + if (gSpecialStatuses[gActiveBank].moveturnLostHP == 0) + gSpecialStatuses[gActiveBank].moveturnLostHP = gBattleMoveDamage; + gDisableStructs[gActiveBank].substituteHP -= gBattleMoveDamage; + gHpDealt = gBattleMoveDamage; + } + else + { + if (gSpecialStatuses[gActiveBank].moveturnLostHP == 0) + gSpecialStatuses[gActiveBank].moveturnLostHP = gDisableStructs[gActiveBank].substituteHP; + gHpDealt = gDisableStructs[gActiveBank].substituteHP; + gDisableStructs[gActiveBank].substituteHP = 0; + } + // check substitute fading + if (gDisableStructs[gActiveBank].substituteHP == 0) + { + gBattlescriptCurrInstr += 2; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SubstituteFade; + return; + } + } + else + { + gHitMarker &= ~(HITMARKER_IGNORE_SUBSTITUTE); + if (gBattleMoveDamage < 0) // hp goes up + { + gBattleMons[gActiveBank].hp -= gBattleMoveDamage; + if (gBattleMons[gActiveBank].hp > gBattleMons[gActiveBank].maxHP) + gBattleMons[gActiveBank].hp = gBattleMons[gActiveBank].maxHP; + + } + else // hp goes down + { + if (gHitMarker & HITMARKER_x20) + { + gHitMarker &= ~(HITMARKER_x20); + } + else + { + gTakenDmg[gActiveBank] += gBattleMoveDamage; + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + gTakenDmgBanks[gActiveBank] = gBankAttacker; + else + gTakenDmgBanks[gActiveBank] = gBankTarget; + } + + if (gBattleMons[gActiveBank].hp > gBattleMoveDamage) + { + gBattleMons[gActiveBank].hp -= gBattleMoveDamage; + gHpDealt = gBattleMoveDamage; + } + else + { + gHpDealt = gBattleMons[gActiveBank].hp; + gBattleMons[gActiveBank].hp = 0; + } + + if (!gSpecialStatuses[gActiveBank].moveturnLostHP && !(gHitMarker & HITMARKER_x100000)) + gSpecialStatuses[gActiveBank].moveturnLostHP = gHpDealt; + + if (moveType <= 8 && !(gHitMarker & HITMARKER_x100000) && gCurrentMove != MOVE_PAIN_SPLIT) + { + gProtectStructs[gActiveBank].physicalDmg = gHpDealt; + gSpecialStatuses[gActiveBank].moveturnLostHP_physical = gHpDealt; + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + { + gProtectStructs[gActiveBank].physicalBank = gBankAttacker; + gSpecialStatuses[gActiveBank].moveturnPhysicalBank = gBankAttacker; + } + else + { + gProtectStructs[gActiveBank].physicalBank = gBankTarget; + gSpecialStatuses[gActiveBank].moveturnPhysicalBank = gBankTarget; + } + } + else if (moveType > 8 && !(gHitMarker & HITMARKER_x100000)) + { + gProtectStructs[gActiveBank].specialDmg = gHpDealt; + gSpecialStatuses[gActiveBank].moveturnLostHP_special = gHpDealt; + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + { + gProtectStructs[gActiveBank].specialBank = gBankAttacker; + gSpecialStatuses[gActiveBank].moveturnSpecialBank = gBankAttacker; + } + else + { + gProtectStructs[gActiveBank].specialBank = gBankTarget; + gSpecialStatuses[gActiveBank].moveturnSpecialBank = gBankTarget; + } + } + } + gHitMarker &= ~(HITMARKER_x100000); + EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBank].hp); + MarkBufferBankForExecution(gActiveBank); + } + } + else + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + if (gSpecialStatuses[gActiveBank].moveturnLostHP == 0) + gSpecialStatuses[gActiveBank].moveturnLostHP = 0xFFFF; + } + gBattlescriptCurrInstr += 2; +} + +static void atk0D_critmessage(void) +{ + if (gBattleExecBuffer == 0) + { + if (gCritMultiplier == 2 && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + PrepareStringBattle(0xD9, gBankAttacker); + gBattleCommunication[MSG_DISPLAY] = 1; + } + gBattlescriptCurrInstr++; + } +} + +static void atk0E_effectiveness_sound(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBank = gBankTarget; + if (!(gBattleMoveFlags & MOVESTATUS_MISSED)) + { + switch (gBattleMoveFlags & (u8)(~(MOVESTATUS_MISSED))) + { + case MOVESTATUS_SUPEREFFECTIVE: + EmitEffectivenessSound(0, SE_KOUKA_H); + MarkBufferBankForExecution(gActiveBank); + break; + case MOVESTATUS_NOTVERYEFFECTIVE: + EmitEffectivenessSound(0, SE_KOUKA_L); + MarkBufferBankForExecution(gActiveBank); + break; + case MOVESTATUS_NOTAFFECTED: + case MOVESTATUS_FAILED: + // no sound + break; + case MOVESTATUS_ENDURED: + case MOVESTATUS_ONEHITKO: + case MOVESTATUS_HUNGON: + default: + if (gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE) + { + EmitEffectivenessSound(0, SE_KOUKA_H); + MarkBufferBankForExecution(gActiveBank); + } + else if (gBattleMoveFlags & MOVESTATUS_NOTVERYEFFECTIVE) + { + EmitEffectivenessSound(0, SE_KOUKA_L); + MarkBufferBankForExecution(gActiveBank); + } + else if (!(gBattleMoveFlags & (MOVESTATUS_NOTAFFECTED | MOVESTATUS_FAILED))) + { + EmitEffectivenessSound(0, SE_KOUKA_M); + MarkBufferBankForExecution(gActiveBank); + } + break; + } + } + gBattlescriptCurrInstr++; +} + +static void atk0F_resultmessage(void) +{ + u32 stringId = 0; + + if (gBattleExecBuffer) + return; + + if (gBattleMoveFlags & MOVESTATUS_MISSED && (!(gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) || gBattleCommunication[6] > 2)) + { + stringId = gMissStringIds[gBattleCommunication[6]]; + gBattleCommunication[MSG_DISPLAY] = 1; + } + else + { + gBattleCommunication[MSG_DISPLAY] = 1; + switch (gBattleMoveFlags & (u8)(~(MOVESTATUS_MISSED))) + { + case MOVESTATUS_SUPEREFFECTIVE: + stringId = 0xDE; + break; + case MOVESTATUS_NOTVERYEFFECTIVE: + stringId = 0xDD; + break; + case MOVESTATUS_ONEHITKO: + stringId = 0xDA; + break; + case MOVESTATUS_ENDURED: + stringId = 0x99; + break; + case MOVESTATUS_FAILED: + stringId = 0xE5; + break; + case MOVESTATUS_NOTAFFECTED: + stringId = 0x1B; + break; + case MOVESTATUS_HUNGON: + gLastUsedItem = gBattleMons[gBankTarget].item; + gStringBank = gBankTarget; + gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_HangedOnMsg; + return; + default: + if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) + { + stringId = 0x1B; + } + else if (gBattleMoveFlags & MOVESTATUS_ONEHITKO) + { + gBattleMoveFlags &= ~(MOVESTATUS_ONEHITKO); + gBattleMoveFlags &= ~(MOVESTATUS_SUPEREFFECTIVE); + gBattleMoveFlags &= ~(MOVESTATUS_NOTVERYEFFECTIVE); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_OneHitKOMsg; + return; + } + else if (gBattleMoveFlags & MOVESTATUS_ENDURED) + { + gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_EnduredMsg; + return; + } + else if (gBattleMoveFlags & MOVESTATUS_HUNGON) + { + gLastUsedItem = gBattleMons[gBankTarget].item; + gStringBank = gBankTarget; + gBattleMoveFlags &= ~(MOVESTATUS_ENDURED | MOVESTATUS_HUNGON); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_HangedOnMsg; + return; + } + else if (gBattleMoveFlags & MOVESTATUS_FAILED) + { + stringId = 0xE5; + } + else + { + gBattleCommunication[MSG_DISPLAY] = 0; + } + } + } + + if (stringId) + PrepareStringBattle(stringId, gBankAttacker); + + gBattlescriptCurrInstr++; +} + +static void atk10_printstring(void) +{ + if (gBattleExecBuffer == 0) + { + u16 var = BS2ScriptRead16(gBattlescriptCurrInstr + 1); + PrepareStringBattle(var, gBankAttacker); + gBattlescriptCurrInstr += 3; + gBattleCommunication[MSG_DISPLAY] = 1; + } +} + +static void atk11_printstring_playeronly(void) +{ + gActiveBank = gBankAttacker; + + EmitPrintStringPlayerOnly(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1)); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 3; + gBattleCommunication[MSG_DISPLAY] = 1; +} + +static void atk12_waitmessage(void) +{ + if (gBattleExecBuffer == 0) + { + if (!gBattleCommunication[MSG_DISPLAY]) + { + gBattlescriptCurrInstr += 3; + } + else + { + u16 toWait = BS2ScriptRead16(gBattlescriptCurrInstr + 1); + if (++gPauseCounterBattle >= toWait) + { + gPauseCounterBattle = 0; + gBattlescriptCurrInstr += 3; + gBattleCommunication[MSG_DISPLAY] = 0; + } + } + } +} + +static void atk13_printfromtable(void) +{ + if (gBattleExecBuffer == 0) + { + const u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + ptr += gBattleCommunication[MULTISTRING_CHOOSER]; + + PrepareStringBattle(*ptr, gBankAttacker); + + gBattlescriptCurrInstr += 5; + gBattleCommunication[MSG_DISPLAY] = 1; + } +} + +static void atk14_printfromtable_playeronly(void) +{ + if (gBattleExecBuffer == 0) + { + const u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + ptr += gBattleCommunication[MULTISTRING_CHOOSER]; + + gActiveBank = gBankAttacker; + EmitPrintStringPlayerOnly(0, *ptr); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 5; + gBattleCommunication[MSG_DISPLAY] = 1; + } +} + +u8 BankGetTurnOrder(u8 bank) +{ + s32 i; + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gTurnOrder[i] == bank) + break; + } + return i; +} + +#define INCREMENT_RESET_RETURN \ +{ \ + gBattlescriptCurrInstr++; \ + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; \ + return; \ +} + +#define RESET_RETURN \ +{ \ + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; \ + return; \ +} + +void SetMoveEffect(bool8 primary, u8 certain) +{ + bool32 statusChanged = FALSE; + u8 affectsUser = 0; // 0x40 otherwise + bool32 noSunCanFreeze = TRUE; + + if (gBattleCommunication[MOVE_EFFECT_BYTE] & MOVE_EFFECT_AFFECTS_USER) + { + gEffectBank = gBankAttacker; // bank that effects get applied on + gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(MOVE_EFFECT_AFFECTS_USER); + affectsUser = MOVE_EFFECT_AFFECTS_USER; + gBattleScripting.bank = gBankTarget; // theoretically the attacker + } + else + { + gEffectBank = gBankTarget; + gBattleScripting.bank = gBankAttacker; + } + + if (gBattleMons[gEffectBank].ability == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 9) + INCREMENT_RESET_RETURN + + if (gSideAffecting[GET_BANK_SIDE(gEffectBank)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 7) + INCREMENT_RESET_RETURN + + if (gBattleMons[gEffectBank].hp == 0 + && gBattleCommunication[MOVE_EFFECT_BYTE] != MOVE_EFFECT_PAYDAY + && gBattleCommunication[MOVE_EFFECT_BYTE] != MOVE_EFFECT_STEAL_ITEM) + INCREMENT_RESET_RETURN + + if (gBattleMons[gEffectBank].status2 & STATUS2_SUBSTITUTE && affectsUser != MOVE_EFFECT_AFFECTS_USER) + INCREMENT_RESET_RETURN + + if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) // status change + { + switch (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + { + case STATUS_SLEEP: + // check active uproar + if (gBattleMons[gEffectBank].ability != ABILITY_SOUNDPROOF) + { + for (gActiveBank = 0; + gActiveBank < gNoOfAllBanks && !(gBattleMons[gActiveBank].status2 & STATUS2_UPROAR); + gActiveBank++) + {} + } + else + gActiveBank = gNoOfAllBanks; + + if (gBattleMons[gEffectBank].status1) + break; + if (gActiveBank != gNoOfAllBanks) + break; + if (gBattleMons[gEffectBank].ability == ABILITY_VITAL_SPIRIT) + break; + if (gBattleMons[gEffectBank].ability == ABILITY_INSOMNIA) + break; + + CancelMultiTurnMoves(gEffectBank); + statusChanged = TRUE; + break; + case STATUS_POISON: + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY + && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) + { + gLastUsedAbility = ABILITY_IMMUNITY; + RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + RESET_RETURN + } + if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON + || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) + && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + RESET_RETURN + } + if (gBattleMons[gEffectBank].type1 == TYPE_POISON) + break; + if (gBattleMons[gEffectBank].type2 == TYPE_POISON) + break; + if (gBattleMons[gEffectBank].type1 == TYPE_STEEL) + break; + if (gBattleMons[gEffectBank].type2 == TYPE_STEEL) + break; + if (gBattleMons[gEffectBank].status1) + break; + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) + break; + + statusChanged = TRUE; + break; + case STATUS_BURN: + if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL + && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) + { + gLastUsedAbility = ABILITY_WATER_VEIL; + RecordAbilityBattle(gEffectBank, ABILITY_WATER_VEIL); + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_BRNPrevention; + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + RESET_RETURN + } + if ((gBattleMons[gEffectBank].type1 == TYPE_FIRE + || gBattleMons[gEffectBank].type2 == TYPE_FIRE) + && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_BRNPrevention; + + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + RESET_RETURN + } + if (gBattleMons[gEffectBank].type1 == TYPE_FIRE) + break; + if (gBattleMons[gEffectBank].type2 == TYPE_FIRE) + break; + if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL) + break; + if (gBattleMons[gEffectBank].status1) + break; + + statusChanged = TRUE; + break; + case STATUS_FREEZE: + if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY) + noSunCanFreeze = FALSE; + if (gBattleMons[gEffectBank].type1 == TYPE_ICE) + break; + if (gBattleMons[gEffectBank].type2 == TYPE_ICE) + break; + if (gBattleMons[gEffectBank].status1) + break; + if (noSunCanFreeze == 0) + break; + if (gBattleMons[gEffectBank].ability == ABILITY_MAGMA_ARMOR) + break; + + CancelMultiTurnMoves(gEffectBank); + statusChanged = TRUE; + break; + case STATUS_PARALYSIS: + if (gBattleMons[gEffectBank].ability == ABILITY_LIMBER) + { + if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN) + { + gLastUsedAbility = ABILITY_LIMBER; + RecordAbilityBattle(gEffectBank, ABILITY_LIMBER); + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PRLZPrevention; + + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + RESET_RETURN + } + else + break; + } + if (gBattleMons[gEffectBank].status1) + break; + + statusChanged = TRUE; + break; + case STATUS_TOXIC_POISON: + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) + { + gLastUsedAbility = ABILITY_IMMUNITY; + RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + RESET_RETURN + } + if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON + || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) + && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + RESET_RETURN + } + if (gBattleMons[gEffectBank].status1) + break; + if (gBattleMons[gEffectBank].type1 != TYPE_POISON + && gBattleMons[gEffectBank].type2 != TYPE_POISON + && gBattleMons[gEffectBank].type1 != TYPE_STEEL + && gBattleMons[gEffectBank].type2 != TYPE_STEEL) + { + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) + break; + + // It's redundant, because at this point we know the status1 value is 0. + gBattleMons[gEffectBank].status1 &= ~(STATUS_TOXIC_POISON); + gBattleMons[gEffectBank].status1 &= ~(STATUS_POISON); + statusChanged = TRUE; + break; + } + else + { + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + } + break; + } + if (statusChanged == TRUE) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + + if (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS_SLEEP) + gBattleMons[gEffectBank].status1 |= ((Random() & 3) + 2); + else + gBattleMons[gEffectBank].status1 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; + + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + + gActiveBank = gEffectBank; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBank].status1); + MarkBufferBankForExecution(gActiveBank); + + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + + // for synchronize + + if (gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_POISON + || gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_TOXIC + || gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_PARALYSIS + || gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_BURN) + { + u8* synchronizeEffect = &gBattleStruct->synchronizeMoveEffect; + *synchronizeEffect = gBattleCommunication[MOVE_EFFECT_BYTE]; + gHitMarker |= HITMARKER_SYNCHRONISE_EFFECT; + } + return; + } + else if (statusChanged == FALSE) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattlescriptCurrInstr++; + return; + } + return; + } + else + { + if (gBattleMons[gEffectBank].status2 & sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + { + gBattlescriptCurrInstr++; + } + else + { + u8 side; + switch (gBattleCommunication[MOVE_EFFECT_BYTE]) + { + case MOVE_EFFECT_CONFUSION: + if (gBattleMons[gEffectBank].ability == ABILITY_OWN_TEMPO + || gBattleMons[gEffectBank].status2 & STATUS2_CONFUSION) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleMons[gEffectBank].status2 |= (((Random()) % 0x4)) + 2; + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + } + break; + case MOVE_EFFECT_FLINCH: + if (gBattleMons[gEffectBank].ability == ABILITY_INNER_FOCUS) + { + if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN) + { + gLastUsedAbility = ABILITY_INNER_FOCUS; + RecordAbilityBattle(gEffectBank, ABILITY_INNER_FOCUS); + gBattlescriptCurrInstr = BattleScript_FlinchPrevention; + } + else + { + gBattlescriptCurrInstr++; + } + } + else + { + if (BankGetTurnOrder(gEffectBank) > gCurrentMoveTurn) + gBattleMons[gEffectBank].status2 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattlescriptCurrInstr++; + } + break; + case MOVE_EFFECT_UPROAR: + if (!(gBattleMons[gEffectBank].status2 & STATUS2_UPROAR)) + { + + gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBank] = gCurrentMove; + gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 4; + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + } + else + { + gBattlescriptCurrInstr++; + } + break; + case MOVE_EFFECT_PAYDAY: + if (GET_BANK_SIDE(gBankAttacker) == SIDE_PLAYER) + { + u16 PayDay = gPaydayMoney; + gPaydayMoney += (gBattleMons[gBankAttacker].level * 5); + if (PayDay > gPaydayMoney) + gPaydayMoney = 0xFFFF; + } + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case MOVE_EFFECT_TRI_ATTACK: + if (gBattleMons[gEffectBank].status1) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleCommunication[MOVE_EFFECT_BYTE] = Random() % 3 + 3; + SetMoveEffect(FALSE, 0); + } + break; + case MOVE_EFFECT_CHARGING: + gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBank] = gCurrentMove; + gProtectStructs[gEffectBank].chargingTurn = 1; + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_WRAP: + if (gBattleMons[gEffectBank].status2 & STATUS2_WRAPPED) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 3) << 0xD; + + *(gBattleStruct->wrappedMove + gEffectBank * 2 + 0) = gCurrentMove; + *(gBattleStruct->wrappedMove + gEffectBank * 2 + 1) = gCurrentMove >> 8; + *(gBattleStruct->wrappedBy + gEffectBank) = gBankAttacker; + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + + for (gBattleCommunication[MULTISTRING_CHOOSER] = 0; ; gBattleCommunication[MULTISTRING_CHOOSER]++) + { + if (gBattleCommunication[MULTISTRING_CHOOSER] > 4) + break; + if (gTrappingMoves[gBattleCommunication[MULTISTRING_CHOOSER]] == gCurrentMove) + break; + } + } + break; + case MOVE_EFFECT_RECOIL_25: // 25% recoil + gBattleMoveDamage = (gHpDealt) / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case MOVE_EFFECT_ATK_PLUS_1: + case MOVE_EFFECT_DEF_PLUS_1: + case MOVE_EFFECT_SPD_PLUS_1: + case MOVE_EFFECT_SP_ATK_PLUS_1: + case MOVE_EFFECT_SP_DEF_PLUS_1: + case MOVE_EFFECT_ACC_PLUS_1: + case MOVE_EFFECT_EVS_PLUS_1: + if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1), + gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_PLUS_1 + 1, + affectsUser, 0)) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); + gBattleScripting.animArg2 = 0; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatUp; + } + break; + case MOVE_EFFECT_ATK_MINUS_1: + case MOVE_EFFECT_DEF_MINUS_1: + case MOVE_EFFECT_SPD_MINUS_1: + case MOVE_EFFECT_SP_ATK_MINUS_1: + case MOVE_EFFECT_SP_DEF_MINUS_1: + case MOVE_EFFECT_ACC_MINUS_1: + case MOVE_EFFECT_EVS_MINUS_1: + if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE, + gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_MINUS_1 + 1, + affectsUser, 0)) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); + gBattleScripting.animArg2 = 0; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatDown; + } + break; + case MOVE_EFFECT_ATK_PLUS_2: + case MOVE_EFFECT_DEF_PLUS_2: + case MOVE_EFFECT_SPD_PLUS_2: + case MOVE_EFFECT_SP_ATK_PLUS_2: + case MOVE_EFFECT_SP_DEF_PLUS_2: + case MOVE_EFFECT_ACC_PLUS_2: + case MOVE_EFFECT_EVS_PLUS_2: + if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2), + gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_PLUS_2 + 1, + affectsUser, 0)) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); + gBattleScripting.animArg2 = 0; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatUp; + } + break; + case MOVE_EFFECT_ATK_MINUS_2: + case MOVE_EFFECT_DEF_MINUS_2: + case MOVE_EFFECT_SPD_MINUS_2: + case MOVE_EFFECT_SP_ATK_MINUS_2: + case MOVE_EFFECT_SP_DEF_MINUS_2: + case MOVE_EFFECT_ACC_MINUS_2: + case MOVE_EFFECT_EVS_MINUS_2: + if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE, + gBattleCommunication[MOVE_EFFECT_BYTE] - MOVE_EFFECT_ATK_MINUS_2 + 1, + affectsUser, 0)) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN); + gBattleScripting.animArg2 = 0; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatDown; + } + break; + case MOVE_EFFECT_RECHARGE: + gBattleMons[gEffectBank].status2 |= STATUS2_RECHARGE; + gDisableStructs[gEffectBank].rechargeCounter = 2; + gLockedMoves[gEffectBank] = gCurrentMove; + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_RAGE: + gBattleMons[gBankAttacker].status2 |= STATUS2_RAGE; + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_STEAL_ITEM: + { + if (gBattleTypeFlags & BATTLE_TYPE_x4000000) + { + gBattlescriptCurrInstr++; + break; + } + + side = GetBankSide(gBankAttacker); + if (GetBankSide(gBankAttacker) == SIDE_OPPONENT + && !(gBattleTypeFlags & + (BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_LINK + | BATTLE_TYPE_x2000000 + | BATTLE_TYPE_SECRET_BASE))) + { + gBattlescriptCurrInstr++; + } + else if (!(gBattleTypeFlags & + (BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_LINK + | BATTLE_TYPE_x2000000 + | BATTLE_TYPE_SECRET_BASE)) + && (gWishFutureKnock.knockedOffPokes[side] & gBitTable[gBattlePartyID[gBankAttacker]])) + { + gBattlescriptCurrInstr++; + } + else if (gBattleMons[gBankTarget].item + && gBattleMons[gBankTarget].ability == ABILITY_STICKY_HOLD) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_NoItemSteal; + + gLastUsedAbility = gBattleMons[gBankTarget].ability; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else if (gBattleMons[gBankAttacker].item != 0 + || gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY + || IS_ITEM_MAIL(gBattleMons[gBankTarget].item) + || gBattleMons[gBankTarget].item == 0) + { + gBattlescriptCurrInstr++; + } + else + { + u16* changedItem = &gBattleStruct->changedItems[gBankAttacker]; + gLastUsedItem = *changedItem = gBattleMons[gBankTarget].item; + gBattleMons[gBankTarget].item = 0; + + gActiveBank = gBankAttacker; + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedItem); + MarkBufferBankForExecution(gBankAttacker); + + gActiveBank = gBankTarget; + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); + MarkBufferBankForExecution(gBankTarget); + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_ItemSteal; + + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 0) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 1) = 0; + } + + } + break; + case MOVE_EFFECT_PREVENT_ESCAPE: + gBattleMons[gBankTarget].status2 |= STATUS2_ESCAPE_PREVENTION; + gDisableStructs[gBankTarget].bankPreventingEscape = gBankAttacker; + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_NIGHTMARE: + gBattleMons[gBankTarget].status2 |= STATUS2_NIGHTMARE; + gBattlescriptCurrInstr++; + break; + case MOVE_EFFECT_ALL_STATS_UP: + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_AllStatsUp; + break; + case MOVE_EFFECT_RAPIDSPIN: + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_RapidSpinAway; + break; + case MOVE_EFFECT_REMOVE_PARALYSIS: // Smelling salts + if (!(gBattleMons[gBankTarget].status1 & STATUS_PARALYSIS)) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleMons[gBankTarget].status1 &= ~(STATUS_PARALYSIS); + + gActiveBank = gBankTarget; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal; + } + break; + case MOVE_EFFECT_ATK_DEF_DOWN: // SuperPower + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_AtkDefDown; + break; + case MOVE_EFFECT_RECOIL_33_PARALYSIS: // Volt Tackle + gBattleMoveDamage = gHpDealt / 3; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case MOVE_EFFECT_THRASH: + if (gBattleMons[gEffectBank].status2 & STATUS2_LOCK_CONFUSE) + { + gBattlescriptCurrInstr++; + } + else + { + gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBank] = gCurrentMove; + gBattleMons[gEffectBank].status2 |= (((Random() & 1) + 2) << 0xA); + } + break; + case MOVE_EFFECT_KNOCK_OFF: + if (gBattleMons[gEffectBank].ability == ABILITY_STICKY_HOLD) + { + if (gBattleMons[gEffectBank].item == 0) + { + gBattlescriptCurrInstr++; + } + else + { + gLastUsedAbility = ABILITY_STICKY_HOLD; + gBattlescriptCurrInstr = BattleScript_StickyHoldActivates; + RecordAbilityBattle(gEffectBank, ABILITY_STICKY_HOLD); + } + break; + } + if (gBattleMons[gEffectBank].item) + { + side = GetBankSide(gEffectBank); + + gLastUsedItem = gBattleMons[gEffectBank].item; + gBattleMons[gEffectBank].item = 0; + gWishFutureKnock.knockedOffPokes[side] |= gBitTable[gBattlePartyID[gEffectBank]]; + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_KnockedOff; + + *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBank]) + 0) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBank]) + 1) = 0; + } + else + { + gBattlescriptCurrInstr++; + } + break; + case MOVE_EFFECT_SP_ATK_TWO_DOWN: // Overheat + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_SAtkDown2; + break; + } + } + } + + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; +} + +static void atk15_seteffectwithchance(void) +{ + u32 percentChance; + + if (gBattleMons[gBankAttacker].ability == ABILITY_SERENE_GRACE) + percentChance = gBattleMoves[gCurrentMove].secondaryEffectChance * 2; + else + percentChance = gBattleMoves[gCurrentMove].secondaryEffectChance; + + if (gBattleCommunication[MOVE_EFFECT_BYTE] & MOVE_EFFECT_CERTAIN + && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(MOVE_EFFECT_CERTAIN); + SetMoveEffect(0, MOVE_EFFECT_CERTAIN); + } + else if (Random() % 100 < percentChance + && gBattleCommunication[MOVE_EFFECT_BYTE] + && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + if (percentChance >= 100) + SetMoveEffect(0, MOVE_EFFECT_CERTAIN); + else + SetMoveEffect(0, 0); + } + else + { + gBattlescriptCurrInstr++; + } + + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattleScripting.field_16 = 0; +} + +static void atk16_seteffectprimary(void) +{ + SetMoveEffect(TRUE, 0); +} + +static void atk17_seteffectsecondary(void) +{ + SetMoveEffect(FALSE, 0); +} + +static void atk18_status_effect_clear(void) +{ + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + if (gBattleCommunication[MOVE_EFFECT_BYTE] <= MOVE_EFFECT_TOXIC) + gBattleMons[gActiveBank].status1 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); + else + gBattleMons[gActiveBank].status2 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); + + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattlescriptCurrInstr += 2; + gBattleScripting.field_16 = 0; +} + +static void atk19_faint_pokemon(void) +{ + const u8 *BS_ptr; + + if (gBattlescriptCurrInstr[2] != 0) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + if (gHitMarker & HITMARKER_FAINTED(gActiveBank)) + { + BS_ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 3); + + BattleScriptPop(); + gBattlescriptCurrInstr = BS_ptr; + gSideAffecting[GetBankSide(gActiveBank)] &= ~(SIDE_STATUS_SPIKES_DAMAGED); + } + else + { + gBattlescriptCurrInstr += 7; + } + } + else + { + u8 bank; + + if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER) + { + gActiveBank = gBankAttacker; + bank = gBankTarget; + BS_ptr = BattleScript_FaintAttacker; + } + else + { + gActiveBank = gBankTarget; + bank = gBankAttacker; + BS_ptr = BattleScript_FaintTarget; + } + if (!(gAbsentBankFlags & gBitTable[gActiveBank]) + && gBattleMons[gActiveBank].hp == 0) + { + gHitMarker |= HITMARKER_FAINTED(gActiveBank); + BattleScriptPush(gBattlescriptCurrInstr + 7); + gBattlescriptCurrInstr = BS_ptr; + if (GetBankSide(gActiveBank) == SIDE_PLAYER) + { + gHitMarker |= HITMARKER_x400000; + if (gBattleResults.playerFaintCounter < 0xFF) + gBattleResults.playerFaintCounter++; + AdjustFriendshipOnBattleFaint(gActiveBank); + } + else + { + if (gBattleResults.opponentFaintCounter < 0xFF) + gBattleResults.opponentFaintCounter++; + gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES, NULL); + } + if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBankAttacker].hp != 0) + { + gHitMarker &= ~(HITMARKER_DESTINYBOND); + BattleScriptPush(gBattlescriptCurrInstr); + gBattleMoveDamage = gBattleMons[bank].hp; + gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife; + } + if ((gStatuses3[gBankTarget] & STATUS3_GRUDGE) + && !(gHitMarker & HITMARKER_GRUDGE) + && GetBankSide(gBankAttacker) != GetBankSide(gBankTarget) + && gBattleMons[gBankAttacker].hp != 0 + && gCurrentMove != MOVE_STRUGGLE) + { + u8 moveIndex = *(gBattleStruct->chosenMovesIds + gBankAttacker); + + gBattleMons[gBankAttacker].pp[moveIndex] = 0; + BattleScriptPush(gBattlescriptCurrInstr); + gBattlescriptCurrInstr = BattleScript_GrudgeTakesPp; + gActiveBank = gBankAttacker; + EmitSetMonData(0, moveIndex + REQUEST_PPMOVE1_BATTLE, 0, 1, &gBattleMons[gActiveBank].pp[moveIndex]); + MarkBufferBankForExecution(gActiveBank); + + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBankAttacker].moves[moveIndex]) + } + } + else + { + gBattlescriptCurrInstr += 7; + } + } +} + +static void atk1A_faint_animation(void) +{ + if (gBattleExecBuffer == 0) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + EmitFaintAnimation(0); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 2; + } +} + +static void atk1B_faint_effects_clear(void) +{ + if (gBattleExecBuffer == 0) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + if (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || gBattleMons[gActiveBank].hp == 0) + { + gBattleMons[gActiveBank].status1 = 0; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 0x4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + } + + UndoEffectsAfterFainting(); // Effects like attractions, trapping, etc. + gBattlescriptCurrInstr += 2; + } +} + +static void atk1C_jumpifstatus(void) +{ + u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); + + if (gBattleMons[bank].status1 & flags && gBattleMons[bank].hp) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 10; +} + +static void atk1D_jumpifstatus2(void) +{ + u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); + + if (gBattleMons[bank].status2 & flags && gBattleMons[bank].hp) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 10; +} + +static void atk1E_jumpifability(void) +{ + u8 bank; + u8 ability = gBattlescriptCurrInstr[2]; + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); + + if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER_SIDE) + { + bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_BANK_SIDE, gBankAttacker, ability, 0, 0); + if (bank) + { + gLastUsedAbility = ability; + gBattlescriptCurrInstr = jumpPtr; + RecordAbilityBattle(bank - 1, gLastUsedAbility); + gBattleScripting.field_15 = bank - 1; + } + else + gBattlescriptCurrInstr += 7; + } + else if (gBattlescriptCurrInstr[1] == BS_GET_NOT_ATTACKER_SIDE) + { + bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gBankAttacker, ability, 0, 0); + if (bank) + { + gLastUsedAbility = ability; + gBattlescriptCurrInstr = jumpPtr; + RecordAbilityBattle(bank - 1, gLastUsedAbility); + gBattleScripting.field_15 = bank - 1; + } + else + gBattlescriptCurrInstr += 7; + } + else + { + bank = GetBattleBank(gBattlescriptCurrInstr[1]); + if (gBattleMons[bank].ability == ability) + { + gLastUsedAbility = ability; + gBattlescriptCurrInstr = jumpPtr; + RecordAbilityBattle(bank, gLastUsedAbility); + gBattleScripting.field_15 = bank; + } + else + gBattlescriptCurrInstr += 7; + } +} + +static void atk1F_jumpifsideaffecting(void) +{ + u8 side; + u16 flags; + const u8* jumpPtr; + + if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER) + side = GET_BANK_SIDE(gBankAttacker); + else + side = GET_BANK_SIDE(gBankTarget); + + flags = BS2ScriptRead16(gBattlescriptCurrInstr + 2); + jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 4); + + if (gSideAffecting[side] & flags) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 8; +} + +static void atk20_jumpifstat(void) +{ + u8 ret = 0; + u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + u8 value = gBattleMons[bank].statStages[gBattlescriptCurrInstr[3]]; + + switch (gBattlescriptCurrInstr[2]) + { + case CMP_EQUAL: + if (value == gBattlescriptCurrInstr[4]) + ret++; + break; + case CMP_NOT_EQUAL: + if (value != gBattlescriptCurrInstr[4]) + ret++; + break; + case CMP_GREATER_THAN: + if (value > gBattlescriptCurrInstr[4]) + ret++; + break; + case CMP_LESS_THAN: + if (value < gBattlescriptCurrInstr[4]) + ret++; + break; + case CMP_COMMON_BITS: + if (value & gBattlescriptCurrInstr[4]) + ret++; + break; + case CMP_NO_COMMON_BITS: + if (!(value & gBattlescriptCurrInstr[4])) + ret++; + break; + } + + if (ret) + gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); + else + gBattlescriptCurrInstr += 9; +} + +static void atk21_jumpifstatus3(void) +{ + u32 flags; + const u8* jumpPtr; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); + jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7); + + if (gBattlescriptCurrInstr[6]) + { + if ((gStatuses3[gActiveBank] & flags) != 0) + gBattlescriptCurrInstr += 11; + else + gBattlescriptCurrInstr = jumpPtr; + } + else + { + if ((gStatuses3[gActiveBank] & flags) != 0) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 11; + } +} + +static void atk22_jumpiftype(void) +{ + u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + u8 type = gBattlescriptCurrInstr[2]; + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); + + if (gBattleMons[bank].type1 == type || gBattleMons[bank].type2 == type) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 7; +} + +static void atk23_getexp(void) +{ + u16 item; + s32 i; // also used as stringId + u8 holdEffect; + s32 sentIn; + + s32 viaExpShare = 0; + u16* exp = &gBattleStruct->expValue; + + gBank1 = GetBattleBank(gBattlescriptCurrInstr[1]); + sentIn = gSentPokesToOpponent[(gBank1 & 2) >> 1]; + + switch (gBattleScripting.atk23_state) + { + case 0: // check if should receive exp at all + if (GetBankSide(gBank1) != SIDE_OPPONENT || (gBattleTypeFlags & + (BATTLE_TYPE_LINK + | BATTLE_TYPE_x2000000 + | BATTLE_TYPE_x4000000 + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_SAFARI + | BATTLE_TYPE_BATTLE_TOWER + | BATTLE_TYPE_EREADER_TRAINER))) + { + gBattleScripting.atk23_state = 6; // goto last case + } + else + { + gBattleScripting.atk23_state++; + gBattleStruct->field_DF |= gBitTable[gBattlePartyID[gBank1]]; + } + break; + case 1: // calculate experience points to redistribute + { + u16 calculatedExp; + s32 viaSentIn; + + for (viaSentIn = 0, i = 0; i < 6; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == SPECIES_NONE || GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0) + continue; + if (gBitTable[i] & sentIn) + viaSentIn++; + + item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + if (holdEffect == HOLD_EFFECT_EXP_SHARE) + viaExpShare++; + } + + calculatedExp = gBaseStats[gBattleMons[gBank1].species].expYield * gBattleMons[gBank1].level / 7; + + if (viaExpShare) // at least one mon is getting exp via exp share + { + *exp = calculatedExp / 2 / viaSentIn; + if (*exp == 0) + *exp = 1; + + gExpShareExp = calculatedExp / 2 / viaExpShare; + if (gExpShareExp == 0) + gExpShareExp = 1; + } + else + { + *exp = calculatedExp / viaSentIn; + if (*exp == 0) + *exp = 1; + gExpShareExp = 0; + } + + gBattleScripting.atk23_state++; + gBattleStruct->expGetterId = 0; + gBattleStruct->sentInPokes = sentIn; + } + // fall through + case 2: // set exp value to the poke in expgetter_id and print message + if (gBattleExecBuffer == 0) + { + item = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HELD_ITEM); + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + if (holdEffect != HOLD_EFFECT_EXP_SHARE && !(gBattleStruct->sentInPokes & 1)) + { + *(&gBattleStruct->sentInPokes) >>= 1; + gBattleScripting.atk23_state = 5; + gBattleMoveDamage = 0; // used for exp + } + else if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL) == MAX_MON_LEVEL) + { + *(&gBattleStruct->sentInPokes) >>= 1; + gBattleScripting.atk23_state = 5; + gBattleMoveDamage = 0; // used for exp + } + else + { + // music change in wild battle after fainting a poke + if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) && gBattleMons[0].hp && !gBattleStruct->wildVictorySong) + { + BattleMusicStop(); + PlayBGM(0x161); + gBattleStruct->wildVictorySong++; + } + + if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP)) + { + if (gBattleStruct->sentInPokes & 1) + gBattleMoveDamage = *exp; + else + gBattleMoveDamage = 0; + + if (holdEffect == HOLD_EFFECT_EXP_SHARE) + gBattleMoveDamage += gExpShareExp; + if (holdEffect == HOLD_EFFECT_LUCKY_EGG) + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; + + if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterId])) + { + // check if the pokemon doesn't belong to the player + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gBattleStruct->expGetterId >= 3) + { + i = 0x149; + } + else + { + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; + i = 0x14A; + } + } + else + { + i = 0x149; + } + + // get exp getter bank + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + if (!(gBattlePartyID[2] != gBattleStruct->expGetterId) && !(gAbsentBankFlags & gBitTable[2])) + gBattleStruct->expGetterBank = 2; + else + { + if (!(gAbsentBankFlags & gBitTable[0])) + gBattleStruct->expGetterBank = 0; + else + gBattleStruct->expGetterBank = 2; + } + } + else + gBattleStruct->expGetterBank = 0; + + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBank, gBattleStruct->expGetterId) + + // buffer 'gained' or 'gained a boosted' + PREPARE_STRING_BUFFER(gBattleTextBuff2, i) + + PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 5, gBattleMoveDamage) + + PrepareStringBattle(0xD, gBattleStruct->expGetterBank); + MonGainEVs(&gPlayerParty[gBattleStruct->expGetterId], gBattleMons[gBank1].species); + } + gBattleStruct->sentInPokes >>= 1; + gBattleScripting.atk23_state++; + } + } + break; + case 3: // Set stats and give exp + if (gBattleExecBuffer == 0) + { + gBattleBufferB[gBattleStruct->expGetterBank][0] = 0; + if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP) && GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL) != MAX_MON_LEVEL) + { + BATTLE_LVLUP_STATS->hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); + BATTLE_LVLUP_STATS->atk = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); + BATTLE_LVLUP_STATS->def = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); + BATTLE_LVLUP_STATS->spd = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); + BATTLE_LVLUP_STATS->spAtk = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); + BATTLE_LVLUP_STATS->spDef = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPDEF); + + gActiveBank = gBattleStruct->expGetterBank; + EmitExpUpdate(0, gBattleStruct->expGetterId, gBattleMoveDamage); + MarkBufferBankForExecution(gActiveBank); + } + gBattleScripting.atk23_state++; + } + break; + case 4: // lvl up if necessary + if (gBattleExecBuffer == 0) + { + gActiveBank = gBattleStruct->expGetterBank; + if (gBattleBufferB[gActiveBank][0] == 0x21 && gBattleBufferB[gActiveBank][1] == 0xB) + { + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId) + sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBank, gBattleStruct->expGetterId) + + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 3, GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL)) + + BattleScriptPushCursor(); + gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterId]; + gBattlescriptCurrInstr = BattleScript_LevelUp; + gBattleMoveDamage = (gBattleBufferB[gActiveBank][2] | (gBattleBufferB[gActiveBank][3] << 8)); + AdjustFriendship(&gPlayerParty[gBattleStruct->expGetterId], 0); + + // update battle mon structure after level up + if (gBattlePartyID[0] == gBattleStruct->expGetterId && gBattleMons[0].hp) + { + gBattleMons[0].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); + gBattleMons[0].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP); + gBattleMons[0].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); + gBattleMons[0].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); + gBattleMons[0].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); + // Why is this duplicated? + gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); + gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); + + gBattleMons[0].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); + gBattleMons[0].spDefense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPDEF); + } + // What is else if? + if (gBattlePartyID[2] == gBattleStruct->expGetterId && gBattleMons[2].hp && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gBattleMons[2].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); + gBattleMons[2].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP); + gBattleMons[2].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); + gBattleMons[2].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); + gBattleMons[2].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); + // Duplicated again, but this time there's no Sp Defense + gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); + gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD); + + gBattleMons[2].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); + } + gBattleScripting.atk23_state = 5; + } + else + { + gBattleMoveDamage = 0; + gBattleScripting.atk23_state = 5; + } + } + break; + case 5: // looper increment + if (gBattleMoveDamage) // there is exp to give, goto case 3 that gives exp + gBattleScripting.atk23_state = 3; + else + { + gBattleStruct->expGetterId++; + if (gBattleStruct->expGetterId <= 5) + gBattleScripting.atk23_state = 2; // loop again + else + gBattleScripting.atk23_state = 6; // we're done + } + break; + case 6: // increment instruction + if (gBattleExecBuffer == 0) + { + // not sure why gf clears the item and ability here + gBattleMons[gBank1].item = 0; + gBattleMons[gBank1].ability = 0; + gBattlescriptCurrInstr += 2; + } + break; + } +} + +#ifdef NONMATCHING +static void atk24(void) +{ + u16 HP_count = 0; + s32 i; + + if (gBattleExecBuffer) + return; + + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId == STEVEN_PARTNER_ID) + { + for (i = 0; i < 3; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) + HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); + } + } + else + { + for (i = 0; i < 6; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) + && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->field_2A0 & gBitTable[i]))) + { + HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); + } + } + } + + if (HP_count == 0) + gBattleOutcome |= BATTLE_LOST; + + for (HP_count = 0, i = 0; i < 6; i++) + { + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES) && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG) + && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->field_2A1 & gBitTable[i]))) + { + HP_count += GetMonData(&gEnemyParty[i], MON_DATA_HP); + } + } + + if (HP_count == 0) + gBattleOutcome |= BATTLE_WON; + + if (gBattleOutcome == 0 && (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))) + { + s32 foundPlayer; + s32 foundOpponent; + + // Impossible to decompile loops. + for (foundPlayer = 0, i = 0; i < gNoOfAllBanks; i += 2) + { + if (HITMARKER_UNK(i) & gHitMarker && !gSpecialStatuses[i].flag40) + foundPlayer++; + } + + for (foundOpponent = 0, i = 1; i < gNoOfAllBanks; i += 2) + { + if (HITMARKER_UNK(i) & gHitMarker && !gSpecialStatuses[i].flag40) + foundOpponent++; + } + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (foundOpponent + foundPlayer > 1) + gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; + } + else + { + if (foundOpponent != 0 && foundPlayer != 0) + gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; + } + } + else + { + gBattlescriptCurrInstr += 5; + } +} +#else +__attribute__((naked)) +static void atk24(void) +{ + asm("\n\ + .syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + movs r6, 0\n\ + ldr r0, =gBattleExecBuffer\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + beq _0804ACE2\n\ + b _0804AF22\n\ + _0804ACE2:\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 15\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804AD48\n\ + ldr r0, =gPartnerTrainerId\n\ + ldrh r1, [r0]\n\ + ldr r0, =0x00000c03\n\ + cmp r1, r0\n\ + bne _0804AD48\n\ + movs r5, 0\n\ + _0804ACFC:\n\ + movs r0, 0x64\n\ + adds r1, r5, 0\n\ + muls r1, r0\n\ + ldr r0, =gPlayerParty\n\ + adds r4, r1, r0\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _0804AD2C\n\ + adds r0, r4, 0\n\ + movs r1, 0x2D\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + bne _0804AD2C\n\ + adds r0, r4, 0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + adds r0, r6, r0\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ + _0804AD2C:\n\ + adds r5, 0x1\n\ + cmp r5, 0x2\n\ + ble _0804ACFC\n\ + b _0804ADA8\n\ + .pool\n\ + _0804AD48:\n\ + movs r5, 0\n\ + _0804AD4A:\n\ + movs r0, 0x64\n\ + adds r1, r5, 0\n\ + muls r1, r0\n\ + ldr r0, =gPlayerParty\n\ + adds r4, r1, r0\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _0804ADA2\n\ + adds r0, r4, 0\n\ + movs r1, 0x2D\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + bne _0804ADA2\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 11\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804AD94\n\ + ldr r0, =gBattleStruct\n\ + ldr r0, [r0]\n\ + movs r1, 0xA8\n\ + lsls r1, 2\n\ + adds r0, r1\n\ + ldrb r1, [r0]\n\ + ldr r2, =gBitTable\n\ + lsls r0, r5, 2\n\ + adds r0, r2\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _0804ADA2\n\ + _0804AD94:\n\ + adds r0, r4, 0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + adds r0, r6, r0\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ + _0804ADA2:\n\ + adds r5, 0x1\n\ + cmp r5, 0x5\n\ + ble _0804AD4A\n\ + _0804ADA8:\n\ + cmp r6, 0\n\ + bne _0804ADB6\n\ + ldr r0, =gBattleOutcome\n\ + ldrb r1, [r0]\n\ + movs r2, 0x2\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ + _0804ADB6:\n\ + movs r6, 0\n\ + movs r5, 0\n\ + _0804ADBA:\n\ + movs r0, 0x64\n\ + adds r1, r5, 0\n\ + muls r1, r0\n\ + ldr r0, =gEnemyParty\n\ + adds r4, r1, r0\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _0804AE10\n\ + adds r0, r4, 0\n\ + movs r1, 0x2D\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + bne _0804AE10\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 11\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804AE02\n\ + ldr r0, =gBattleStruct\n\ + ldr r0, [r0]\n\ + ldr r1, =0x000002a1\n\ + adds r0, r1\n\ + ldrb r1, [r0]\n\ + ldr r2, =gBitTable\n\ + lsls r0, r5, 2\n\ + adds r0, r2\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _0804AE10\n\ + _0804AE02:\n\ + adds r0, r4, 0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + adds r0, r6, r0\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ + _0804AE10:\n\ + adds r5, 0x1\n\ + cmp r5, 0x5\n\ + ble _0804ADBA\n\ + ldr r2, =gBattleOutcome\n\ + cmp r6, 0\n\ + bne _0804AE24\n\ + ldrb r0, [r2]\n\ + movs r1, 0x1\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + _0804AE24:\n\ + ldrb r0, [r2]\n\ + cmp r0, 0\n\ + bne _0804AF1A\n\ + ldr r0, =gBattleTypeFlags\n\ + ldr r1, [r0]\n\ + ldr r2, =0x02000002\n\ + ands r1, r2\n\ + mov r8, r0\n\ + cmp r1, 0\n\ + beq _0804AF1A\n\ + movs r3, 0\n\ + movs r5, 0\n\ + ldr r0, =gNoOfAllBanks\n\ + ldrb r1, [r0]\n\ + mov r12, r0\n\ + ldr r7, =gBattlescriptCurrInstr\n\ + cmp r3, r1\n\ + bge _0804AE70\n\ + ldr r0, =gHitMarker\n\ + movs r6, 0x80\n\ + lsls r6, 21\n\ + ldr r4, [r0]\n\ + adds r2, r1, 0\n\ + ldr r1, =gSpecialStatuses\n\ + _0804AE54:\n\ + adds r0, r6, 0\n\ + lsls r0, r5\n\ + ands r0, r4\n\ + cmp r0, 0\n\ + beq _0804AE68\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _0804AE68\n\ + adds r3, 0x1\n\ + _0804AE68:\n\ + adds r1, 0x28\n\ + adds r5, 0x2\n\ + cmp r5, r2\n\ + blt _0804AE54\n\ + _0804AE70:\n\ + movs r2, 0\n\ + movs r5, 0x1\n\ + mov r4, r12\n\ + ldrb r1, [r4]\n\ + cmp r5, r1\n\ + bge _0804AEAA\n\ + ldr r0, =gHitMarker\n\ + movs r4, 0x80\n\ + lsls r4, 21\n\ + mov r12, r4\n\ + ldr r6, [r0]\n\ + ldr r0, =gSpecialStatuses\n\ + adds r4, r1, 0\n\ + adds r1, r0, 0\n\ + adds r1, 0x14\n\ + _0804AE8E:\n\ + mov r0, r12\n\ + lsls r0, r5\n\ + ands r0, r6\n\ + cmp r0, 0\n\ + beq _0804AEA2\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _0804AEA2\n\ + adds r2, 0x1\n\ + _0804AEA2:\n\ + adds r1, 0x28\n\ + adds r5, 0x2\n\ + cmp r5, r4\n\ + blt _0804AE8E\n\ + _0804AEAA:\n\ + mov r1, r8\n\ + ldr r0, [r1]\n\ + movs r1, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804AEF0\n\ + adds r0, r2, r3\n\ + cmp r0, 0x1\n\ + bgt _0804AEF8\n\ + b _0804AF12\n\ + .pool\n\ + _0804AEF0:\n\ + cmp r2, 0\n\ + beq _0804AF12\n\ + cmp r3, 0\n\ + beq _0804AF12\n\ + _0804AEF8:\n\ + ldr r2, [r7]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + adds r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + adds r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + adds r1, r0\n\ + str r1, [r7]\n\ + b _0804AF22\n\ + _0804AF12:\n\ + ldr r0, [r7]\n\ + adds r0, 0x5\n\ + str r0, [r7]\n\ + b _0804AF22\n\ + _0804AF1A:\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x5\n\ + str r0, [r1]\n\ + _0804AF22:\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} + +#endif // NONMATCHING + +static void MoveValuesCleanUp(void) +{ + gBattleMoveFlags = 0; + gBattleScripting.dmgMultiplier = 1; + gCritMultiplier = 1; + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattleCommunication[6] = 0; + gHitMarker &= ~(HITMARKER_DESTINYBOND); + gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); +} + +static void atk25_move_values_cleanup(void) +{ + MoveValuesCleanUp(); + gBattlescriptCurrInstr += 1; +} + +static void atk26_set_multihit(void) +{ + gMultiHitCounter = gBattlescriptCurrInstr[1]; + gBattlescriptCurrInstr += 2; +} + +static void atk27_decrement_multihit(void) +{ + if (--gMultiHitCounter == 0) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); +} + +static void atk28_goto(void) +{ + gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); +} + +static void atk29_jumpifbyte(void) +{ + u8 caseID = gBattlescriptCurrInstr[1]; + const u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); + u8 value = gBattlescriptCurrInstr[6]; + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7); + + gBattlescriptCurrInstr += 11; + + switch (caseID) + { + case CMP_EQUAL: + if (*memByte == value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NOT_EQUAL: + if (*memByte != value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_GREATER_THAN: + if (*memByte > value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_LESS_THAN: + if (*memByte < value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_COMMON_BITS: + if (*memByte & value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NO_COMMON_BITS: + if (!(*memByte & value)) + gBattlescriptCurrInstr = jumpPtr; + break; + } +} + +static void atk2A_jumpifhalfword(void) +{ + u8 caseID = gBattlescriptCurrInstr[1]; + const u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); + u16 value = BS2ScriptRead16(gBattlescriptCurrInstr + 6); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 8); + + gBattlescriptCurrInstr += 12; + + switch (caseID) + { + case CMP_EQUAL: + if (*memHword == value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NOT_EQUAL: + if (*memHword != value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_GREATER_THAN: + if (*memHword > value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_LESS_THAN: + if (*memHword < value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_COMMON_BITS: + if (*memHword & value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NO_COMMON_BITS: + if (!(*memHword & value)) + gBattlescriptCurrInstr = jumpPtr; + break; + } +} + +static void atk2B_jumpifword(void) +{ + u8 caseID = gBattlescriptCurrInstr[1]; + const u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); + u32 value = BSScriptRead32(gBattlescriptCurrInstr + 6); + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); + + gBattlescriptCurrInstr += 14; + + switch (caseID) + { + case CMP_EQUAL: + if (*memWord == value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NOT_EQUAL: + if (*memWord != value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_GREATER_THAN: + if (*memWord > value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_LESS_THAN: + if (*memWord < value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_COMMON_BITS: + if (*memWord & value) + gBattlescriptCurrInstr = jumpPtr; + break; + case CMP_NO_COMMON_BITS: + if (!(*memWord & value)) + gBattlescriptCurrInstr = jumpPtr; + break; + } +} + +static void atk2C_jumpifarrayequal(void) +{ + const u8* mem1 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + const u8* mem2 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); + u32 size = gBattlescriptCurrInstr[9]; + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); + + u8 i; + for (i = 0; i < size; i++) + { + if (*mem1 != *mem2) + { + gBattlescriptCurrInstr += 14; + break; + } + mem1++, mem2++; + } + + if (i == size) + gBattlescriptCurrInstr = jumpPtr; +} + +static void atk2D_jumpifarraynotequal(void) +{ + u8 equalBytes = 0; + const u8* mem1 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + const u8* mem2 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); + u32 size = gBattlescriptCurrInstr[9]; + const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10); + + u8 i; + for (i = 0; i < size; i++) + { + if (*mem1 == *mem2) + { + equalBytes++; + } + mem1++, mem2++; + } + + if (equalBytes != size) + gBattlescriptCurrInstr = jumpPtr; + else + gBattlescriptCurrInstr += 14; +} + +static void atk2E_setbyte(void) +{ + u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + *memByte = gBattlescriptCurrInstr[5]; + + gBattlescriptCurrInstr += 6; +} + +static void atk2F_addbyte(void) +{ + u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + *memByte += gBattlescriptCurrInstr[5]; + gBattlescriptCurrInstr += 6; +} + +static void atk30_subbyte(void) +{ + u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + *memByte -= gBattlescriptCurrInstr[5]; + gBattlescriptCurrInstr += 6; +} + +static void atk31_copyarray(void) +{ + u8* dest = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + const u8* src = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); + s32 size = gBattlescriptCurrInstr[9]; + + s32 i; + for (i = 0; i < size; i++) + { + dest[i] = src[i]; + } + + gBattlescriptCurrInstr += 10; +} + +static void atk32_copyarray_withindex(void) +{ + u8* dest = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + const u8* src = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5); + const u8* index = BS2ScriptReadPtr(gBattlescriptCurrInstr + 9); + s32 size = gBattlescriptCurrInstr[13]; + + s32 i; + for (i = 0; i < size; i++) + { + dest[i] = src[i + *index]; + } + + gBattlescriptCurrInstr += 14; +} + +static void atk33_orbyte(void) +{ + u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + *memByte |= gBattlescriptCurrInstr[5]; + gBattlescriptCurrInstr += 6; +} + +static void atk34_orhalfword(void) +{ + u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + u16 val = BS2ScriptRead16(gBattlescriptCurrInstr + 5); + + *memHword |= val; + gBattlescriptCurrInstr += 7; +} + +static void atk35_orword(void) +{ + u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + u32 val = BS2ScriptRead32(gBattlescriptCurrInstr + 5); + + *memWord |= val; + gBattlescriptCurrInstr += 9; +} + +static void atk36_bicbyte(void) +{ + u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + *memByte &= ~(gBattlescriptCurrInstr[5]); + gBattlescriptCurrInstr += 6; +} + +static void atk37_bichalfword(void) +{ + u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + u16 val = BS2ScriptRead16(gBattlescriptCurrInstr + 5); + + *memHword &= ~val; + gBattlescriptCurrInstr += 7; +} + +static void atk38_bicword(void) +{ + u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1); + u32 val = BS2ScriptRead32(gBattlescriptCurrInstr + 5); + + *memWord &= ~val; + gBattlescriptCurrInstr += 9; +} + +static void atk39_pause(void) +{ + if (gBattleExecBuffer == 0) + { + u16 value = BS2ScriptRead16(gBattlescriptCurrInstr + 1); + if (++gPauseCounterBattle >= value) + { + gPauseCounterBattle = 0; + gBattlescriptCurrInstr += 3; + } + } +} + +static void atk3A_waitstate(void) +{ + if (gBattleExecBuffer == 0) + gBattlescriptCurrInstr++; +} + +static void atk3B_healthbar_update(void) +{ + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + gActiveBank = gBankTarget; + else + gActiveBank = gBankAttacker; + + EmitHealthBarUpdate(0, gBattleMoveDamage); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 2; +} + +static void atk3C_return(void) +{ + BattleScriptPop(); +} + +static void atk3D_end(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_ARENA) + sub_81A5718(gBankAttacker); + + gBattleMoveFlags = 0; + gActiveBank = 0; + gFightStateTracker = 0xB; +} + +static void atk3E_end2(void) +{ + gActiveBank = 0; + gFightStateTracker = 0xB; +} + +static void atk3F_end3(void) // pops the main function stack +{ + BattleScriptPop(); + if (BATTLE_CALLBACKS_STACK->size) + BATTLE_CALLBACKS_STACK->size--; + gBattleMainFunc = BATTLE_CALLBACKS_STACK->function[BATTLE_CALLBACKS_STACK->size]; +} + +static void atk41_call(void) +{ + BattleScriptPush(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); +} + +static void atk42_jumpiftype2(void) +{ + u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + + if (gBattlescriptCurrInstr[2] == gBattleMons[bank].type1 || gBattlescriptCurrInstr[2] == gBattleMons[bank].type2) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 3); + else + gBattlescriptCurrInstr += 7; +} + +static void atk43_jumpifabilitypresent(void) +{ + if (AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, gBattlescriptCurrInstr[1], 0, 0)) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; +} + +static void atk44(void) +{ + *(gBankAttacker + gBattleStruct->field_54) = 1; +} + +static void atk45_playanimation(void) +{ + const u16* argumentPtr; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); + + if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE + || gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE + || gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE) + { + EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 7; + } + else if (gHitMarker & HITMARKER_NO_ANIMATIONS) + { + BattleScriptPush(gBattlescriptCurrInstr + 7); + gBattlescriptCurrInstr = BattleScript_Pausex20; + } + else if (gBattlescriptCurrInstr[2] == B_ANIM_RAIN_CONTINUES + || gBattlescriptCurrInstr[2] == B_ANIM_SUN_CONTINUES + || gBattlescriptCurrInstr[2] == B_ANIM_SANDSTORM_CONTINUES + || gBattlescriptCurrInstr[2] == B_ANIM_HAIL_CONTINUES) + { + EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 7; + } + else if (gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) + { + gBattlescriptCurrInstr += 7; + } + else + { + EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 7; + } +} + +static void atk46_playanimation2(void) // animation Id is stored in the first pointer +{ + const u16* argumentPtr; + const u8* animationIdPtr; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + animationIdPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); + argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); + + if (*animationIdPtr == B_ANIM_STATS_CHANGE + || *animationIdPtr == B_ANIM_SNATCH_MOVE + || *animationIdPtr == B_ANIM_SUBSTITUTE_FADE) + { + EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 10; + } + else if (gHitMarker & HITMARKER_NO_ANIMATIONS) + { + gBattlescriptCurrInstr += 10; + } + else if (*animationIdPtr == B_ANIM_RAIN_CONTINUES + || *animationIdPtr == B_ANIM_SUN_CONTINUES + || *animationIdPtr == B_ANIM_SANDSTORM_CONTINUES + || *animationIdPtr == B_ANIM_HAIL_CONTINUES) + { + EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 10; + } + else if (gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) + { + gBattlescriptCurrInstr += 10; + } + else + { + EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 10; + } +} + +static void atk47_setgraphicalstatchangevalues(void) +{ + u8 value = 0; + switch (gBattleScripting.statChanger & 0xF0) + { + case 0x10: // +1 + value = 0xF; + break; + case 0x20: // +2 + value = 0x27; + break; + case 0x90: // -1 + value = 0x16; + break; + case 0xA0: // -2 + value = 0x2E; + break; + } + gBattleScripting.animArg1 = (gBattleScripting.statChanger & 0xF) + value - 1; + gBattleScripting.animArg2 = 0; + gBattlescriptCurrInstr++; +} + +#ifdef NONMATCHING +static void atk48_playstatchangeanimation(void) +{ + u32 currStat = 0; + s16 statAnimId = 0; + s16 checkingStatAnimId = 0; + s32 changeableStats = 0; + u32 statsToCheck = 0; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + statsToCheck = gBattlescriptCurrInstr[2]; + + if (gBattlescriptCurrInstr[3] & ATK48_STAT_NEGATIVE) // goes down + { + checkingStatAnimId = (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) ? 0x2D : 0x15; + while (statsToCheck != 0) + { + if (statsToCheck & 1) + { + if (!(gBattlescriptCurrInstr[3] & ATK48_LOWER_FAIL_CHECK)) + { + if (gBattleMons[gActiveBank].statStages[currStat] > 0) + { + statAnimId = checkingStatAnimId; + changeableStats++; + } + } + else if (!gSideTimers[GET_BANK_SIDE(gActiveBank)].mistTimer + && gBattleMons[gActiveBank].ability != ABILITY_CLEAR_BODY + && gBattleMons[gActiveBank].ability != ABILITY_WHITE_SMOKE + && !(gBattleMons[gActiveBank].ability == ABILITY_KEEN_EYE && currStat == STAT_STAGE_ACC) + && !(gBattleMons[gActiveBank].ability == ABILITY_HYPER_CUTTER && currStat == STAT_STAGE_ATK)) + { + if (gBattleMons[gActiveBank].statStages[currStat] > 0) + { + statAnimId = checkingStatAnimId; + changeableStats++; + } + } + } + statsToCheck >>= 1, checkingStatAnimId++, currStat++; + } + + if (changeableStats > 1) // more than one stat, so the color is gray + { + if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) + statAnimId = 0x3A; + else + statAnimId = 0x39; + } + } + else // goes up + { + checkingStatAnimId = (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) ? 0x26 : 0xE; + while (statsToCheck != 0) + { + if (statsToCheck & 1 && gBattleMons[gActiveBank].statStages[currStat] < 0xC) + { + statAnimId = checkingStatAnimId; + changeableStats++; + } + statsToCheck >>= 1, checkingStatAnimId += 1, currStat++; + } + + if (changeableStats > 1) // more than one stat, so the color is gray + { + if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) + statAnimId = 0x38; + else + statAnimId = 0x37; + } + } + + if (gBattlescriptCurrInstr[3] & ATK48_BIT_x4 && changeableStats < 2) + { + gBattlescriptCurrInstr += 4; + } + else if (changeableStats != 0 && gBattleScripting.field_1B == 0) + { + EmitBattleAnimation(0, B_ANIM_STATS_CHANGE, statAnimId); + MarkBufferBankForExecution(gActiveBank); + if (gBattlescriptCurrInstr[3] & ATK48_BIT_x4 && changeableStats > 1) + gBattleScripting.field_1B = 1; + gBattlescriptCurrInstr += 4; + } + else + { + gBattlescriptCurrInstr += 4; + } +} +#else +__attribute__((naked)) +static void atk48_playstatchangeanimation(void) +{ + asm("\n\ + .syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x4\n\ + movs r7, 0\n\ + movs r0, 0\n\ + mov r8, r0\n\ + movs r3, 0\n\ + ldr r5, =gBattlescriptCurrInstr\n\ + ldr r0, [r5]\n\ + ldrb r0, [r0, 0x1]\n\ + str r3, [sp]\n\ + bl GetBattleBank\n\ + ldr r2, =gActiveBank\n\ + strb r0, [r2]\n\ + ldr r0, [r5]\n\ + ldrb r4, [r0, 0x2]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + ldr r3, [sp]\n\ + cmp r0, 0\n\ + beq _0804BAEC\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0x15\n\ + cmp r0, 0\n\ + beq _0804BA18\n\ + movs r1, 0x2D\n\ +_0804BA18:\n\ + cmp r4, 0\n\ + beq _0804BAC0\n\ + movs r0, 0x1\n\ + mov r10, r0\n\ + ldr r0, =gBattleMons + 0x18\n\ + mov r9, r0\n\ + lsls r5, r1, 16\n\ +_0804BA26:\n\ + adds r0, r4, 0\n\ + mov r1, r10\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804BAB2\n\ + ldr r0, =gBattlescriptCurrInstr\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x8\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804BA58\n\ + ldr r0, =gActiveBank\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r7, r0\n\ + b _0804BAA0\n\ + .pool\n\ +_0804BA58:\n\ + ldr r6, =gActiveBank\n\ + ldrb r0, [r6]\n\ + str r3, [sp]\n\ + bl GetBankIdentity\n\ + mov r1, r10\n\ + ands r1, r0\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + ldr r1, =gSideTimers\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x4]\n\ + ldr r3, [sp]\n\ + cmp r0, 0\n\ + bne _0804BAB2\n\ + ldr r0, =gBattleMons\n\ + ldrb r2, [r6]\n\ + movs r1, 0x58\n\ + muls r2, r1\n\ + adds r0, r2, r0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x1D\n\ + beq _0804BAB2\n\ + cmp r0, 0x49\n\ + beq _0804BAB2\n\ + cmp r0, 0x33\n\ + bne _0804BA96\n\ + cmp r7, 0x6\n\ + beq _0804BAB2\n\ +_0804BA96:\n\ + cmp r0, 0x34\n\ + bne _0804BA9E\n\ + cmp r7, 0x1\n\ + beq _0804BAB2\n\ +_0804BA9E:\n\ + adds r0, r7, r2\n\ +_0804BAA0:\n\ + add r0, r9\n\ + ldrb r0, [r0]\n\ + lsls r0, 24\n\ + asrs r0, 24\n\ + cmp r0, 0\n\ + ble _0804BAB2\n\ + lsrs r0, r5, 16\n\ + mov r8, r0\n\ + adds r3, 0x1\n\ +_0804BAB2:\n\ + lsrs r4, 1\n\ + movs r1, 0x80\n\ + lsls r1, 9\n\ + adds r5, r1\n\ + adds r7, 0x1\n\ + cmp r4, 0\n\ + bne _0804BA26\n\ +_0804BAC0:\n\ + ldr r0, =gBattlescriptCurrInstr\n\ + mov r9, r0\n\ + cmp r3, 0x1\n\ + ble _0804BB4E\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0x39\n\ + mov r8, r1\n\ + cmp r0, 0\n\ + beq _0804BB4E\n\ + movs r0, 0x3A\n\ + b _0804BB4C\n\ + .pool\n\ +_0804BAEC:\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0xE\n\ + cmp r0, 0\n\ + beq _0804BAF8\n\ + movs r1, 0x26\n\ +_0804BAF8:\n\ + mov r9, r5\n\ + cmp r4, 0\n\ + beq _0804BB34\n\ + ldr r6, =gBattleMons + 0x18\n\ + adds r5, r2, 0\n\ + lsls r2, r1, 16\n\ +_0804BB04:\n\ + movs r0, 0x1\n\ + ands r0, r4\n\ + cmp r0, 0\n\ + beq _0804BB26\n\ + ldrb r1, [r5]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r7, r0\n\ + adds r0, r6\n\ + ldrb r0, [r0]\n\ + lsls r0, 24\n\ + asrs r0, 24\n\ + cmp r0, 0xB\n\ + bgt _0804BB26\n\ + lsrs r1, r2, 16\n\ + mov r8, r1\n\ + adds r3, 0x1\n\ +_0804BB26:\n\ + lsrs r4, 1\n\ + movs r0, 0x80\n\ + lsls r0, 9\n\ + adds r2, r0\n\ + adds r7, 0x1\n\ + cmp r4, 0\n\ + bne _0804BB04\n\ +_0804BB34:\n\ + cmp r3, 0x1\n\ + ble _0804BB4E\n\ + mov r1, r9\n\ + ldr r0, [r1]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0x37\n\ + mov r8, r1\n\ + cmp r0, 0\n\ + beq _0804BB4E\n\ + movs r0, 0x38\n\ +_0804BB4C:\n\ + mov r8, r0\n\ +_0804BB4E:\n\ + mov r1, r9\n\ + ldr r2, [r1]\n\ + ldrb r1, [r2, 0x3]\n\ + movs r0, 0x4\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0804BB6C\n\ + cmp r3, 0x1\n\ + bgt _0804BB6C\n\ + adds r0, r2, 0x4\n\ + mov r1, r9\n\ + b _0804BBBA\n\ + .pool\n\ +_0804BB6C:\n\ + cmp r3, 0\n\ + beq _0804BBB4\n\ + ldr r4, =gBattleScripting\n\ + ldrb r0, [r4, 0x1B]\n\ + cmp r0, 0\n\ + bne _0804BBB4\n\ + movs r0, 0\n\ + movs r1, 0x1\n\ + mov r2, r8\n\ + str r3, [sp]\n\ + bl EmitBattleAnimation\n\ + ldr r0, =gActiveBank\n\ + ldrb r0, [r0]\n\ + bl MarkBufferBankForExecution\n\ + ldr r0, =gBattlescriptCurrInstr\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x4\n\ + ands r0, r1\n\ + ldr r3, [sp]\n\ + cmp r0, 0\n\ + beq _0804BBA4\n\ + cmp r3, 0x1\n\ + ble _0804BBA4\n\ + movs r0, 0x1\n\ + strb r0, [r4, 0x1B]\n\ +_0804BBA4:\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + b _0804BBB6\n\ + .pool\n\ +_0804BBB4:\n\ + mov r1, r9\n\ +_0804BBB6:\n\ + ldr r0, [r1]\n\ + adds r0, 0x4\n\ +_0804BBBA:\n\ + str r0, [r1]\n\ + add sp, 0x4\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided"); +} +#endif // NONMATCHING + +#define ATK49_LAST_CASE 17 + +static void atk49_moveend(void) +{ + s32 i; + bool32 effect; + u8 moveType; + u8 holdEffectAtk; + u16 *choicedMoveAtk; + u8 arg1, arg2; + u16 lastMove; + + effect = FALSE; + + if (gLastUsedMove == 0xFFFF) + lastMove = 0; + else + lastMove = gLastUsedMove; + + arg1 = gBattlescriptCurrInstr[1]; + arg2 = gBattlescriptCurrInstr[2]; + + if (gBattleMons[gBankAttacker].item == ITEM_ENIGMA_BERRY) + holdEffectAtk = gEnigmaBerries[gBankAttacker].holdEffect; + else + holdEffectAtk = ItemId_GetHoldEffect(gBattleMons[gBankAttacker].item); + + choicedMoveAtk = &gBattleStruct->choicedMove[gBankAttacker]; + + GET_MOVE_TYPE(gCurrentMove, moveType); + + do + { + switch (gBattleScripting.atk49_state) + { + case 0: // rage check + if (gBattleMons[gBankTarget].status2 & STATUS2_RAGE + && gBattleMons[gBankTarget].hp != 0 && gBankAttacker != gBankTarget + && GetBankSide(gBankAttacker) != GetBankSide(gBankTarget) + && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT) && TARGET_TURN_DAMAGED + && gBattleMoves[gCurrentMove].power && gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] <= 0xB) + { + gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK]++; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_RageIsBuilding; + effect = TRUE; + } + gBattleScripting.atk49_state++; + break; + case 1: // defrosting check + if (gBattleMons[gBankTarget].status1 & STATUS_FREEZE + && gBattleMons[gBankTarget].hp != 0 && gBankAttacker != gBankTarget + && gSpecialStatuses[gBankTarget].moveturnLostHP_special + && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT) && moveType == TYPE_FIRE) + { + gBattleMons[gBankTarget].status1 &= ~(STATUS_FREEZE); + gActiveBank = gBankTarget; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); + MarkBufferBankForExecution(gActiveBank); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove; + effect = TRUE; + } + gBattleScripting.atk49_state++; + break; + case 2: // target synchronize + if (AbilityBattleEffects(ABILITYEFFECT_SYNCHRONIZE, gBankTarget, 0, 0, 0)) + effect = TRUE; + gBattleScripting.atk49_state++; + break; + case 3: // contact abilities + if (AbilityBattleEffects(ABILITYEFFECT_CONTACT, gBankTarget, 0, 0, 0)) + effect = TRUE; + gBattleScripting.atk49_state++; + break; + case 4: // status immunities + if (AbilityBattleEffects(ABILITYEFFECT_IMMUNITY, 0, 0, 0, 0)) + effect = TRUE; // it loops through all banks, so we increment after its done with all banks + else + gBattleScripting.atk49_state++; + break; + case 5: // attacker synchronize + if (AbilityBattleEffects(ABILITYEFFECT_ATK_SYNCHRONIZE, gBankAttacker, 0, 0, 0)) + effect = TRUE; + gBattleScripting.atk49_state++; + break; + case 6: // update choice band move + if (!(gHitMarker & HITMARKER_OBEYS) || holdEffectAtk != HOLD_EFFECT_CHOICE_BAND + || gLastUsedMove == MOVE_STRUGGLE || (*choicedMoveAtk != 0 && *choicedMoveAtk != 0xFFFF)) + goto LOOP; + if (gLastUsedMove == MOVE_BATON_PASS && !(gBattleMoveFlags & MOVESTATUS_FAILED)) + { + gBattleScripting.atk49_state++; + break; + } + *choicedMoveAtk = gLastUsedMove; + LOOP: + { + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankAttacker].moves[i] == *choicedMoveAtk) + break; + } + if (i == 4) + *choicedMoveAtk = 0; + + gBattleScripting.atk49_state++; + } + break; + case 7: // changed held items + for (i = 0; i < gNoOfAllBanks; i++) + { + u16* changedItem = &gBattleStruct->changedItems[i]; + if (*changedItem != 0) + { + gBattleMons[i].item = *changedItem; + *changedItem = 0; + } + } + gBattleScripting.atk49_state++; + break; + case 11: // item effects for all banks + if (ItemBattleEffects(3, 0, FALSE)) + effect = TRUE; + else + gBattleScripting.atk49_state++; + break; + case 12: // king's rock and shell bell + if (ItemBattleEffects(4, 0, FALSE)) + effect = TRUE; + gBattleScripting.atk49_state++; + break; + case 8: // make attacker sprite invisible + if (gStatuses3[gBankAttacker] & (STATUS3_SEMI_INVULNERABLE) + && gHitMarker & HITMARKER_NO_ANIMATIONS) + { + gActiveBank = gBankAttacker; + EmitSpriteInvisibility(0, TRUE); + MarkBufferBankForExecution(gActiveBank); + gBattleScripting.atk49_state++; + return; + } + gBattleScripting.atk49_state++; + break; + case 9: // make attacker sprite visible + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT + || !(gStatuses3[gBankAttacker] & (STATUS3_SEMI_INVULNERABLE)) + || HasMoveFailed(gBankAttacker)) + { + gActiveBank = gBankAttacker; + EmitSpriteInvisibility(0, FALSE); + MarkBufferBankForExecution(gActiveBank); + gStatuses3[gBankAttacker] &= ~(STATUS3_SEMI_INVULNERABLE); + gSpecialStatuses[gBankAttacker].restoredBankSprite = 1; + gBattleScripting.atk49_state++; + return; + } + gBattleScripting.atk49_state++; + break; + case 10: // make target sprite visible + if (!gSpecialStatuses[gBankTarget].restoredBankSprite && gBankTarget < gNoOfAllBanks + && !(gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE)) + { + gActiveBank = gBankTarget; + EmitSpriteInvisibility(0, FALSE); + MarkBufferBankForExecution(gActiveBank); + gStatuses3[gBankTarget] &= ~(STATUS3_SEMI_INVULNERABLE); + gBattleScripting.atk49_state++; + return; + } + gBattleScripting.atk49_state++; + break; + case 13: // update substitute + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gDisableStructs[i].substituteHP == 0) + gBattleMons[i].status2 &= ~(STATUS2_SUBSTITUTE); + } + gBattleScripting.atk49_state++; + break; + case 14: // This case looks interesting, although I am not certain what it does. Probably fine tunes edge cases. + if (gHitMarker & HITMARKER_PURSUIT_TRAP) + { + gActiveBank = gBankAttacker; + gBankAttacker = gBankTarget; + gBankTarget = gActiveBank; + gHitMarker &= ~(HITMARKER_PURSUIT_TRAP); + } + if (gHitMarker & HITMARKER_ATTACKSTRING_PRINTED) + { + gUnknownMovesUsedByBanks[gBankAttacker] = gLastUsedMove; + } + if (!(gAbsentBankFlags & gBitTable[gBankAttacker]) + && !(gBattleStruct->field_91 & gBitTable[gBankAttacker]) + && gBattleMoves[lastMove].effect != EFFECT_BATON_PASS) + { + if (gHitMarker & HITMARKER_OBEYS) + { + gLastUsedMovesByBanks[gBankAttacker] = gLastUsedMove; + gUnknown_02024260[gBankAttacker] = gCurrentMove; + } + else + { + gLastUsedMovesByBanks[gBankAttacker] = 0xFFFF; + gUnknown_02024260[gBankAttacker] = 0xFFFF; + } + + if (!(gHitMarker & HITMARKER_FAINTED(gBankTarget))) + gUnknown_02024270[gBankTarget] = gBankAttacker; + + if (gHitMarker & HITMARKER_OBEYS && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + if (gLastUsedMove == 0xFFFF) + { + gUnknown_02024250[gBankTarget] = gLastUsedMove; + } + else + { + gUnknown_02024250[gBankTarget] = gCurrentMove; + GET_MOVE_TYPE(gCurrentMove, gUnknown_02024258[gBankTarget]); + } + } + else + { + gUnknown_02024250[gBankTarget] = 0xFFFF; + } + } + gBattleScripting.atk49_state++; + break; + case 15: // mirror move + if (!(gAbsentBankFlags & gBitTable[gBankAttacker]) && !(gBattleStruct->field_91 & gBitTable[gBankAttacker]) + && gBattleMoves[lastMove].flags & FLAG_MIRROR_MOVE_AFFECTED && gHitMarker & HITMARKER_OBEYS + && gBankAttacker != gBankTarget && !(gHitMarker & HITMARKER_FAINTED(gBankTarget)) + && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT)) + { + u8 target, attacker; + + *(gBattleStruct->mirrorMoves + gBankTarget * 2 + 0) = gLastUsedMove; + *(gBattleStruct->mirrorMoves + gBankTarget * 2 + 1) = gLastUsedMove >> 8; + + target = gBankTarget; + attacker = gBankAttacker; + *(attacker * 2 + target * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 0) = gLastUsedMove; + + target = gBankTarget; + attacker = gBankAttacker; + *(attacker * 2 + target * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 1) = gLastUsedMove >> 8; + } + gBattleScripting.atk49_state++; + break; + case 16: // + if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) && gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !gProtectStructs[gBankAttacker].chargingTurn && gBattleMoves[gCurrentMove].target == MOVE_TARGET_BOTH + && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) + { + u8 bank = GetBankByIdentity(GetBankIdentity(gBankTarget) ^ BIT_MON); + if (gBattleMons[bank].hp != 0) + { + gBankTarget = bank; + gHitMarker |= HITMARKER_NO_ATTACKSTRING; + gBattleScripting.atk49_state = 0; + MoveValuesCleanUp(); + BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); + gBattlescriptCurrInstr = gUnknown_082DB87D; + return; + } + else + { + gHitMarker |= HITMARKER_NO_ATTACKSTRING; + } + } + gBattleScripting.atk49_state++; + break; + case ATK49_LAST_CASE: + break; + } + + if (arg1 == 1 && effect == FALSE) + gBattleScripting.atk49_state = ATK49_LAST_CASE; + if (arg1 == 2 && arg2 == gBattleScripting.atk49_state) + gBattleScripting.atk49_state = ATK49_LAST_CASE; + + } while (gBattleScripting.atk49_state != ATK49_LAST_CASE && effect == FALSE); + + if (gBattleScripting.atk49_state == ATK49_LAST_CASE && effect == FALSE) + gBattlescriptCurrInstr += 3; +} + +static void atk4A_typecalc2(void) +{ + u8 flags = 0; + s32 i = 0; + u8 moveType = gBattleMoves[gCurrentMove].type; + + if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND) + { + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gBattleMoveFlags |= (MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED); + gUnknown_02024250[gBankTarget] = 0; + gBattleCommunication[6] = moveType; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else + { + while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + { + break; + } + else + { + i += 3; + continue; + } + } + + if (gTypeEffectiveness[i] == moveType) + { + // check type1 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1) + { + if (gTypeEffectiveness[i + 2] == 0) + { + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + break; + } + if (gTypeEffectiveness[i + 2] == 5) + { + flags |= MOVESTATUS_NOTVERYEFFECTIVE; + } + if (gTypeEffectiveness[i + 2] == 20) + { + flags |= MOVESTATUS_SUPEREFFECTIVE; + } + } + // check type2 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2) + { + if (gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == 0) + { + gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED; + break; + } + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == 5) + { + flags |= MOVESTATUS_NOTVERYEFFECTIVE; + } + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == 20) + { + flags |= MOVESTATUS_SUPEREFFECTIVE; + } + } + } + i += 3; + } + } + + if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD + && !(flags & MOVESTATUS_NOEFFECT) + && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2 + && (!(flags & MOVESTATUS_SUPEREFFECTIVE) || ((flags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE))) + && gBattleMoves[gCurrentMove].power) + { + gLastUsedAbility = ABILITY_WONDER_GUARD; + gBattleMoveFlags |= MOVESTATUS_MISSED; + gUnknown_02024250[gBankTarget] = 0; + gBattleCommunication[6] = 3; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED) + gProtectStructs[gBankAttacker].notEffective = 1; + + gBattlescriptCurrInstr++; +} + +static void atk4B_return_atk_to_ball(void) +{ + gActiveBank = gBankAttacker; + if (!(gHitMarker & HITMARKER_FAINTED(gActiveBank))) + { + EmitReturnPokeToBall(0, 0); + MarkBufferBankForExecution(gActiveBank); + } + gBattlescriptCurrInstr++; +} + +static void atk4C_copy_poke_data(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + gBattlePartyID[gActiveBank] = *(gBattleStruct->field_5C + gActiveBank); + + EmitGetMonData(0, 0, gBitTable[gBattlePartyID[gActiveBank]]); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +static void atk4D_switch_data_update(void) +{ + struct BattlePokemon oldData; + s32 i; + u8 *monData; + + if (gBattleExecBuffer) + return; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + oldData = gBattleMons[gActiveBank]; + monData = (u8*)(&gBattleMons[gActiveBank]); + + for (i = 0; i < sizeof(struct BattlePokemon); i++) + { + monData[i] = gBattleBufferB[gActiveBank][4 + i]; + } + + gBattleMons[gActiveBank].type1 = gBaseStats[gBattleMons[gActiveBank].species].type1; + gBattleMons[gActiveBank].type2 = gBaseStats[gBattleMons[gActiveBank].species].type2; + gBattleMons[gActiveBank].ability = GetAbilityBySpecies(gBattleMons[gActiveBank].species, gBattleMons[gActiveBank].altAbility); + + // check knocked off item + i = GetBankSide(gActiveBank); + if (gWishFutureKnock.knockedOffPokes[i] & gBitTable[gBattlePartyID[gActiveBank]]) + { + gBattleMons[gActiveBank].item = 0; + } + + if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS) + { + for (i = 0; i < 8; i++) + { + gBattleMons[gActiveBank].statStages[i] = oldData.statStages[i]; + } + gBattleMons[gActiveBank].status2 = oldData.status2; + } + + SwitchInClearStructs(); + + if (gBattleTypeFlags & BATTLE_TYPE_PALACE && gBattleMons[gActiveBank].maxHP / 2 >= gBattleMons[gActiveBank].hp + && gBattleMons[gActiveBank].hp != 0 && !(gBattleMons[gActiveBank].status1 & STATUS_SLEEP)) + { + gBattleStruct->field_92 |= gBitTable[gActiveBank]; + } + + gBattleScripting.bank = gActiveBank; + gBattleTextBuff1[0] = PLACEHOLDER_BEGIN; + gBattleTextBuff1[1] = 7; + gBattleTextBuff1[2] = gActiveBank; + gBattleTextBuff1[3] = gBattlePartyID[gActiveBank]; + gBattleTextBuff1[4] = EOS; + + gBattlescriptCurrInstr += 2; +} + +static void atk4E_switchin_anim(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + if (GetBankSide(gActiveBank) == SIDE_OPPONENT + && !(gBattleTypeFlags & (BATTLE_TYPE_LINK + | BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_x2000000 + | BATTLE_TYPE_x4000000 + | BATTLE_TYPE_FRONTIER))) + HandleSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBank].species), FLAG_SET_SEEN, gBattleMons[gActiveBank].personality); + + gAbsentBankFlags &= ~(gBitTable[gActiveBank]); + + EmitSwitchInAnim(0, gBattlePartyID[gActiveBank], gBattlescriptCurrInstr[2]); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 3; + + if (gBattleTypeFlags & BATTLE_TYPE_ARENA) + sub_81A56B4(); +} + +static void atk4F_jump_if_cannot_switch(void) +{ + s32 val = 0; + s32 compareVar = 0; + struct Pokemon *party = NULL; + s32 r7 = 0; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1] & ~(ATK4F_DONT_CHECK_STATUSES)); + + if (!(gBattlescriptCurrInstr[1] & ATK4F_DONT_CHECK_STATUSES) + && ((gBattleMons[gActiveBank].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) + || (gStatuses3[gActiveBank] & STATUS3_ROOTED))) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + } + else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) + { + #ifndef NONMATCHING + asm("":::"r5"); + #endif // NONMATCHING + if (GetBankSide(gActiveBank) == SIDE_OPPONENT) + party = gEnemyParty; + else + party = gPlayerParty; + + val = 0; + if (2 & gActiveBank) + val = 3; + + for (compareVar = val + 3; val < compareVar; val++) + { + if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[val], MON_DATA_IS_EGG) + && GetMonData(&party[val], MON_DATA_HP) != 0 + && gBattlePartyID[gActiveBank] != val) + break; + } + + if (val == compareVar) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + } + else if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (gBattleTypeFlags & BATTLE_TYPE_x800000) + { + if (GetBankSide(gActiveBank) == SIDE_PLAYER) + { + party = gPlayerParty; + + val = 0; + if (sub_806D82C(sub_806D864(gActiveBank)) == TRUE) + val = 3; + } + else + { + party = gEnemyParty; + + if (gActiveBank == 1) + val = 0; + else + val = 3; + } + } + else + { + if (GetBankSide(gActiveBank) == SIDE_OPPONENT) + party = gEnemyParty; + else + party = gPlayerParty; + + + val = 0; + if (sub_806D82C(sub_806D864(gActiveBank)) == TRUE) + val = 3; + } + + for (compareVar = val + 3; val < compareVar; val++) + { + if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[val], MON_DATA_IS_EGG) + && GetMonData(&party[val], MON_DATA_HP) != 0 + && gBattlePartyID[gActiveBank] != val) + break; + } + + if (val == compareVar) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + } + else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && GetBankSide(gActiveBank) == SIDE_OPPONENT) + { + party = gEnemyParty; + + val = 0; + if (gActiveBank == 3) + val = 3; + + for (compareVar = val + 3; val < compareVar; val++) + { + if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[val], MON_DATA_IS_EGG) + && GetMonData(&party[val], MON_DATA_HP) != 0 + && gBattlePartyID[gActiveBank] != val) + break; + } + + if (val == compareVar) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + } + else + { + if (GetBankSide(gActiveBank) == SIDE_OPPONENT) + { + r7 = GetBankByIdentity(1); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + compareVar = GetBankByIdentity(3); + else + compareVar = r7; + + party = gEnemyParty; + } + else + { + r7 = GetBankByIdentity(0); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + compareVar = GetBankByIdentity(2); + else + compareVar = r7; + + party = gPlayerParty; + } + for (val = 0; val < 6; val++) + { + if (GetMonData(&party[val], MON_DATA_HP) != 0 + && GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[val], MON_DATA_IS_EGG) + && val != gBattlePartyID[r7] && val != gBattlePartyID[compareVar]) + break; + } + + if (val == 6) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + } +} + +static void sub_804CF10(u8 arg0) +{ + *(gBattleStruct->field_58 + gActiveBank) = gBattlePartyID[gActiveBank]; + *(gBattleStruct->field_5C + gActiveBank) = 6; + gBattleStruct->field_93 &= ~(gBitTable[gActiveBank]); + + EmitChoosePokemon(0, 1, arg0, 0, gBattleStruct->field_60[gActiveBank]); + MarkBufferBankForExecution(gActiveBank); +} + +static void atk50_openpartyscreen(void) +{ + u32 flags; + u8 hitmarkerFaintBits; + u8 bank; + const u8 *jumpPtr; + + bank = 0; + flags = 0; + jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + + if (gBattlescriptCurrInstr[1] == 5) + { + if ((gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI)) != BATTLE_TYPE_DOUBLE) + { + for (gActiveBank = 0; gActiveBank < gNoOfAllBanks; gActiveBank++) + { + if (gHitMarker & HITMARKER_FAINTED(gActiveBank)) + { + if (sub_80423F4(gActiveBank, 6, 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(6); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + } + else + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + u8 flag40_0, flag40_1, flag40_2, flag40_3; + + hitmarkerFaintBits = gHitMarker >> 0x1C; + + if (gBitTable[0] & hitmarkerFaintBits) + { + gActiveBank = 0; + if (sub_80423F4(0, 6, 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[2]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + else + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + flags |= 1; + } + } + if (gBitTable[2] & hitmarkerFaintBits && !(gBitTable[0] & hitmarkerFaintBits)) + { + gActiveBank = 2; + if (sub_80423F4(2, 6, 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[0]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + else if (!(flags & 1)) + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + if (gBitTable[1] & hitmarkerFaintBits) + { + gActiveBank = 1; + if (sub_80423F4(1, 6, 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[3]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + else + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + flags |= 2; + } + } + if (gBitTable[3] & hitmarkerFaintBits && !(gBitTable[1] & hitmarkerFaintBits)) + { + gActiveBank = 3; + if (sub_80423F4(3, 6, 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[1]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + else if (!(flags & 2)) + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + + flag40_0 = gSpecialStatuses[0].flag40; + if (!flag40_0) + { + flag40_2 = gSpecialStatuses[2].flag40; + if (!flag40_2 && hitmarkerFaintBits != 0) + { + if (gAbsentBankFlags & gBitTable[0]) + gActiveBank = 2; + else + gActiveBank = 0; + + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + + } + flag40_1 = gSpecialStatuses[1].flag40; + if (!flag40_1) + { + flag40_3 = gSpecialStatuses[3].flag40; + if (!flag40_3 && hitmarkerFaintBits != 0) + { + if (gAbsentBankFlags & gBitTable[1]) + gActiveBank = 3; + else + gActiveBank = 1; + + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + } + gBattlescriptCurrInstr += 6; + } + else if (gBattlescriptCurrInstr[1] == 6) + { + if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + hitmarkerFaintBits = gHitMarker >> 0x1C; + if (gBitTable[2] & hitmarkerFaintBits && gBitTable[0] & hitmarkerFaintBits) + { + gActiveBank = 2; + if (sub_80423F4(2, gBattleBufferB[0][1], 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[0]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + } + if (gBitTable[3] & hitmarkerFaintBits && hitmarkerFaintBits & gBitTable[1]) + { + gActiveBank = 3; + if (sub_80423F4(3, gBattleBufferB[1][1], 6)) + { + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + Emit_x2A(0); + MarkBufferBankForExecution(gActiveBank); + } + else if (!gSpecialStatuses[gActiveBank].flag40) + { + sub_804CF10(gBattleStruct->field_5C[1]); + gSpecialStatuses[gActiveBank].flag40 = 1; + } + } + gBattlescriptCurrInstr += 6; + } + else + { + gBattlescriptCurrInstr += 6; + } + } + else + { + gBattlescriptCurrInstr += 6; + } + + hitmarkerFaintBits = gHitMarker >> 0x1C; + + gBank1 = 0; + while (1) + { + if (gBitTable[gBank1] & hitmarkerFaintBits) + break; + if (gBank1 >= gNoOfAllBanks) + break; + gBank1++; + } + + if (gBank1 == gNoOfAllBanks) + gBattlescriptCurrInstr = jumpPtr; + } + else + { + if (gBattlescriptCurrInstr[1] & 0x80) + hitmarkerFaintBits = 0; // used here as the caseId for the EmitChoose function + else + hitmarkerFaintBits = 1; + + bank = GetBattleBank(gBattlescriptCurrInstr[1] & ~(0x80)); + if (gSpecialStatuses[bank].flag40) + { + gBattlescriptCurrInstr += 6; + } + else if (sub_80423F4(bank, 6, 6)) + { + gActiveBank = bank; + gAbsentBankFlags |= gBitTable[gActiveBank]; + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + gBattlescriptCurrInstr = jumpPtr; + } + else + { + gActiveBank = bank; + *(gBattleStruct->field_58 + gActiveBank) = gBattlePartyID[gActiveBank]; + *(gBattleStruct->field_5C + gActiveBank) = 6; + gBattleStruct->field_93 &= ~(gBitTable[gActiveBank]); + + EmitChoosePokemon(0, hitmarkerFaintBits, *(gBattleStruct->field_5C + (gActiveBank ^ 2)), 0, gBattleStruct->field_60[gActiveBank]); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 6; + + if (GetBankIdentity(gActiveBank) == 0 && gBattleResults.playerSwitchesCounter < 0xFF) + gBattleResults.playerSwitchesCounter++; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + for (gActiveBank = 0; gActiveBank < gNoOfAllBanks; gActiveBank++) + { + if (gActiveBank != bank) + { + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + } + else + { + gActiveBank = GetBankByIdentity(GetBankIdentity(bank) ^ BIT_SIDE); + if (gAbsentBankFlags & gBitTable[gActiveBank]) + gActiveBank ^= BIT_MON; + + EmitLinkStandbyMsg(0, 2, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + } +} + +static void atk51_switch_handle_order(void) +{ + s32 i; + if (gBattleExecBuffer) + return; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + switch (gBattlescriptCurrInstr[2]) + { + case 0: + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleBufferB[i][0] == 0x22) + { + *(gBattleStruct->field_5C + i) = gBattleBufferB[i][1]; + if (!(gBattleStruct->field_93 & gBitTable[i])) + { + RecordedBattle_SetBankAction(i, gBattleBufferB[i][1]); + gBattleStruct->field_93 |= gBitTable[i]; + } + } + } + break; + case 1: + if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + sub_803BDA0(gActiveBank); + break; + case 2: + if (!(gBattleStruct->field_93 & gBitTable[gActiveBank])) + { + RecordedBattle_SetBankAction(gActiveBank, gBattleBufferB[gActiveBank][1]); + gBattleStruct->field_93 |= gBitTable[gActiveBank]; + } + // fall through + case 3: + gBattleCommunication[0] = gBattleBufferB[gActiveBank][1]; + *(gBattleStruct->field_5C + gActiveBank) = gBattleBufferB[gActiveBank][1]; + + if ((gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_LINK)) == (BATTLE_TYPE_MULTI | BATTLE_TYPE_LINK)) + { + *(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 0) &= 0xF; + *(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBank][2] & 0xF0); + *(gActiveBank * 3 + (u8*)(gBattleStruct->field_60) + 1) = gBattleBufferB[gActiveBank][3]; + + *((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 0) &= (0xF0); + *((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBank][2] & 0xF0) >> 4; + *((gActiveBank ^ 2) * 3 + (u8*)(gBattleStruct->field_60) + 2) = gBattleBufferB[gActiveBank][3]; + } + else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) + { + sub_80571DC(gActiveBank, *(gBattleStruct->field_5C + gActiveBank)); + } + else + { + sub_803BDA0(gActiveBank); + } + + PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBankAttacker].species) + PREPARE_MON_NICK_BUFFER(gBattleTextBuff2, gActiveBank, gBattleBufferB[gActiveBank][1]) + + break; + } + + gBattlescriptCurrInstr += 3; +} + +static void atk52_switch_in_effects(void) +{ + s32 i; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + sub_803FA70(gActiveBank); + + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank)); + gSpecialStatuses[gActiveBank].flag40 = 0; + + if (!(gSideAffecting[GetBankSide(gActiveBank)] & SIDE_STATUS_SPIKES_DAMAGED) + && (gSideAffecting[GetBankSide(gActiveBank)] & SIDE_STATUS_SPIKES) + && gBattleMons[gActiveBank].type1 != TYPE_FLYING + && gBattleMons[gActiveBank].type2 != TYPE_FLYING + && gBattleMons[gActiveBank].ability != ABILITY_LEVITATE) + { + u8 spikesDmg; + + gSideAffecting[GetBankSide(gActiveBank)] |= SIDE_STATUS_SPIKES_DAMAGED; + + gBattleMons[gActiveBank].status2 &= ~(STATUS2_DESTINY_BOND); + gHitMarker &= ~(HITMARKER_DESTINYBOND); + + spikesDmg = (5 - gSideTimers[GetBankSide(gActiveBank)].spikesAmount) * 2; + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / (spikesDmg); + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattleScripting.bank = gActiveBank; + BattleScriptPushCursor(); + + if (gBattlescriptCurrInstr[1] == 0) + gBattlescriptCurrInstr = gUnknown_082DAE90; + else if (gBattlescriptCurrInstr[1] == 1) + gBattlescriptCurrInstr = gUnknown_082DAE59; + else + gBattlescriptCurrInstr = gUnknown_082DAEC7; + } + else + { + if (gBattleMons[gActiveBank].ability == ABILITY_TRUANT && !gDisableStructs[gActiveBank].truantUnknownBit) + gDisableStructs[gActiveBank].truantCounter = 1; + + gDisableStructs[gActiveBank].truantUnknownBit = 0; + + if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBank, 0, 0, 0) == 0 && + ItemBattleEffects(0, gActiveBank, 0) == 0) + { + gSideAffecting[GetBankSide(gActiveBank)] &= ~(SIDE_STATUS_SPIKES_DAMAGED); + + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gTurnOrder[i] == gActiveBank) + gUnknown_0202407A[i] = 0xC; + } + + for (i = 0; i < gNoOfAllBanks; i++) + { + u16* hpOnSwitchout = &gBattleStruct->hpOnSwitchout[GetBankSide(i)]; + *hpOnSwitchout = gBattleMons[i].hp; + } + + if (gBattlescriptCurrInstr[1] == 5) + { + u32 hitmarkerFaintBits = gHitMarker >> 0x1C; + + gBank1++; + while (1) + { + if (hitmarkerFaintBits & gBitTable[gBank1] && !(gAbsentBankFlags & gBitTable[gBank1])) + break; + if (gBank1 >= gNoOfAllBanks) + break; + gBank1++; + } + } + gBattlescriptCurrInstr += 2; + } + } +} + +static void atk53_trainer_slide(void) +{ + gActiveBank = GetBankByIdentity(gBattlescriptCurrInstr[1]); + EmitTrainerSlide(0); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +static void atk54_effectiveness_sound(void) +{ + gActiveBank = gBankAttacker; + EmitEffectivenessSound(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1)); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 3; +} + +static void atk55_play_sound(void) +{ + gActiveBank = gBankAttacker; + EmitPlaySound(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1), 0); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 3; +} + +static void atk56_fainting_cry(void) +{ + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + EmitFaintingCry(0); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +static void atk57(void) +{ + gActiveBank = GetBankByIdentity(0); + Emit_x37(0, gBattleOutcome); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 1; +} + +static void atk58_return_to_ball(void) +{ + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + EmitReturnPokeToBall(0, 1); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +static void atk59_learnmove_inbattle(void) +{ + const u8* jumpPtr1 = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + const u8* jumpPtr2 = BSScriptReadPtr(gBattlescriptCurrInstr + 5); + + u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], gBattlescriptCurrInstr[9]); + while (ret == 0xFFFE) + ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], 0); + + if (ret == 0) + { + gBattlescriptCurrInstr = jumpPtr2; + } + else if (ret == 0xFFFF) + { + gBattlescriptCurrInstr += 10; + } + else + { + gActiveBank = GetBankByIdentity(0); + + if (gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId + && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) + { + GiveMoveToBattleMon(&gBattleMons[gActiveBank], ret); + } + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + gActiveBank = GetBankByIdentity(2); + if (gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId + && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) + { + GiveMoveToBattleMon(&gBattleMons[gActiveBank], ret); + } + } + + gBattlescriptCurrInstr = jumpPtr1; + } +} + +static void atk5A_yesnoboxlearnmove(void) +{ + gActiveBank = 0; + + switch (gBattleScripting.learnMoveState) + { + case 0: + sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); + sub_814F9EC(gText_BattleYesNoChoice, 0xC); + gBattleScripting.learnMoveState++; + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 1; + BattleCreateCursorAt(1); + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (gBattleCommunication[1] == 0) + { + sub_8056A3C(0x18, 0x8, 0x1D, 0xD, 1); + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + gBattleScripting.learnMoveState++; + } + else + { + gBattleScripting.learnMoveState = 5; + } + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gBattleScripting.learnMoveState = 5; + } + break; + case 2: + if (!gPaletteFade.active) + { + FreeAllWindowBuffers(); + sub_81BFA38(gPlayerParty, gBattleStruct->expGetterId, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, gMoveToLearn); + gBattleScripting.learnMoveState++; + } + break; + case 3: + if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2) + { + gBattleScripting.learnMoveState++; + } + break; + case 4: + if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2) + { + u8 movePosition = sub_81C1B94(); + if (movePosition == 4) + { + gBattleScripting.learnMoveState = 5; + } + else + { + u16 moveId = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MOVE1 + movePosition); + if (IsHMMove2(moveId)) + { + PrepareStringBattle(0x13F, gActiveBank); + gBattleScripting.learnMoveState = 6; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + PREPARE_MOVE_BUFFER(gBattleTextBuff2, moveId) + + RemoveMonPPBonus(&gPlayerParty[gBattleStruct->expGetterId], movePosition); + SetMonMoveSlot(&gPlayerParty[gBattleStruct->expGetterId], gMoveToLearn, movePosition); + + if (gBattlePartyID[0] == gBattleStruct->expGetterId + && !(gBattleMons[0].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[0].unk18_b & gBitTable[movePosition])) + { + RemoveBattleMonPPBonus(&gBattleMons[0], movePosition); + SetBattleMonMoveSlot(&gBattleMons[0], gMoveToLearn, movePosition); + } + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && gBattlePartyID[2] == gBattleStruct->expGetterId + && !(gBattleMons[2].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[2].unk18_b & gBitTable[movePosition])) + { + RemoveBattleMonPPBonus(&gBattleMons[2], movePosition); + SetBattleMonMoveSlot(&gBattleMons[2], gMoveToLearn, movePosition); + } + } + } + } + break; + case 5: + sub_8056A3C(0x18, 8, 0x1D, 0xD, 1); + gBattlescriptCurrInstr += 5; + break; + case 6: + if (gBattleExecBuffer == 0) + { + gBattleScripting.learnMoveState = 2; + } + break; + } +} + +static void atk5B_yesnoboxstoplearningmove(void) +{ + switch (gBattleScripting.learnMoveState) + { + case 0: + sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); + sub_814F9EC(gText_BattleYesNoChoice, 0xC); + gBattleScripting.learnMoveState++; + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 1; + BattleCreateCursorAt(1); + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + + if (gBattleCommunication[1] != 0) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; + + sub_8056A3C(0x18, 0x8, 0x1D, 0xD, 1); + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + sub_8056A3C(0x18, 0x8, 0x1D, 0xD, 1); + } + break; + } +} + +static void atk5C_hitanimation(void) +{ + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) + { + gBattlescriptCurrInstr += 2; + } + else if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE) || !(gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE) || gDisableStructs[gActiveBank].substituteHP == 0) + { + EmitHitAnimation(0); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 2; + } + else + { + gBattlescriptCurrInstr += 2; + } +} + +static u32 GetTrainerMoneyToGive(u16 trainerId) +{ + u32 i = 0; + u32 lastMonLevel = 0; + u32 moneyReward = 0; + + if (trainerId == SECRET_BASE_OPPONENT) + { + moneyReward = 20 * gBattleResources->secretBase->partyLevels[0] * gBattleStruct->moneyMultiplier; + } + else + { + switch (gTrainers[trainerId].partyFlags) + { + case 0: + { + const struct TrainerMonNoItemDefaultMoves *party = gTrainers[trainerId].party.NoItemDefaultMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + case PARTY_FLAG_CUSTOM_MOVES: + { + const struct TrainerMonNoItemCustomMoves *party = gTrainers[trainerId].party.NoItemCustomMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + case PARTY_FLAG_HAS_ITEM: + { + const struct TrainerMonItemDefaultMoves *party = gTrainers[trainerId].party.ItemDefaultMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + case PARTY_FLAG_CUSTOM_MOVES | PARTY_FLAG_HAS_ITEM: + { + const struct TrainerMonItemCustomMoves *party = gTrainers[trainerId].party.ItemCustomMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + } + + for (; gTrainerMoneyTable[i].classId != 0xFF; i++) + { + if (gTrainerMoneyTable[i].classId == gTrainers[trainerId].trainerClass) + break; + } + + if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * gTrainerMoneyTable[i].value; + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * 2 * gTrainerMoneyTable[i].value; + else + moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * gTrainerMoneyTable[i].value; + } + + return moneyReward; +} + +static void atk5D_getmoneyreward(void) +{ + u32 moneyReward = GetTrainerMoneyToGive(gTrainerBattleOpponent_A); + if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + moneyReward += GetTrainerMoneyToGive(gTrainerBattleOpponent_B); + + AddMoney(&gSaveBlock1Ptr->money, moneyReward); + + PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff1, 5, moneyReward) + + gBattlescriptCurrInstr++; +} + +static void atk5E_8025A70(void) +{ + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + switch (gBattleCommunication[0]) + { + case 0: + EmitGetMonData(0, REQUEST_ALL_BATTLE, 0); + MarkBufferBankForExecution(gActiveBank); + gBattleCommunication[0]++; + break; + case 1: + if (gBattleExecBuffer == 0) + { + s32 i; + struct BattlePokemon* bufferPoke = (struct BattlePokemon*) &gBattleBufferB[gActiveBank][4]; + for (i = 0; i < 4; i++) + { + gBattleMons[gActiveBank].moves[i] = bufferPoke->moves[i]; + gBattleMons[gActiveBank].pp[i] = bufferPoke->pp[i]; + } + gBattlescriptCurrInstr += 2; + } + break; + } +} + +static void atk5F_8025B24(void) +{ + gActiveBank = gBankAttacker; + gBankAttacker = gBankTarget; + gBankTarget = gActiveBank; + + if (gHitMarker & HITMARKER_PURSUIT_TRAP) + gHitMarker &= ~(HITMARKER_PURSUIT_TRAP); + else + gHitMarker |= HITMARKER_PURSUIT_TRAP; + + gBattlescriptCurrInstr++; +} + +static void atk60_increment_gamestat(void) +{ + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + IncrementGameStat(gBattlescriptCurrInstr[1]); + + gBattlescriptCurrInstr += 2; +} + +static void atk61_8025BA4(void) +{ + s32 i; + struct Pokemon* party; + struct HpAndStatus hpStatuses[6]; + + if (gBattleExecBuffer) + return; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + if (GetBankSide(gActiveBank) == SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + for (i = 0; i < 6; i++) + { + if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_NONE + || GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG) + { + hpStatuses[i].hp = 0xFFFF; + hpStatuses[i].status = 0; + } + else + { + hpStatuses[i].hp = GetMonData(&party[i], MON_DATA_HP); + hpStatuses[i].status = GetMonData(&party[i], MON_DATA_STATUS); + } + } + + EmitCmd48(0, hpStatuses, 1); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +static void atk62_08025C6C(void) +{ + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + EmitCmd49(0); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +static void atk63_jumptorandomattack(void) +{ + if (gBattlescriptCurrInstr[1] != 0) + gCurrentMove = gRandomMove; + else + gLastUsedMove = gCurrentMove = gRandomMove; + + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; +} + +static void atk64_statusanimation(void) +{ + if (gBattleExecBuffer == 0) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) + && gDisableStructs[gActiveBank].substituteHP == 0 + && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) + { + EmitStatusAnimation(0, FALSE, gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + } + gBattlescriptCurrInstr += 2; + } +} + +static void atk65_status2animation(void) +{ + u32 wantedToAnimate; + + if (gBattleExecBuffer == 0) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + wantedToAnimate = BSScriptRead32(gBattlescriptCurrInstr + 2); + if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) + && gDisableStructs[gActiveBank].substituteHP == 0 + && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) + { + EmitStatusAnimation(0, TRUE, gBattleMons[gActiveBank].status2 & wantedToAnimate); + MarkBufferBankForExecution(gActiveBank); + } + gBattlescriptCurrInstr += 6; + } +} + +static void atk66_chosenstatusanimation(void) +{ + u32 wantedStatus; + + if (gBattleExecBuffer == 0) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + wantedStatus = BSScriptRead32(gBattlescriptCurrInstr + 3); + if (!(gStatuses3[gActiveBank] & STATUS3_SEMI_INVULNERABLE) + && gDisableStructs[gActiveBank].substituteHP == 0 + && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) + { + EmitStatusAnimation(0, gBattlescriptCurrInstr[2], wantedStatus); + MarkBufferBankForExecution(gActiveBank); + } + gBattlescriptCurrInstr += 7; + } +} + +static void atk67_yesnobox(void) +{ + switch (gBattleCommunication[0]) + { + case 0: + sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); + sub_814F9EC(gText_BattleYesNoChoice, 0xC); + gBattleCommunication[0]++; + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 1; + BattleCreateCursorAt(1); + } + if (gMain.newKeys & B_BUTTON) + { + gBattleCommunication[CURSOR_POSITION] = 1; + PlaySE(SE_SELECT); + sub_8056A3C(0x18, 8, 0x1D, 0xD, 1); + gBattlescriptCurrInstr++; + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + sub_8056A3C(0x18, 8, 0x1D, 0xD, 1); + gBattlescriptCurrInstr++; + } + break; + } +} + +static void atk68_80246A0(void) +{ + s32 i; + + for (i = 0; i < gNoOfAllBanks; i++) + gUnknown_0202407A[i] = 0xC; + + gBattlescriptCurrInstr++; +} + +static void atk69_dmg_adjustment3(void) // The same as 0x7, except there's no random damage multiplier. +{ + u8 holdEffect, quality; + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + { + RecordItemEffectBattle(gBankTarget, holdEffect); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + goto END; + if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE && !gProtectStructs[gBankTarget].endured + && !gSpecialStatuses[gBankTarget].focusBanded) + goto END; + + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + goto END; + + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + + if (gProtectStructs[gBankTarget].endured) + { + gBattleMoveFlags |= MOVESTATUS_ENDURED; + } + else if (gSpecialStatuses[gBankTarget].focusBanded) + { + gBattleMoveFlags |= MOVESTATUS_HUNGON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + + END: + gBattlescriptCurrInstr++; +} + +static void atk6A_removeitem(void) +{ + u16* usedHeldItem; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBank]; + *usedHeldItem = gBattleMons[gActiveBank].item; + gBattleMons[gActiveBank].item = 0; + + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBank].item); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +static void atk6B_atknameinbuff1(void) +{ + PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBankAttacker, gBattlePartyID[gBankAttacker]) + + gBattlescriptCurrInstr++; +} + +static void atk6C_draw_lvlupbox(void) +{ + if (gBattleScripting.atk6C_state == 0) + { + if (IsMonGettingExpSentOut()) + gBattleScripting.atk6C_state = 3; + else + gBattleScripting.atk6C_state = 1; + } + + switch (gBattleScripting.atk6C_state) + { + case 1: + gBattle_BG2_Y = 0x60; + SetBgAttribute(2, BG_CTRL_ATTR_MOSAIC, 0); + ShowBg(2); + sub_804F17C(); + gBattleScripting.atk6C_state = 2; + break; + case 2: + if (!sub_804F1CC()) + gBattleScripting.atk6C_state = 3; + break; + case 3: + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0x100; + SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 1); + SetBgAttribute(1, BG_CTRL_ATTR_MOSAIC, 0); + ShowBg(0); + ShowBg(1); + sub_8056A3C(0x12, 7, 0x1D, 0x13, 0x80); + gBattleScripting.atk6C_state = 4; + break; + case 4: + sub_804F100(); + PutWindowTilemap(13); + CopyWindowToVram(13, 3); + gBattleScripting.atk6C_state++; + break; + case 5: + case 7: + if (!IsDma3ManagerBusyWithBgCopy()) + { + gBattle_BG1_Y = 0; + gBattleScripting.atk6C_state++; + } + break; + case 6: + if (gMain.newKeys != 0) + { + PlaySE(SE_SELECT); + sub_804F144(); + CopyWindowToVram(13, 2); + gBattleScripting.atk6C_state++; + } + break; + case 8: + if (gMain.newKeys != 0) + { + PlaySE(SE_SELECT); + sub_8056A3C(0x12, 7, 0x1D, 0x13, 0x81); + gBattleScripting.atk6C_state++; + } + break; + case 9: + if (!sub_804F344()) + { + ClearWindowTilemap(14); + CopyWindowToVram(14, 1); + + ClearWindowTilemap(13); + CopyWindowToVram(13, 1); + + SetBgAttribute(2, BG_CTRL_ATTR_MOSAIC, 2); + ShowBg(2); + + gBattleScripting.atk6C_state = 10; + } + break; + case 10: + if (!IsDma3ManagerBusyWithBgCopy()) + { + SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 0); + SetBgAttribute(1, BG_CTRL_ATTR_MOSAIC, 1); + ShowBg(0); + ShowBg(1); + gBattlescriptCurrInstr++; + } + break; + } +} + +static void sub_804F100(void) +{ + struct StatsArray currentStats; + + sub_81D388C(&gPlayerParty[gBattleStruct->expGetterId], ¤tStats); + sub_81D3640(0xD, gBattleResources->statsBeforeLvlUp, ¤tStats, 0xE, 0xD, 0xF); +} + +static void sub_804F144(void) +{ + struct StatsArray currentStats; + + sub_81D388C(&gPlayerParty[gBattleStruct->expGetterId], ¤tStats); + sub_81D3784(0xD, ¤tStats, 0xE, 0xD, 0xF); +} + +static void sub_804F17C(void) +{ + gBattle_BG2_Y = 0; + gBattle_BG2_X = 0x1A0; + + LoadPalette(sUnknown_0831C2C8, 0x60, 0x20); + CopyToWindowPixelBuffer(14, sUnknown_0831C2E8, 0, 0); + PutWindowTilemap(14); + CopyWindowToVram(14, 3); + + PutMonIconOnLvlUpBox(); +} + +static bool8 sub_804F1CC(void) +{ + if (IsDma3ManagerBusyWithBgCopy()) + return TRUE; + + if (gBattle_BG2_X == 0x200) + return FALSE; + + if (gBattle_BG2_X == 0x1A0) + PutLevelAndGenderOnLvlUpBox(); + + gBattle_BG2_X += 8; + if (gBattle_BG2_X >= 0x200) + gBattle_BG2_X = 0x200; + + return (gBattle_BG2_X != 0x200); +} + +static void PutLevelAndGenderOnLvlUpBox(void) +{ + u16 monLevel; + u8 monGender; + struct TextSubPrinter subPrinter; + u8 *txtPtr; + u32 var; + + monLevel = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); + monGender = GetMonGender(&gPlayerParty[gBattleStruct->expGetterId]); + GetMonNickname(&gPlayerParty[gBattleStruct->expGetterId], gStringVar4); + + subPrinter.current_text_offset = gStringVar4; + subPrinter.windowId = 14; + subPrinter.fontId = 0; + subPrinter.x = 32; + subPrinter.y = 0; + subPrinter.currentX = 32; + subPrinter.currentY = 0; + subPrinter.letterSpacing = 0; + subPrinter.lineSpacing = 0; + subPrinter.fontColor_l = TEXT_COLOR_TRANSPARENT; + subPrinter.fontColor_h = TEXT_COLOR_WHITE; + subPrinter.bgColor = TEXT_COLOR_TRANSPARENT; + subPrinter.shadowColor = TEXT_COLOR_DARK_GREY; + + AddTextPrinter(&subPrinter, 0xFF, NULL); + + txtPtr = gStringVar4; + gStringVar4[0] = CHAR_SPECIAL_F9; + txtPtr++; + txtPtr[0] = 5; + txtPtr++; + + var = (u32)(txtPtr); + txtPtr = ConvertIntToDecimalStringN(txtPtr, monLevel, STR_CONV_MODE_LEFT_ALIGN, 3); + var = (u32)(txtPtr) - var; + txtPtr = StringFill(txtPtr, 0x77, 4 - var); + + if (monGender != MON_GENDERLESS) + { + if (monGender == MON_MALE) + { + txtPtr = WriteColorChangeControlCode(txtPtr, 0, 0xC); + txtPtr = WriteColorChangeControlCode(txtPtr, 1, 0xD); + *(txtPtr++) = CHAR_MALE; + } + else + { + txtPtr = WriteColorChangeControlCode(txtPtr, 0, 0xE); + txtPtr = WriteColorChangeControlCode(txtPtr, 1, 0xF); + *(txtPtr++) = CHAR_FEMALE; + } + *(txtPtr++) = EOS; + } + + subPrinter.y = 10; + subPrinter.currentY = 10; + AddTextPrinter(&subPrinter, 0xFF, NULL); + + CopyWindowToVram(14, 2); +} + +static bool8 sub_804F344(void) +{ + if (gBattle_BG2_X == 0x1A0) + return FALSE; + + if (gBattle_BG2_X - 16 < 0x1A0) + gBattle_BG2_X = 0x1A0; + else + gBattle_BG2_X -= 16; + + return (gBattle_BG2_X != 0x1A0); +} + +#define sDestroy data0 +#define sSavedLvlUpBoxXPosition data1 + +static void PutMonIconOnLvlUpBox(void) +{ + u8 spriteId; + const u16* iconPal; + struct SpriteSheet iconSheet; + struct SpritePalette iconPalSheet; + + u16 species = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPECIES); + u32 personality = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_PERSONALITY); + + const u8* iconPtr = GetMonIconPtr(species, personality, 1); + iconSheet.data = iconPtr; + iconSheet.size = 0x200; + iconSheet.tag = MON_ICON_LVLUP_BOX_TAG; + + iconPal = GetValidMonIconPalettePtr(species); + iconPalSheet.data = iconPal; + iconPalSheet.tag = MON_ICON_LVLUP_BOX_TAG; + + LoadSpriteSheet(&iconSheet); + LoadSpritePalette(&iconPalSheet); + + spriteId = CreateSprite(&sSpriteTemplate_MonIconOnLvlUpBox, 256, 10, 0); + gSprites[spriteId].sDestroy = FALSE; + gSprites[spriteId].sSavedLvlUpBoxXPosition = gBattle_BG2_X; +} + +static void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite) +{ + sprite->pos2.x = sprite->sSavedLvlUpBoxXPosition - gBattle_BG2_X; + + if (sprite->pos2.x != 0) + { + sprite->sDestroy = TRUE; + } + else if (sprite->sDestroy) + { + DestroySprite(sprite); + FreeSpriteTilesByTag(MON_ICON_LVLUP_BOX_TAG); + FreeSpritePaletteByTag(MON_ICON_LVLUP_BOX_TAG); + } +} + +#undef sDestroy +#undef sSavedLvlUpBoxXPosition + +static bool32 IsMonGettingExpSentOut(void) +{ + if (gBattlePartyID[0] == gBattleStruct->expGetterId) + return TRUE; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlePartyID[2] == gBattleStruct->expGetterId) + return TRUE; + + return FALSE; +} + +static void atk6D_reset_sentpokes_value(void) +{ + ResetSentPokesToOpponentValue(); + gBattlescriptCurrInstr++; +} + +static void atk6E_set_atk_to_player0(void) +{ + gBankAttacker = GetBankByIdentity(0); + gBattlescriptCurrInstr++; +} + +static void atk6F_set_visible(void) +{ + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + EmitSpriteInvisibility(0, FALSE); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} + +static void atk70_record_last_used_ability(void) +{ + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + RecordAbilityBattle(gActiveBank, gLastUsedAbility); + gBattlescriptCurrInstr += 1; // UB: Should be + 2, one byte for command and one byte for bank argument. +} + +void BufferMoveToLearnIntoBattleTextBuff2(void) +{ + PREPARE_MOVE_BUFFER(gBattleTextBuff2, gMoveToLearn); +} + +static void atk71_buffer_move_to_learn(void) +{ + BufferMoveToLearnIntoBattleTextBuff2(); + gBattlescriptCurrInstr++; +} + +static void atk72_jump_if_can_run_frombattle(void) +{ + if (CanRunFromBattle(gBank1)) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; +} + +static void atk73_hp_thresholds(void) +{ + u8 opposingBank; + s32 result; + + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + opposingBank = gActiveBank ^ BIT_SIDE; + + result = gBattleMons[opposingBank].hp * 100 / gBattleMons[opposingBank].maxHP; + if (result == 0) + result = 1; + + if (result > 69 || !gBattleMons[opposingBank].hp) + gBattleStruct->hpScale = 0; + else if (result > 39) + gBattleStruct->hpScale = 1; + else if (result > 9) + gBattleStruct->hpScale = 2; + else + gBattleStruct->hpScale = 3; + } + + gBattlescriptCurrInstr += 2; +} + +static void atk74_hp_thresholds2(void) +{ + u8 opposingBank; + s32 result; + u8 hpSwitchout; + + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + opposingBank = gActiveBank ^ BIT_SIDE; + hpSwitchout = *(gBattleStruct->hpOnSwitchout + GetBankSide(opposingBank)); + result = (hpSwitchout - gBattleMons[opposingBank].hp) * 100 / hpSwitchout; + + if (gBattleMons[opposingBank].hp >= hpSwitchout) + gBattleStruct->hpScale = 0; + else if (result <= 29) + gBattleStruct->hpScale = 1; + else if (result <= 69) + gBattleStruct->hpScale = 2; + else + gBattleStruct->hpScale = 3; + } + + gBattlescriptCurrInstr += 2; +} + +static void atk75_item_effect_on_opponent(void) +{ + gBankInMenu = gBankAttacker; + ExecuteTableBasedItemEffect(&gEnemyParty[gBattlePartyID[gBankAttacker]], gLastUsedItem, gBattlePartyID[gBankAttacker], 0, 1); + + gBattlescriptCurrInstr += 1; +} + +static void atk76_various(void) +{ + u8 side; + s32 i; + + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + switch (gBattlescriptCurrInstr[2]) + { + case VARIOUS_CANCEL_MULTI_TURN_MOVES: + CancelMultiTurnMoves(gActiveBank); + break; + case VARIOUS_SET_MAGIC_COAT_TARGET: + gBankAttacker = gBankTarget; + side = GetBankSide(gBankAttacker) ^ 1; + if (gSideTimers[side].followmeTimer != 0 && gBattleMons[gSideTimers[side].followmeTarget].hp != 0) + gBankTarget = gSideTimers[side].followmeTarget; + else + gBankTarget = gActiveBank; + break; + case 2: + gBattleCommunication[0] = IsRunningFromBattleImpossible(); + break; + case VARIOUS_GET_MOVE_TARGET: + gBankTarget = GetMoveTarget(gCurrentMove, 0); + break; + case 4: + if (gHitMarker & HITMARKER_FAINTED(gActiveBank)) + gBattleCommunication[0] = 1; + else + gBattleCommunication[0] = 0; + break; + case VARIOUS_RESET_INTIMIDATE_TRACE_BITS: + gSpecialStatuses[gActiveBank].intimidatedPoke = 0; + gSpecialStatuses[gActiveBank].traced = 0; + break; + case VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP: + if (gBattlePartyID[0] == gBattleStruct->expGetterId || gBattlePartyID[2] == gBattleStruct->expGetterId) + { + u16 *choicedMove; + + if (gBattlePartyID[0] == gBattleStruct->expGetterId) + gActiveBank = 0; + else + gActiveBank = 2; + + choicedMove = &gBattleStruct->choicedMove[gActiveBank]; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[gActiveBank].moves[i] == *choicedMove) + break; + } + if (i == 4) + *choicedMove = 0; + } + break; + case 7: + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE)) + && gBattleTypeFlags & BATTLE_TYPE_TRAINER + && gBattleMons[0].hp != 0 + && gBattleMons[1].hp != 0) + { + gHitMarker &= ~(HITMARKER_x400000); + } + break; + case 8: + gBattleCommunication[0] = 0; + gBattleScripting.bank = gActiveBank = gBattleCommunication[1]; + if (!(gBattleStruct->field_92 & gBitTable[gActiveBank]) + && gBattleMons[gActiveBank].maxHP / 2 >= gBattleMons[gActiveBank].hp + && gBattleMons[gActiveBank].hp != 0 + && !(gBattleMons[gActiveBank].status1 & STATUS_SLEEP)) + { + gBattleStruct->field_92 |= gBitTable[gActiveBank]; + gBattleCommunication[0] = 1; + gBattleCommunication[MULTISTRING_CHOOSER] = sUnknown_0831C4F8[GetNatureFromPersonality(gBattleMons[gActiveBank].personality)]; + } + break; + case 9: + i = sub_81A5258(gBattleCommunication); + if (i == 0) + return; + + gBattleCommunication[1] = i; + break; + case 10: + gBattleMons[1].hp = 0; + gHitMarker |= HITMARKER_FAINTED(1); + gBattleStruct->field_2A1 |= gBitTable[gBattlePartyID[1]]; + gDisableStructs[1].truantUnknownBit = 1; + break; + case 11: + gBattleMons[0].hp = 0; + gHitMarker |= HITMARKER_FAINTED(0); + gHitMarker |= HITMARKER_x400000; + gBattleStruct->field_2A0 |= gBitTable[gBattlePartyID[0]]; + gDisableStructs[0].truantUnknownBit = 1; + break; + case 12: + gBattleMons[0].hp = 0; + gBattleMons[1].hp = 0; + gHitMarker |= HITMARKER_FAINTED(0); + gHitMarker |= HITMARKER_FAINTED(1); + gHitMarker |= HITMARKER_x400000; + gBattleStruct->field_2A0 |= gBitTable[gBattlePartyID[0]]; + gBattleStruct->field_2A1 |= gBitTable[gBattlePartyID[1]]; + gDisableStructs[0].truantUnknownBit = 1; + gDisableStructs[1].truantUnknownBit = 1; + break; + case 13: + EmitCmd13(0); + MarkBufferBankForExecution(gActiveBank); + break; + case 14: + sub_81A5BF8(); + break; + case 15: + sub_81A5D44(); + break; + case 16: + BattleStringExpandPlaceholdersToDisplayedString(gRefereeStringsTable[gBattlescriptCurrInstr[1]]); + sub_814F9EC(gDisplayedStringBattle, 0x16); + break; + case 17: + if (IsTextPrinterActive(0x16)) + return; + break; + case VARIOUS_WAIT_CRY: + if (!IsCryFinished()) + return; + break; + case VARIOUS_RETURN_OPPONENT_MON1: + gActiveBank = 1; + if (gBattleMons[gActiveBank].hp != 0) + { + EmitReturnPokeToBall(0, 0); + MarkBufferBankForExecution(gActiveBank); + } + break; + case VARIOUS_RETURN_OPPONENT_MON2: + if (gNoOfAllBanks > 3) + { + gActiveBank = 3; + if (gBattleMons[gActiveBank].hp != 0) + { + EmitReturnPokeToBall(0, 0); + MarkBufferBankForExecution(gActiveBank); + } + } + break; + case 21: + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x55); + break; + case 22: + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + break; + case 23: + gBattleStruct->field_2A2 |= gBitTable[gActiveBank]; + break; + case 24: + if (sub_805725C(gActiveBank)) + return; + break; + case VARIOUS_SET_TELEPORT_OUTCOME: + if (GetBankSide(gActiveBank) == SIDE_PLAYER) + gBattleOutcome = BATTLE_PLAYER_TELEPORTED; + else + gBattleOutcome = BATTLE_OPPONENT_TELEPORTED; + break; + case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC: + EmitPlaySound(0, 0x19C, 1); + MarkBufferBankForExecution(gActiveBank); + break; + } + + gBattlescriptCurrInstr += 3; +} + +static void atk77_set_protect_like(void) // protect and endure +{ + bool8 notLastTurn = TRUE; + u16 lastMove = gUnknown_02024260[gBankAttacker]; + + if (lastMove != MOVE_PROTECT && lastMove != MOVE_DETECT && lastMove != MOVE_ENDURE) + gDisableStructs[gBankAttacker].protectUses = 0; + + if (gCurrentMoveTurn == (gNoOfAllBanks - 1)) + notLastTurn = FALSE; + + if (sProtectSuccessRates[gDisableStructs[gBankAttacker].protectUses] >= Random() && notLastTurn) + { + if (gBattleMoves[gCurrentMove].effect == EFFECT_PROTECT) + { + gProtectStructs[gBankAttacker].protected = 1; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + if (gBattleMoves[gCurrentMove].effect == EFFECT_ENDURE) + { + gProtectStructs[gBankAttacker].endured = 1; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + gDisableStructs[gBankAttacker].protectUses++; + } + else + { + gDisableStructs[gBankAttacker].protectUses = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + gBattleMoveFlags |= MOVESTATUS_MISSED; + } + + gBattlescriptCurrInstr++; +} + +static void atk78_faintifabilitynotdamp(void) +{ + if (gBattleExecBuffer) + return; + + for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) + { + if (gBattleMons[gBankTarget].ability == ABILITY_DAMP) + break; + } + + if (gBankTarget == gNoOfAllBanks) + { + gActiveBank = gBankAttacker; + gBattleMoveDamage = gBattleMons[gActiveBank].hp; + EmitHealthBarUpdate(0, 0x7FFF); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr++; + + for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBankFlags & gBitTable[gBankTarget])) + break; + } + } + else + { + gLastUsedAbility = ABILITY_DAMP; + RecordAbilityBattle(gBankTarget, gBattleMons[gBankTarget].ability); + gBattlescriptCurrInstr = BattleScript_DampStopsExplosion; + } +} + +static void atk79_setatkhptozero(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBank = gBankAttacker; + gBattleMons[gActiveBank].hp = 0; + EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBank].hp); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr++; +} + +static void atk7A_jumpwhiletargetvalid(void) // Used by intimidate to loop through all targets. +{ + const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + for (gBankTarget++; ; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBankFlags & gBitTable[gBankTarget])) + break; + } + + if (gBankTarget >= gNoOfAllBanks) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = jumpPtr; + } + else + gBattlescriptCurrInstr += 5; +} + +static void atk7B_healhalfHP_if_possible(void) +{ + const u8* failPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + if (gBattlescriptCurrInstr[5] == BS_GET_ATTACKER) + gBankTarget = gBankAttacker; + + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + + if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) + gBattlescriptCurrInstr = failPtr; + else + gBattlescriptCurrInstr += 6; +} + +static void atk7C_trymirrormove(void) +{ + s32 validMovesCount; + s32 i; + u16 move; + u16 movesArray[4]; + + for (i = 0; i < 3; i++) + movesArray[i] = 0; + + for (validMovesCount = 0, i = 0; i < gNoOfAllBanks; i++) + { + if (i != gBankAttacker) + { + move = *(i * 2 + gBankAttacker * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 0) + | (*(i * 2 + gBankAttacker * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 1) << 8); + + if (move != 0 && move != 0xFFFF) + { + movesArray[validMovesCount] = move; + validMovesCount++; + } + } + } + + move = *(gBattleStruct->mirrorMoves + gBankAttacker * 2 + 0) + | (*(gBattleStruct->mirrorMoves + gBankAttacker * 2 + 1) << 8); + + if (move != 0 && move != 0xFFFF) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gCurrentMove = move; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + } + else if (validMovesCount) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + i = Random() % validMovesCount; + gCurrentMove = movesArray[i]; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + } + else + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr++; + } +} + +static void atk7D_set_rain(void) +{ + if (gBattleWeather & WEATHER_RAIN_ANY) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_RAIN_TEMPORARY; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gWishFutureKnock.weatherDuration = 5; + } + gBattlescriptCurrInstr++; +} + +static void atk7E_setreflect(void) +{ + if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_REFLECT) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_REFLECT; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].reflectTimer = 5; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].reflectBank = gBankAttacker; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_ATK_SIDE) == 2) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + gBattlescriptCurrInstr++; +} + +static void atk7F_setseeded(void) +{ + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT || gStatuses3[gBankTarget] & STATUS3_LEECHSEED) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else if (gBattleMons[gBankTarget].type1 == TYPE_GRASS || gBattleMons[gBankTarget].type2 == TYPE_GRASS) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gStatuses3[gBankTarget] |= gBankAttacker; + gStatuses3[gBankTarget] |= STATUS3_LEECHSEED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + + gBattlescriptCurrInstr++; +} + +static void atk80_manipulatedamage(void) +{ + switch (gBattlescriptCurrInstr[1]) + { + case ATK80_DMG_CHANGE_SIGN: + gBattleMoveDamage *= -1; + break; + case ATK80_DMG_HALF_BY_TWO_NOT_MORE_THAN_HALF_MAX_HP: + gBattleMoveDamage /= 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if ((gBattleMons[gBankTarget].maxHP / 2) < gBattleMoveDamage) + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; + break; + case ATK80_DMG_DOUBLED: + gBattleMoveDamage *= 2; + break; + } + + gBattlescriptCurrInstr += 2; +} + +static void atk81_setrest(void) +{ + const u8* failJump = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + gActiveBank = gBankTarget = gBankAttacker; + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP * (-1); + + if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) + { + gBattlescriptCurrInstr = failJump; + } + else + { + if (gBattleMons[gBankTarget].status1 & ((u8)(~STATUS_SLEEP))) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + + gBattleMons[gBankTarget].status1 = 3; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 5; + } +} + +static void atk82_jumpifnotfirstturn(void) +{ + const u8* failJump = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + if (gDisableStructs[gBankAttacker].isFirstTurn) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = failJump; +} + +static void atk83_nop(void) +{ + gBattlescriptCurrInstr++; +} + +bool8 UproarWakeUpCheck(u8 bank) +{ + s32 i; + + for (i = 0; i < gNoOfAllBanks; i++) + { + if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || gBattleMons[bank].ability == ABILITY_SOUNDPROOF) + continue; + + gBattleScripting.bank = i; + + if (gBankTarget == 0xFF) + gBankTarget = i; + else if (gBankTarget == i) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + + break; + } + + if (i == gNoOfAllBanks) + return FALSE; + else + return TRUE; +} + +static void atk84_jump_if_cant_sleep(void) +{ + const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + if (UproarWakeUpCheck(gBankTarget)) + { + gBattlescriptCurrInstr = jumpPtr; + } + else if (gBattleMons[gBankTarget].ability == ABILITY_INSOMNIA + || gBattleMons[gBankTarget].ability == ABILITY_VITAL_SPIRIT) + { + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + gBattlescriptCurrInstr = jumpPtr; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else + { + gBattlescriptCurrInstr += 5; + } +} + +static void atk85_stockpile(void) +{ + if (gDisableStructs[gBankAttacker].stockpileCounter == 3) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gDisableStructs[gBankAttacker].stockpileCounter++; + + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 1, gDisableStructs[gBankAttacker].stockpileCounter) + + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + gBattlescriptCurrInstr++; +} + +static void atk86_stockpiletobasedamage(void) +{ + const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + if (gDisableStructs[gBankAttacker].stockpileCounter == 0) + { + gBattlescriptCurrInstr = jumpPtr; + } + else + { + if (gBattleCommunication[6] != 1) + { + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, + gSideAffecting[GET_BANK_SIDE(gBankTarget)], 0, + 0, gBankAttacker, gBankTarget) + * gDisableStructs[gBankAttacker].stockpileCounter; + gBattleScripting.animTurn = gDisableStructs[gBankAttacker].stockpileCounter; + + if (gProtectStructs[gBankAttacker].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; + } + + gDisableStructs[gBankAttacker].stockpileCounter = 0; + gBattlescriptCurrInstr += 5; + } +} + +static void atk87_stockpiletohpheal(void) +{ + const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + + if (gDisableStructs[gBankAttacker].stockpileCounter == 0) + { + gBattlescriptCurrInstr = jumpPtr; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else if (gBattleMons[gBankAttacker].maxHP == gBattleMons[gBankAttacker].hp) + { + gDisableStructs[gBankAttacker].stockpileCounter = 0; + gBattlescriptCurrInstr = jumpPtr; + gBankTarget = gBankAttacker; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / (1 << (3 - gDisableStructs[gBankAttacker].stockpileCounter)); + + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + + gBattleScripting.animTurn = gDisableStructs[gBankAttacker].stockpileCounter; + gDisableStructs[gBankAttacker].stockpileCounter = 0; + gBattlescriptCurrInstr += 5; + gBankTarget = gBankAttacker; + } +} + +static void atk88_negativedamage(void) +{ + gBattleMoveDamage = -(gHpDealt / 2); + if (gBattleMoveDamage == 0) + gBattleMoveDamage = -1; + + gBattlescriptCurrInstr++; +} + +static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8* BS_ptr) +{ + bool8 certain = 0; + bool8 notProtectAffected = FALSE; + u32 index; + + if (flags & MOVE_EFFECT_AFFECTS_USER) + gActiveBank = gBankAttacker; + else + gActiveBank = gBankTarget; + + flags &= ~(MOVE_EFFECT_AFFECTS_USER); + + if (flags & MOVE_EFFECT_CERTAIN) + certain++; + flags &= ~(MOVE_EFFECT_CERTAIN); + + if (flags & STAT_CHANGE_NOT_PROTECT_AFFECTED) + notProtectAffected++; + flags &= ~(STAT_CHANGE_NOT_PROTECT_AFFECTED); + + PREPARE_STAT_BUFFER(gBattleTextBuff1, statId) + + if ((statValue << 0x18) < 0) // stat decrease + { + if (gSideTimers[GET_BANK_SIDE(gActiveBank)].mistTimer + && !certain && gCurrentMove != MOVE_CURSE) + { + if (flags == STAT_CHANGE_BS_PTR) + { + if (gSpecialStatuses[gActiveBank].statLowered) + { + gBattlescriptCurrInstr = BS_ptr; + } + else + { + BattleScriptPush(BS_ptr); + gBattleScripting.bank = gActiveBank; + gBattlescriptCurrInstr = BattleScript_MistProtected; + gSpecialStatuses[gActiveBank].statLowered = 1; + } + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gCurrentMove != MOVE_CURSE + && notProtectAffected != TRUE && JumpIfMoveAffectedByProtect(0)) + { + gBattlescriptCurrInstr = BattleScript_ButItFailed; + return STAT_CHANGE_DIDNT_WORK; + } + else if ((gBattleMons[gActiveBank].ability == ABILITY_CLEAR_BODY + || gBattleMons[gActiveBank].ability == ABILITY_WHITE_SMOKE) + && !certain && gCurrentMove != MOVE_CURSE) + { + if (flags == STAT_CHANGE_BS_PTR) + { + if (gSpecialStatuses[gActiveBank].statLowered) + { + gBattlescriptCurrInstr = BS_ptr; + } + else + { + BattleScriptPush(BS_ptr); + gBattleScripting.bank = gActiveBank; + gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss; + gLastUsedAbility = gBattleMons[gActiveBank].ability; + RecordAbilityBattle(gActiveBank, gLastUsedAbility); + gSpecialStatuses[gActiveBank].statLowered = 1; + } + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gBattleMons[gActiveBank].ability == ABILITY_KEEN_EYE + && !certain && statId == STAT_STAGE_ACC) + { + if (flags == STAT_CHANGE_BS_PTR) + { + BattleScriptPush(BS_ptr); + gBattleScripting.bank = gActiveBank; + gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; + gLastUsedAbility = gBattleMons[gActiveBank].ability; + RecordAbilityBattle(gActiveBank, gLastUsedAbility); + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gBattleMons[gActiveBank].ability == ABILITY_HYPER_CUTTER + && !certain && statId == STAT_STAGE_ATK) + { + if (flags == STAT_CHANGE_BS_PTR) + { + BattleScriptPush(BS_ptr); + gBattleScripting.bank = gActiveBank; + gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; + gLastUsedAbility = gBattleMons[gActiveBank].ability; + RecordAbilityBattle(gActiveBank, gLastUsedAbility); + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gBattleMons[gActiveBank].ability == ABILITY_SHIELD_DUST && flags == 0) + { + return STAT_CHANGE_DIDNT_WORK; + } + else // try to decrease + { + statValue = -GET_STAT_BUFF_VALUE(statValue); + gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; + index = 1; + if (statValue == -2) + { + gBattleTextBuff2[1] = B_BUFF_STRING; + gBattleTextBuff2[2] = 0xD3; // harshly + gBattleTextBuff2[3] = 0xD3 >> 8; + index = 4; + } + gBattleTextBuff2[index] = B_BUFF_STRING; + index++; + gBattleTextBuff2[index] = 0xD4; // fell + index++; + gBattleTextBuff2[index] = 0xD4 >> 8; + index++; + gBattleTextBuff2[index] = B_BUFF_EOS; + + if (gBattleMons[gActiveBank].statStages[statId] == 0) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = (gBankTarget == gActiveBank); + + } + } + else // stat increase + { + statValue = GET_STAT_BUFF_VALUE(statValue); + gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; + index = 1; + if (statValue == 2) + { + gBattleTextBuff2[1] = B_BUFF_STRING; + gBattleTextBuff2[2] = 0xD1; // sharply + gBattleTextBuff2[3] = 0xD1 >> 8; + index = 4; + } + gBattleTextBuff2[index] = B_BUFF_STRING; + index++; + gBattleTextBuff2[index] = 0xD2; // rose + index++; + gBattleTextBuff2[index] = 0xD2 >> 8; + index++; + gBattleTextBuff2[index] = B_BUFF_EOS; + + if (gBattleMons[gActiveBank].statStages[statId] == 0xC) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = (gBankTarget == gActiveBank); + } + + gBattleMons[gActiveBank].statStages[statId] += statValue; + if (gBattleMons[gActiveBank].statStages[statId] < 0) + gBattleMons[gActiveBank].statStages[statId] = 0; + if (gBattleMons[gActiveBank].statStages[statId] > 0xC) + gBattleMons[gActiveBank].statStages[statId] = 0xC; + + if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && flags & STAT_CHANGE_BS_PTR) + gBattleMoveFlags |= MOVESTATUS_MISSED; + + if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && !(flags & STAT_CHANGE_BS_PTR)) + return STAT_CHANGE_DIDNT_WORK; + + return STAT_CHANGE_WORKED; +} + +static void atk89_statbuffchange(void) +{ + const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + if (ChangeStatBuffs(gBattleScripting.statChanger & 0xF0, GET_STAT_BUFF_ID(gBattleScripting.statChanger), gBattlescriptCurrInstr[1], jumpPtr) == STAT_CHANGE_WORKED) + gBattlescriptCurrInstr += 6; +} + +static void atk8A_normalisebuffs(void) // haze +{ + s32 i, j; + + for (i = 0; i < gNoOfAllBanks; i++) + { + for (j = 0; j < BATTLE_STATS_NO; j++) + gBattleMons[i].statStages[j] = 6; + } + + gBattlescriptCurrInstr++; +} + +static void atk8B_setbide(void) +{ + gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gBankAttacker] = gCurrentMove; + gTakenDmg[gBankAttacker] = 0; + gBattleMons[gBankAttacker].status2 |= (STATUS2_BIDE - 0x100); // 2 turns + + gBattlescriptCurrInstr++; +} + +static void atk8C_confuseifrepeatingattackends(void) +{ + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_LOCK_CONFUSE)) + gBattleCommunication[MOVE_EFFECT_BYTE] = (MOVE_EFFECT_THRASH | MOVE_EFFECT_AFFECTS_USER); + + gBattlescriptCurrInstr++; +} + +static void atk8D_setmultihit_counter(void) +{ + if (gBattlescriptCurrInstr[1]) + { + gMultiHitCounter = gBattlescriptCurrInstr[1]; + } + else + { + gMultiHitCounter = Random() & 3; + if (gMultiHitCounter > 1) + gMultiHitCounter = (Random() & 3) + 2; + else + gMultiHitCounter += 2; + } + + gBattlescriptCurrInstr += 2; +} + +static void atk8E_init_multihit_string(void) +{ + PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) + + gBattlescriptCurrInstr++; +} + +static bool8 sub_8051064(void) +{ + if (gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + { + *(gBattleStruct->field_58 + gBankTarget) = gBattlePartyID[gBankTarget]; + } + else + { + u16 random = Random() & 0xFF; + if ((u32)((random * (gBattleMons[gBankAttacker].level + gBattleMons[gBankTarget].level) >> 8) + 1) <= (gBattleMons[gBankTarget].level / 4)) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + return FALSE; + } + *(gBattleStruct->field_58 + gBankTarget) = gBattlePartyID[gBankTarget]; + } + + gBattlescriptCurrInstr = gUnknown_082DADD8; + return TRUE; +} + +static void atk8F_forcerandomswitch(void) +{ + s32 i; + s32 bank1PartyId = 0; + s32 bank2PartyId = 0; + + #ifdef NONMATCHING + s32 lastMonId = 0; // + 1 + #else + register s32 lastMonId asm("r8") = 0; // + 1 + #endif // NONMATCHING + + s32 firstMonId = 0; + s32 monsCount = 0; + struct Pokemon* party = NULL; + s32 validMons = 0; + s32 minNeeded = 0; + + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER)) + { + if (GetBankSide(gBankTarget) == SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + if ((gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_LINK) + || (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_x2000000) + || (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)) + { + if ((gBankTarget & BIT_MON) != 0) + { + firstMonId = 3; + lastMonId = 6; + } + else + { + firstMonId = 0; + lastMonId = 3; + } + monsCount = 3; + minNeeded = 1; + bank2PartyId = gBattlePartyID[gBankTarget]; + bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; + } + else if ((gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK) + || (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_x2000000)) + { + if (sub_806D82C(sub_806D864(gBankTarget)) == 1) + { + firstMonId = 3; + lastMonId = 6; + } + else + { + firstMonId = 0; + lastMonId = 3; + } + monsCount = 3; + minNeeded = 1; + bank2PartyId = gBattlePartyID[gBankTarget]; + bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; + } + else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + { + if (GetBankSide(gBankTarget) == SIDE_PLAYER) + { + firstMonId = 0; + lastMonId = 6; + monsCount = 6; + minNeeded = 2; // since there are two opponents, it has to be a double battle + } + else + { + if ((gBankTarget & BIT_MON) != 0) + { + firstMonId = 3; + lastMonId = 6; + } + else + { + firstMonId = 0; + lastMonId = 3; + } + monsCount = 3; + minNeeded = 1; + } + bank2PartyId = gBattlePartyID[gBankTarget]; + bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; + } + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + firstMonId = 0; + lastMonId = 6; + monsCount = 6; + minNeeded = 2; + bank2PartyId = gBattlePartyID[gBankTarget]; + bank1PartyId = gBattlePartyID[gBankTarget ^ BIT_MON]; + } + else + { + firstMonId = 0; + lastMonId = 6; + monsCount = 6; + minNeeded = 1; + bank2PartyId = gBattlePartyID[gBankTarget]; // there is only one pokemon out in single battles + bank1PartyId = gBattlePartyID[gBankTarget]; + } + + for (i = firstMonId; i < lastMonId; i++) + { + if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[i], MON_DATA_IS_EGG) + && GetMonData(&party[i], MON_DATA_HP) != 0) + { + validMons++; + } + } + + if (validMons <= minNeeded) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + if (sub_8051064()) + { + do + { + i = Random() % monsCount; + i += firstMonId; + } + while (i == bank2PartyId + || i == bank1PartyId + || GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_NONE + || GetMonData(&party[i], MON_DATA_IS_EGG) == TRUE + || GetMonData(&party[i], MON_DATA_HP) == 0); + } + *(gBattleStruct->field_5C + gBankTarget) = i; + + if (!sub_81B1250()) + sub_803BDA0(gBankTarget); + + if ((gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + || (gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_MULTI) + || (gBattleTypeFlags & BATTLE_TYPE_x2000000 && gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + || (gBattleTypeFlags & BATTLE_TYPE_x2000000 && gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + sub_81B8E80(gBankTarget, i, 0); + sub_81B8E80(gBankTarget ^ BIT_MON, i, 1); + } + + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) + sub_80571DC(gBankTarget, i); + } + } + else + { + sub_8051064(); + } +} + +static void atk90_conversion_type_change(void) // randomly changes user's type to one of its moves' type +{ + u8 validMoves = 0; + u8 moveChecked; + u8 moveType; + + while (validMoves < 4) + { + if (gBattleMons[gBankAttacker].moves[validMoves] == 0) + break; + + validMoves++; + } + + for (moveChecked = 0; moveChecked < validMoves; moveChecked++) + { + moveType = gBattleMoves[gBattleMons[gBankAttacker].moves[moveChecked]].type; + + if (moveType == TYPE_MYSTERY) + { + if (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST) + moveType = TYPE_GHOST; + else + moveType = TYPE_NORMAL; + } + if (moveType != gBattleMons[gBankAttacker].type1 + && moveType != gBattleMons[gBankAttacker].type2) + { + break; + } + } + + if (moveChecked == validMoves) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + do + { + + while ((moveChecked = Random() & 3) >= validMoves); + + moveType = gBattleMoves[gBattleMons[gBankAttacker].moves[moveChecked]].type; + + if (moveType == TYPE_MYSTERY) + { + if (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST) + moveType = TYPE_GHOST; + else + moveType = TYPE_NORMAL; + } + } + while (moveType == gBattleMons[gBankAttacker].type1 || moveType == gBattleMons[gBankAttacker].type2); + + gBattleMons[gBankAttacker].type1 = moveType; + gBattleMons[gBankAttacker].type2 = moveType; + + PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType) + + gBattlescriptCurrInstr += 5; + } +} + +static void atk91_givepaydaymoney(void) +{ + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) && gPaydayMoney != 0) + { + u32 bonusMoney = gPaydayMoney * gBattleStruct->moneyMultiplier; + AddMoney(&gSaveBlock1Ptr->money, bonusMoney); + + PREPARE_HWORD_NUMBER_BUFFER(gBattleTextBuff1, 5, bonusMoney) + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PrintPayDayMoneyString; + } + else + { + gBattlescriptCurrInstr++; + } +} + +static void atk92_setlightscreen(void) +{ + if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_LIGHTSCREEN) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_LIGHTSCREEN; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].lightscreenTimer = 5; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].lightscreenBank = gBankAttacker; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_ATK_SIDE) == 2) + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 3; + } + + gBattlescriptCurrInstr++; +} + +static void atk93_ko_move(void) +{ + u8 holdEffect, param; + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect; + param = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + param = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < param) + { + RecordItemEffectBattle(gBankTarget, HOLD_EFFECT_FOCUS_BAND); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + + if (gBattleMons[gBankTarget].ability == ABILITY_STURDY) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gLastUsedAbility = ABILITY_STURDY; + gBattlescriptCurrInstr = BattleScript_SturdyPreventsOHKO; + RecordAbilityBattle(gBankTarget, ABILITY_STURDY); + } + else + { + u16 chance; + if (!(gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS)) + { + chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBankAttacker].level - gBattleMons[gBankTarget].level); + if (Random() % 100 + 1 < chance && gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + chance = TRUE; + else + chance = FALSE; + } + else if (gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker + && gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + { + chance = TRUE; + } + else + { + chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBankAttacker].level - gBattleMons[gBankTarget].level); + if (Random() % 100 + 1 < chance && gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + chance = TRUE; + else + chance = FALSE; + } + if (chance) + { + if (gProtectStructs[gBankTarget].endured) + { + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + gBattleMoveFlags |= MOVESTATUS_ENDURED; + } + else if (gSpecialStatuses[gBankTarget].focusBanded) + { + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + gBattleMoveFlags |= MOVESTATUS_HUNGON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + else + { + gBattleMoveDamage = gBattleMons[gBankTarget].hp; + gBattleMoveFlags |= MOVESTATUS_ONEHITKO; + } + gBattlescriptCurrInstr += 5; + } + else + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + if (gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + } +} + +static void atk94_damagetohalftargethp(void) // super fang +{ + gBattleMoveDamage = gBattleMons[gBankTarget].hp / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattlescriptCurrInstr++; +} + +static void atk95_setsandstorm(void) +{ + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_SANDSTORM_TEMPORARY; + gBattleCommunication[MULTISTRING_CHOOSER] = 3; + gWishFutureKnock.weatherDuration = 5; + } + gBattlescriptCurrInstr++; +} + +static void atk96_weatherdamage(void) +{ + if (WEATHER_HAS_EFFECT) + { + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + { + if (gBattleMons[gBankAttacker].type1 != TYPE_ROCK + && gBattleMons[gBankAttacker].type1 != TYPE_STEEL + && gBattleMons[gBankAttacker].type1 != TYPE_GROUND + && gBattleMons[gBankAttacker].type2 != TYPE_ROCK + && gBattleMons[gBankAttacker].type2 != TYPE_STEEL + && gBattleMons[gBankAttacker].type2 != TYPE_GROUND + && gBattleMons[gBankAttacker].ability != ABILITY_SAND_VEIL + && !(gStatuses3[gBankAttacker] & STATUS3_UNDERGROUND) + && !(gStatuses3[gBankAttacker] & STATUS3_UNDERWATER)) + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + else + { + gBattleMoveDamage = 0; + } + } + if (gBattleWeather & WEATHER_HAIL) + { + if (gBattleMons[gBankAttacker].type1 != TYPE_ICE + && gBattleMons[gBankAttacker].type2 != TYPE_ICE + && !(gStatuses3[gBankAttacker] & STATUS3_UNDERGROUND) + && !(gStatuses3[gBankAttacker] & STATUS3_UNDERWATER)) + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + else + { + gBattleMoveDamage = 0; + } + } + } + else + { + gBattleMoveDamage = 0; + } + + if (gAbsentBankFlags & gBitTable[gBankAttacker]) + gBattleMoveDamage = 0; + + gBattlescriptCurrInstr++; +} + +static void atk97_try_infatuation(void) +{ + struct Pokemon *monAttacker, *monTarget; + u16 speciesAttacker, speciesTarget; + u32 personalityAttacker, personalityTarget; + + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + monAttacker = &gPlayerParty[gBattlePartyID[gBankAttacker]]; + else + monAttacker = &gEnemyParty[gBattlePartyID[gBankAttacker]]; + + if (GetBankSide(gBankTarget) == SIDE_PLAYER) + monTarget = &gPlayerParty[gBattlePartyID[gBankTarget]]; + else + monTarget = &gEnemyParty[gBattlePartyID[gBankTarget]]; + + speciesAttacker = GetMonData(monAttacker, MON_DATA_SPECIES); + personalityAttacker = GetMonData(monAttacker, MON_DATA_PERSONALITY); + + speciesTarget = GetMonData(monTarget, MON_DATA_SPECIES); + personalityTarget = GetMonData(monTarget, MON_DATA_PERSONALITY); + + if (gBattleMons[gBankTarget].ability == ABILITY_OBLIVIOUS) + { + gBattlescriptCurrInstr = BattleScript_ObliviousPreventsAttraction; + gLastUsedAbility = ABILITY_OBLIVIOUS; + RecordAbilityBattle(gBankTarget, ABILITY_OBLIVIOUS); + } + else + { + if (GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) + || gBattleMons[gBankTarget].status2 & STATUS2_INFATUATION + || GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == MON_GENDERLESS + || GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) == MON_GENDERLESS) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMons[gBankTarget].status2 |= STATUS2_INFATUATED_WITH(gBankAttacker); + gBattlescriptCurrInstr += 5; + } + } +} + +static void atk98_status_icon_update(void) +{ + if (gBattleExecBuffer) + return; + + if (gBattlescriptCurrInstr[1] != BS_ATTACKER_WITH_PARTNER) + { + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + EmitStatusIconUpdate(0, gBattleMons[gActiveBank].status1, gBattleMons[gActiveBank].status2); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 2; + } + else + { + gActiveBank = gBankAttacker; + if (!(gAbsentBankFlags & gBitTable[gActiveBank])) + { + EmitStatusIconUpdate(0, gBattleMons[gActiveBank].status1, gBattleMons[gActiveBank].status2); + MarkBufferBankForExecution(gActiveBank); + } + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gActiveBank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); + if (!(gAbsentBankFlags & gBitTable[gActiveBank])) + { + EmitStatusIconUpdate(0, gBattleMons[gActiveBank].status1, gBattleMons[gActiveBank].status2); + MarkBufferBankForExecution(gActiveBank); + } + } + gBattlescriptCurrInstr += 2; + } +} + +static void atk99_setmist(void) +{ + if (gSideTimers[GET_BANK_SIDE(gBankAttacker)].mistTimer) + { + gBattleMoveFlags |= MOVESTATUS_FAILED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gSideTimers[GET_BANK_SIDE(gBankAttacker)].mistTimer = 5; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].mistBank = gBankAttacker; + gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_MIST; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + gBattlescriptCurrInstr++; +} + +static void atk9A_set_focusenergy(void) +{ + if (gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) + { + gBattleMoveFlags |= MOVESTATUS_FAILED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gBattleMons[gBankAttacker].status2 |= STATUS2_FOCUS_ENERGY; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + gBattlescriptCurrInstr++; +} + +static void atk9B_transformdataexecution(void) +{ + gLastUsedMove = 0xFFFF; + gBattlescriptCurrInstr++; + if (gBattleMons[gBankTarget].status2 & STATUS2_TRANSFORMED + || gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE) + { + gBattleMoveFlags |= MOVESTATUS_FAILED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + s32 i; + u8 *battleMonAttacker, *battleMonTarget; + + gBattleMons[gBankAttacker].status2 |= STATUS2_TRANSFORMED; + gDisableStructs[gBankAttacker].disabledMove = 0; + gDisableStructs[gBankAttacker].disableTimer1 = 0; + gDisableStructs[gBankAttacker].unk0 = gBattleMons[gBankTarget].personality; + gDisableStructs[gBankAttacker].unk18_b = 0; + + PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBankTarget].species) + + battleMonAttacker = (u8*)(&gBattleMons[gBankAttacker]); + battleMonTarget = (u8*)(&gBattleMons[gBankTarget]); + + for (i = 0; i < offsetof(struct BattlePokemon, pp); i++) + battleMonAttacker[i] = battleMonTarget[i]; + + for (i = 0; i < 4; i++) + { + if (gBattleMoves[gBattleMons[gBankAttacker].moves[i]].pp < 5) + gBattleMons[gBankAttacker].pp[i] = gBattleMoves[gBattleMons[gBankAttacker].moves[i]].pp; + else + gBattleMons[gBankAttacker].pp[i] = 5; + } + + gActiveBank = gBankAttacker; + EmitResetActionMoveSelection(0, RESET_MOVE_SELECTION); + MarkBufferBankForExecution(gActiveBank); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } +} + +static void atk9C_set_substitute(void) +{ + u32 hp = gBattleMons[gBankAttacker].maxHP / 4; + if (gBattleMons[gBankAttacker].maxHP / 4 == 0) + hp = 1; + + if (gBattleMons[gBankAttacker].hp <= hp) + { + gBattleMoveDamage = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4; // one bit value will only work for pokemon which max hp can go to 1020(which is more than possible in games) + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattleMons[gBankAttacker].status2 |= STATUS2_SUBSTITUTE; + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_WRAPPED); + gDisableStructs[gBankAttacker].substituteHP = gBattleMoveDamage; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE; + } + + gBattlescriptCurrInstr++; +} + +static bool8 IsMoveUncopyableByMimic(u16 move) +{ + s32 i; + for (i = 0; sMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END + && sMovesForbiddenToCopy[i] != move; i++); + + return (sMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END); +} + +static void atk9D_mimicattackcopy(void) +{ + gLastUsedMove = 0xFFFF; + + if (IsMoveUncopyableByMimic(gLastUsedMovesByBanks[gBankTarget]) + || gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED + || gLastUsedMovesByBanks[gBankTarget] == 0 + || gLastUsedMovesByBanks[gBankTarget] == 0xFFFF) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankAttacker].moves[i] == gLastUsedMovesByBanks[gBankTarget]) + break; + } + + if (i == 4) + { + gBattleMons[gBankAttacker].moves[gCurrMovePos] = gLastUsedMovesByBanks[gBankTarget]; + if (gBattleMoves[gLastUsedMovesByBanks[gBankTarget]].pp < 5) + gBattleMons[gBankAttacker].pp[gCurrMovePos] = gBattleMoves[gLastUsedMovesByBanks[gBankTarget]].pp; + else + gBattleMons[gBankAttacker].pp[gCurrMovePos] = 5; + + + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastUsedMovesByBanks[gBankTarget]) + + gDisableStructs[gBankAttacker].unk18_b |= gBitTable[gCurrMovePos]; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + } +} + +#ifdef NONMATCHING +static void atk9E_metronome(void) +{ + while (1) + { + const u16 *move; + s32 i, j; + + gCurrentMove = (Random() & 0x1FF) + 1; + if (gCurrentMove > LAST_MOVE_INDEX) + continue; + + for (i = 0; i < 4; i++); // ? + + for (move = sMovesForbiddenToCopy; ; move++) + { + if (*move == gCurrentMove) + break; + if (*move == METRONOME_FORBIDDEN_END) + break; + } + + if (*move == METRONOME_FORBIDDEN_END) + break; + } + + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + gBankTarget = GetMoveTarget(gCurrentMove, 0); +} + +#else +__attribute__((naked)) +static void atk9E_metronome(void) +{ + asm( + "\n\ + .syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + ldr r7, =gCurrentMove\n\ + movs r6, 0xB1\n\ + lsls r6, 1\n\ + ldr r5, =sMovesForbiddenToCopy\n\ + ldr r0, =gBattlescriptCurrInstr\n\ + mov r8, r0\n\ +_080524EE:\n\ + bl Random\n\ + ldr r2, =0x000001ff\n\ + adds r1, r2, 0\n\ + ands r0, r1\n\ + adds r0, 0x1\n\ + strh r0, [r7]\n\ + cmp r0, r6\n\ + bhi _080524EE\n\ + movs r0, 0x3\n\ +_08052502:\n\ + subs r0, 0x1\n\ + cmp r0, 0\n\ + bge _08052502\n\ + ldr r4, =gCurrentMove\n\ + ldrh r2, [r4]\n\ + ldr r3, =0x0000ffff\n\ + subs r0, r5, 0x2\n\ +_08052510:\n\ + adds r0, 0x2\n\ + ldrh r1, [r0]\n\ + cmp r1, r2\n\ + beq _0805251C\n\ + cmp r1, r3\n\ + bne _08052510\n\ +_0805251C:\n\ + ldr r0, =0x0000ffff\n\ + cmp r1, r0\n\ + bne _080524EE\n\ + ldr r2, =gHitMarker\n\ + ldr r0, [r2]\n\ + ldr r1, =0xfffffbff\n\ + ands r0, r1\n\ + str r0, [r2]\n\ + ldr r3, =gBattleScriptsForMoveEffects\n\ + ldr r2, =gBattleMoves\n\ + ldrh r1, [r4]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r0, [r0]\n\ + lsls r0, 2\n\ + adds r0, r3\n\ + ldr r0, [r0]\n\ + mov r1, r8\n\ + str r0, [r1]\n\ + ldrh r0, [r4]\n\ + movs r1, 0\n\ + bl GetMoveTarget\n\ + ldr r1, =gBankTarget\n\ + strb r0, [r1]\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} + +#endif // NONMATCHING + +static void atk9F_dmgtolevel(void) +{ + gBattleMoveDamage = gBattleMons[gBankAttacker].level; + gBattlescriptCurrInstr++; +} + +static void atkA0_psywavedamageeffect(void) +{ + s32 randDamage; + + while ((randDamage = (Random() & 0xF)) > 10); + + randDamage *= 10; + gBattleMoveDamage = gBattleMons[gBankAttacker].level * (randDamage + 50) / 100; + gBattlescriptCurrInstr++; +} + +static void atkA1_counterdamagecalculator(void) +{ + u8 sideAttacker = GetBankSide(gBankAttacker); + u8 sideTarget = GetBankSide(gProtectStructs[gBankAttacker].physicalBank); + + if (gProtectStructs[gBankAttacker].physicalDmg + && sideAttacker != sideTarget + && gBattleMons[gProtectStructs[gBankAttacker].physicalBank].hp) + { + gBattleMoveDamage = gProtectStructs[gBankAttacker].physicalDmg * 2; + + if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp) + gBankTarget = gSideTimers[sideTarget].followmeTarget; + else + gBankTarget = gProtectStructs[gBankAttacker].physicalBank; + + gBattlescriptCurrInstr += 5; + } + else + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkA2_mirrorcoatdamagecalculator(void) // a copy of atkA1 with the physical -> special field changes +{ + u8 sideAttacker = GetBankSide(gBankAttacker); + u8 sideTarget = GetBankSide(gProtectStructs[gBankAttacker].specialBank); + + if (gProtectStructs[gBankAttacker].specialDmg && sideAttacker != sideTarget && gBattleMons[gProtectStructs[gBankAttacker].specialBank].hp) + { + gBattleMoveDamage = gProtectStructs[gBankAttacker].specialDmg * 2; + + if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp) + gBankTarget = gSideTimers[sideTarget].followmeTarget; + else + gBankTarget = gProtectStructs[gBankAttacker].specialBank; + + gBattlescriptCurrInstr += 5; + } + else + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkA3_disablelastusedattack(void) +{ + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankTarget].moves[i] == gLastUsedMovesByBanks[gBankTarget]) + break; + } + if (gDisableStructs[gBankTarget].disabledMove == 0 + && i != 4 && gBattleMons[gBankTarget].pp[i] != 0) + { + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBankTarget].moves[i]) + + gDisableStructs[gBankTarget].disabledMove = gBattleMons[gBankTarget].moves[i]; + gDisableStructs[gBankTarget].disableTimer1 = (Random() & 3) + 2; + gDisableStructs[gBankTarget].disableTimer2 = gDisableStructs[gBankTarget].disableTimer1; // used to save the random amount of turns? + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkA4_setencore(void) +{ + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankTarget].moves[i] == gLastUsedMovesByBanks[gBankTarget]) + break; + } + + if (gLastUsedMovesByBanks[gBankTarget] == MOVE_STRUGGLE + || gLastUsedMovesByBanks[gBankTarget] == MOVE_ENCORE + || gLastUsedMovesByBanks[gBankTarget] == MOVE_MIRROR_MOVE) + { + i = 4; + } + + if (gDisableStructs[gBankTarget].encoredMove == 0 + && i != 4 && gBattleMons[gBankTarget].pp[i] != 0) + { + gDisableStructs[gBankTarget].encoredMove = gBattleMons[gBankTarget].moves[i]; + gDisableStructs[gBankTarget].encoredMovePos = i; + gDisableStructs[gBankTarget].encoreTimer1 = (Random() & 3) + 3; + gDisableStructs[gBankTarget].encoreTimer2 = gDisableStructs[gBankTarget].encoreTimer1; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkA5_painsplitdmgcalc(void) +{ + if (!(gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE)) + { + s32 hpDiff = (gBattleMons[gBankAttacker].hp + gBattleMons[gBankTarget].hp) / 2; + s32 painSplitHp = gBattleMoveDamage = gBattleMons[gBankTarget].hp - hpDiff; + u8* storeLoc = (void*)(&gBattleScripting.painSplitHp); + + storeLoc[0] = (painSplitHp); + storeLoc[1] = (painSplitHp & 0x0000FF00) >> 8; + storeLoc[2] = (painSplitHp & 0x00FF0000) >> 16; + storeLoc[3] = (painSplitHp & 0xFF000000) >> 24; + + gBattleMoveDamage = gBattleMons[gBankAttacker].hp - hpDiff; + gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF; + + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +#ifdef NONMATCHING +static void atkA6_settypetorandomresistance(void) // conversion 2 +{ + if (gUnknown_02024250[gBankAttacker] == 0 + || gUnknown_02024250[gBankAttacker] == 0xFFFF) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else if (IsTwoTurnsMove(gUnknown_02024250[gBankAttacker]) + && gBattleMons[gUnknown_02024270[gBankAttacker]].status2 & STATUS2_MULTIPLETURNS) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + s32 type = 0, rands = 0; + do + { + while (((type = (Random() & 0x7F)) > 0x70)); + + type *= 3; + + if (gTypeEffectiveness[type] == gUnknown_02024258[gBankAttacker] + && gTypeEffectiveness[type + 2] <= 5 + && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1] + && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1]) + { + gBattleMons[gBankAttacker].type1 = type; + gBattleMons[gBankAttacker].type2 = type; + + PREPARE_TYPE_BUFFER(gBattleTextBuff1, type) + + gBattlescriptCurrInstr += 5; + return; + } + + rands++; + } while (rands <= 999); + + type = 0, rands = 0; + do + { + s8 var = (s8)(gTypeEffectiveness[type]); + if (var > -1 || var < -2) + { + if (gTypeEffectiveness[type] == gUnknown_02024258[gBankAttacker] + && gTypeEffectiveness[type + 2] <= 5 + && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1] + && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1]) + { + gBattleMons[gBankAttacker].type1 = gTypeEffectiveness[rands + 1]; + gBattleMons[gBankAttacker].type2 = gTypeEffectiveness[rands + 1]; + + PREPARE_TYPE_BUFFER(gBattleTextBuff1, gTypeEffectiveness[rands + 1]) + + gBattlescriptCurrInstr += 5; + return; + } + } + type += 3, rands += 3; + } while (rands < 336); + + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +#else +__attribute__((naked)) +static void atkA6_settypetorandomresistance(void) // conversion 2 +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + ldr r1, =gUnknown_02024250\n\ + ldr r4, =gBankAttacker\n\ + ldrb r0, [r4]\n\ + lsls r0, 1\n\ + adds r2, r0, r1\n\ + ldrh r1, [r2]\n\ + cmp r1, 0\n\ + beq _08052B7E\n\ + ldr r0, =0x0000ffff\n\ + cmp r1, r0\n\ + beq _08052B7E\n\ + ldrh r0, [r2]\n\ + bl IsTwoTurnsMove\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08052C1C\n\ + ldr r1, =gBattleMons\n\ + ldr r2, =gUnknown_02024270\n\ + ldrb r0, [r4]\n\ + adds r0, r2\n\ + ldrb r2, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r1, 0x50\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 5\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08052C1C\n\ +_08052B7E:\n\ + ldr r3, =gBattlescriptCurrInstr\n\ + ldr r2, [r3]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + str r1, [r3]\n\ + b _08052D08\n\ + .pool\n\ +_08052BB4:\n\ + mov r0, r12\n\ + strb r5, [r0]\n\ + mov r1, r10\n\ + ldrb r0, [r1]\n\ + muls r0, r2\n\ + adds r0, r7\n\ + adds r0, 0x22\n\ + strb r5, [r0]\n\ + ldr r1, =gBattleTextBuff1\n\ + movs r0, 0xFD\n\ + strb r0, [r1]\n\ + movs r0, 0x3\n\ + strb r0, [r1, 0x1]\n\ + strb r5, [r1, 0x2]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x3]\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + b _08052C0A\n\ + .pool\n\ +_08052BE0:\n\ + mov r0, r8\n\ + adds r0, 0x1\n\ + adds r0, r3\n\ + ldrb r2, [r0]\n\ + strb r2, [r4]\n\ + mov r4, r10\n\ + ldrb r0, [r4]\n\ + muls r0, r6\n\ + ldr r7, =gBattleMons\n\ + adds r0, r7\n\ + adds r0, 0x22\n\ + strb r2, [r0]\n\ + ldr r1, =gBattleTextBuff1\n\ + movs r0, 0xFD\n\ + strb r0, [r1]\n\ + movs r0, 0x3\n\ + strb r0, [r1, 0x1]\n\ + strb r2, [r1, 0x2]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x3]\n\ + mov r1, r12\n\ +_08052C0A:\n\ + ldr r0, [r1]\n\ + adds r0, 0x5\n\ + str r0, [r1]\n\ + b _08052D08\n\ + .pool\n\ +_08052C1C:\n\ + movs r4, 0\n\ + mov r8, r4\n\ + movs r7, 0x7F\n\ + mov r9, r7\n\ +_08052C24:\n\ + bl Random\n\ + mov r4, r9\n\ + ands r4, r0\n\ + cmp r4, 0x70\n\ + bhi _08052C24\n\ + lsls r0, r4, 1\n\ + adds r4, r0, r4\n\ + ldr r6, =gTypeEffectiveness\n\ + adds r3, r4, r6\n\ + ldr r1, =gUnknown_02024258\n\ + ldr r2, =gBankAttacker\n\ + ldrb r5, [r2]\n\ + lsls r0, r5, 1\n\ + adds r0, r1\n\ + ldrb r1, [r3]\n\ + mov r10, r2\n\ + ldrh r0, [r0]\n\ + cmp r1, r0\n\ + bne _08052C80\n\ + adds r0, r4, 0x2\n\ + adds r0, r6\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x5\n\ + bhi _08052C80\n\ + ldr r7, =gBattleMons\n\ + movs r2, 0x58\n\ + adds r0, r5, 0\n\ + muls r0, r2\n\ + adds r3, r0, r7\n\ + movs r0, 0x21\n\ + adds r0, r3\n\ + mov r12, r0\n\ + adds r0, r4, 0x1\n\ + adds r0, r6\n\ + ldrb r5, [r0]\n\ + mov r1, r12\n\ + ldrb r0, [r1]\n\ + adds r1, r5, 0\n\ + cmp r0, r1\n\ + beq _08052C80\n\ + adds r0, r3, 0\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, r1\n\ + bne _08052BB4\n\ +_08052C80:\n\ + movs r7, 0x1\n\ + add r8, r7\n\ + ldr r0, =0x000003e7\n\ + cmp r8, r0\n\ + ble _08052C24\n\ + movs r0, 0\n\ + mov r8, r0\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + mov r12, r1\n\ + ldr r3, =gTypeEffectiveness\n\ + adds r0, r4, 0x1\n\ + adds r0, r3\n\ + mov r9, r0\n\ + adds r5, r3, 0\n\ +_08052C9C:\n\ + ldrb r1, [r5]\n\ + cmp r1, 0xFF\n\ + bgt _08052CA6\n\ + cmp r1, 0xFE\n\ + bge _08052CE0\n\ +_08052CA6:\n\ + mov r4, r10\n\ + ldrb r2, [r4]\n\ + lsls r0, r2, 1\n\ + ldr r7, =gUnknown_02024258\n\ + adds r0, r7\n\ + ldrh r0, [r0]\n\ + cmp r1, r0\n\ + bne _08052CE0\n\ + ldrb r0, [r5, 0x2]\n\ + cmp r0, 0x5\n\ + bhi _08052CE0\n\ + movs r6, 0x58\n\ + adds r0, r2, 0\n\ + muls r0, r6\n\ + ldr r1, =gBattleMons\n\ + adds r2, r0, r1\n\ + adds r4, r2, 0\n\ + adds r4, 0x21\n\ + ldrb r0, [r4]\n\ + mov r7, r9\n\ + ldrb r1, [r7]\n\ + cmp r0, r1\n\ + beq _08052CE0\n\ + adds r0, r2, 0\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, r1\n\ + beq _08052CE0\n\ + b _08052BE0\n\ +_08052CE0:\n\ + adds r5, 0x3\n\ + movs r0, 0x3\n\ + add r8, r0\n\ + ldr r0, =0x0000014f\n\ + cmp r8, r0\n\ + bls _08052C9C\n\ + mov r1, r12\n\ + ldr r2, [r1]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + mov r4, r12\n\ + str r1, [r4]\n\ +_08052D08:\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} +#endif // NONMATCHING + +static void atkA7_setalwayshitflag(void) +{ + gStatuses3[gBankTarget] &= ~(STATUS3_ALWAYS_HITS); + gStatuses3[gBankTarget] |= 0x10; + gDisableStructs[gBankTarget].bankWithSureHit = gBankAttacker; + gBattlescriptCurrInstr++; +} + +static void atkA8_copymovepermanently(void) // sketch +{ + gLastUsedMove = 0xFFFF; + + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED) + && gUnknownMovesUsedByBanks[gBankTarget] != MOVE_STRUGGLE + && gUnknownMovesUsedByBanks[gBankTarget] != 0 + && gUnknownMovesUsedByBanks[gBankTarget] != 0xFFFF + && gUnknownMovesUsedByBanks[gBankTarget] != MOVE_SKETCH) + { + s32 i; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankAttacker].moves[i] == MOVE_SKETCH) + continue; + if (gBattleMons[gBankAttacker].moves[i] == gUnknownMovesUsedByBanks[gBankTarget]) + break; + } + + if (i != 4) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else // sketch worked + { + struct MovePpInfo movePpData; + + gBattleMons[gBankAttacker].moves[gCurrMovePos] = gUnknownMovesUsedByBanks[gBankTarget]; + gBattleMons[gBankAttacker].pp[gCurrMovePos] = gBattleMoves[gUnknownMovesUsedByBanks[gBankTarget]].pp; + gActiveBank = gBankAttacker; + + for (i = 0; i < 4; i++) + { + movePpData.move[i] = gBattleMons[gBankAttacker].moves[i]; + movePpData.pp[i] = gBattleMons[gBankAttacker].pp[i]; + } + movePpData.ppBonuses = gBattleMons[gBankAttacker].ppBonuses; + + EmitSetMonData(0, REQUEST_MOVES_PP_BATTLE, 0, sizeof(struct MovePpInfo), &movePpData); + MarkBufferBankForExecution(gActiveBank); + + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gUnknownMovesUsedByBanks[gBankTarget]) + + gBattlescriptCurrInstr += 5; + } + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static bool8 IsTwoTurnsMove(u16 move) +{ + if (gBattleMoves[move].effect == EFFECT_SKULL_BASH + || gBattleMoves[move].effect == EFFECT_RAZOR_WIND + || gBattleMoves[move].effect == EFFECT_SKY_ATTACK + || gBattleMoves[move].effect == EFFECT_SOLARBEAM + || gBattleMoves[move].effect == EFFECT_FLY + || gBattleMoves[move].effect == EFFECT_BIDE) + return TRUE; + else + return FALSE; +} + +static bool8 IsInvalidForSleepTalkOrAssist(u16 move) +{ + if (move == 0 || move == MOVE_SLEEP_TALK || move == MOVE_ASSIST + || move == MOVE_MIRROR_MOVE || move == MOVE_METRONOME) + return TRUE; + else + return FALSE; +} + +static u8 AttacksThisTurn(u8 bank, u16 move) // Note: returns 1 if it's a charging turn, otherwise 2 +{ + // first argument is unused + if (gBattleMoves[move].effect == EFFECT_SOLARBEAM + && (gBattleWeather & WEATHER_SUN_ANY)) + return 2; + + if (gBattleMoves[move].effect == EFFECT_SKULL_BASH + || gBattleMoves[move].effect == EFFECT_RAZOR_WIND + || gBattleMoves[move].effect == EFFECT_SKY_ATTACK + || gBattleMoves[move].effect == EFFECT_SOLARBEAM + || gBattleMoves[move].effect == EFFECT_FLY + || gBattleMoves[move].effect == EFFECT_BIDE) + { + if ((gHitMarker & HITMARKER_x8000000)) + return 1; + } + return 2; +} + +static void atkA9_sleeptalk_choose_move(void) +{ + s32 i; + u8 unusableMovesBits = 0; + + for (i = 0; i < 4; i++) + { + if (IsInvalidForSleepTalkOrAssist(gBattleMons[gBankAttacker].moves[i]) + || gBattleMons[gBankAttacker].moves[i] == MOVE_FOCUS_PUNCH + || gBattleMons[gBankAttacker].moves[i] == MOVE_UPROAR + || IsTwoTurnsMove(gBattleMons[gBankAttacker].moves[i])) + { + unusableMovesBits |= gBitTable[i]; + } + + } + + unusableMovesBits = CheckMoveLimitations(gBankAttacker, unusableMovesBits, ~(MOVE_LIMITATION_PP)); + if (unusableMovesBits == 0xF) // all 4 moves cannot be chosen + { + gBattlescriptCurrInstr += 5; + } + else // at least one move can be chosen + { + u32 movePosition; + + do + { + movePosition = Random() & 3; + } while ((gBitTable[movePosition] & unusableMovesBits)); + + gRandomMove = gBattleMons[gBankAttacker].moves[movePosition]; + gCurrMovePos = movePosition; + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gBankTarget = GetMoveTarget(gRandomMove, 0); + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkAA_set_destinybond(void) +{ + gBattleMons[gBankAttacker].status2 |= STATUS2_DESTINY_BOND; + gBattlescriptCurrInstr++; +} + +static void DestinyBondFlagUpdate(void) +{ + u8 sideAttacker = GetBankSide(gBankAttacker); + u8 sideTarget = GetBankSide(gBankTarget); + if (gBattleMons[gBankTarget].status2 & STATUS2_DESTINY_BOND + && sideAttacker != sideTarget + && !(gHitMarker & HITMARKER_GRUDGE)) + { + gHitMarker |= HITMARKER_DESTINYBOND; + } +} + +static void atkAB_DestinyBondFlagUpdate(void) +{ + DestinyBondFlagUpdate(); + gBattlescriptCurrInstr++; +} + +static void atkAC_remaininghptopower(void) +{ + s32 i; + s32 hpFraction = GetScaledHPFraction(gBattleMons[gBankAttacker].hp, gBattleMons[gBankAttacker].maxHP, 48); + + for (i = 0; i < (s32) sizeof(sFlailHpScaleToPowerTable); i += 2) + { + if (hpFraction <= sFlailHpScaleToPowerTable[i]) + break; + } + + gDynamicBasePower = sFlailHpScaleToPowerTable[i + 1]; + gBattlescriptCurrInstr++; +} + +static void atkAD_spite_ppreduce(void) +{ + if (gLastUsedMovesByBanks[gBankTarget] != 0 + && gLastUsedMovesByBanks[gBankTarget] != 0xFFFF) + { + s32 i; + + for (i = 0; i < 4; i++) + { + if (gLastUsedMovesByBanks[gBankTarget] == gBattleMons[gBankTarget].moves[i]) + break; + } + + if (i != 4 && gBattleMons[gBankTarget].pp[i] > 1) + { + s32 ppToDeduct = (Random() & 3) + 2; + if (gBattleMons[gBankTarget].pp[i] < ppToDeduct) + ppToDeduct = gBattleMons[gBankTarget].pp[i]; + + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastUsedMovesByBanks[gBankTarget]) + + ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, 0, 1); + + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct) + + gBattleMons[gBankTarget].pp[i] -= ppToDeduct; + gActiveBank = gBankTarget; + + if (!(gDisableStructs[gActiveBank].unk18_b & gBitTable[i]) + && !(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED)) + { + EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + i, 0, 1, &gBattleMons[gActiveBank].pp[i]); + MarkBufferBankForExecution(gActiveBank); + } + + gBattlescriptCurrInstr += 5; + + if (gBattleMons[gBankTarget].pp[i] == 0) + CancelMultiTurnMoves(gBankTarget); + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkAE_heal_party_status(void) +{ + u32 zero = 0; + u8 toHeal = 0; + + if (gCurrentMove == MOVE_HEAL_BELL) + { + struct Pokemon* party; + s32 i; + + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + if (gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF) + { + gBattleMons[gBankAttacker].status1 = 0; + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + } + else + { + RecordAbilityBattle(gBankAttacker, gBattleMons[gBankAttacker].ability); + gBattleCommunication[MULTISTRING_CHOOSER] |= 1; + } + + gActiveBank = gBattleScripting.bank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !(gAbsentBankFlags & gBitTable[gActiveBank])) + { + if (gBattleMons[gActiveBank].ability != ABILITY_SOUNDPROOF) + { + gBattleMons[gActiveBank].status1 = 0; + gBattleMons[gActiveBank].status2 &= ~(STATUS2_NIGHTMARE); + } + else + { + RecordAbilityBattle(gActiveBank, gBattleMons[gActiveBank].ability); + gBattleCommunication[MULTISTRING_CHOOSER] |= 2; + } + } + + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&party[i], MON_DATA_SPECIES2); + u8 abilityBit = GetMonData(&party[i], MON_DATA_ALT_ABILITY); + + if (species != 0 && species != SPECIES_EGG) + { + u8 ability; + + if (gBattlePartyID[gBankAttacker] == i) + ability = gBattleMons[gBankAttacker].ability; + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && gBattlePartyID[gActiveBank] == i + && !(gAbsentBankFlags & gBitTable[gActiveBank])) + ability = gBattleMons[gActiveBank].ability; + else + ability = GetAbilityBySpecies(species, abilityBit); + + if (ability != ABILITY_SOUNDPROOF) + toHeal |= (1 << i); + } + } + } + else // Aromatherapy + { + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + toHeal = 0x3F; + + gBattleMons[gBankAttacker].status1 = 0; + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + + gActiveBank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ 2); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !(gAbsentBankFlags & gBitTable[gActiveBank])) + { + gBattleMons[gActiveBank].status1 = 0; + gBattleMons[gActiveBank].status2 &= ~(STATUS2_NIGHTMARE); + } + + } + + if (toHeal) + { + gActiveBank = gBankAttacker; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, toHeal, 4, &zero); + MarkBufferBankForExecution(gActiveBank); + } + + gBattlescriptCurrInstr++; +} + +static void atkAF_cursetarget(void) +{ + if (gBattleMons[gBankTarget].status2 & STATUS2_CURSED) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMons[gBankTarget].status2 |= STATUS2_CURSED; + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattlescriptCurrInstr += 5; + } +} + +static void atkB0_set_spikes(void) +{ + u8 targetSide = GetBankSide(gBankAttacker) ^ BIT_SIDE; + + if (gSideTimers[targetSide].spikesAmount == 3) + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gSideAffecting[targetSide] |= SIDE_STATUS_SPIKES; + gSideTimers[targetSide].spikesAmount++; + gBattlescriptCurrInstr += 5; + } +} + +static void atkB1_set_foresight(void) +{ + gBattleMons[gBankTarget].status2 |= STATUS2_FORESIGHT; + gBattlescriptCurrInstr++; +} + +static void atkB2_setperishsong(void) +{ + s32 i; + s32 notAffectedCount = 0; + + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gStatuses3[i] & STATUS3_PERISH_SONG + || gBattleMons[i].ability == ABILITY_SOUNDPROOF) + { + notAffectedCount++; + } + else + { + gStatuses3[i] |= STATUS3_PERISH_SONG; + gDisableStructs[i].perishSong1 = 3; + gDisableStructs[i].perishSong2 = 3; + } + } + + PressurePPLoseOnUsingPerishSong(gBankAttacker); + + if (notAffectedCount == gNoOfAllBanks) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; +} + +static void atkB3_rolloutdamagecalculation(void) +{ + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) + { + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_PauseEffectivenessSoundResultMsgEndMove; + } + else + { + s32 i; + + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) // first hit + { + gDisableStructs[gBankAttacker].rolloutTimer1 = 5; + gDisableStructs[gBankAttacker].rolloutTimer2 = 5; + gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gBankAttacker] = gCurrentMove; + } + if (--gDisableStructs[gBankAttacker].rolloutTimer1 == 0) // last hit + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS); + } + + gDynamicBasePower = gBattleMoves[gCurrentMove].power; + + for (i = 1; i < (5 - gDisableStructs[gBankAttacker].rolloutTimer1); i++) + gDynamicBasePower *= 2; + + if (gBattleMons[gBankAttacker].status2 & STATUS2_DEFENSE_CURL) + gDynamicBasePower *= 2; + + gBattlescriptCurrInstr++; + } +} + +static void atkB4_jumpifconfusedandstatmaxed(void) +{ + if (gBattleMons[gBankTarget].status2 & STATUS2_CONFUSION + && gBattleMons[gBankTarget].statStages[gBattlescriptCurrInstr[1]] == 0xC) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; +} + +static void atkB5_furycuttercalc(void) +{ + if (gBattleMoveFlags & MOVESTATUS_NOEFFECT) + { + gDisableStructs[gBankAttacker].furyCutterCounter = 0; + gBattlescriptCurrInstr = BattleScript_PauseEffectivenessSoundResultMsgEndMove; + } + else + { + s32 i; + + if (gDisableStructs[gBankAttacker].furyCutterCounter != 5) + gDisableStructs[gBankAttacker].furyCutterCounter++; + + gDynamicBasePower = gBattleMoves[gCurrentMove].power; + + for (i = 1; i < gDisableStructs[gBankAttacker].furyCutterCounter; i++) + gDynamicBasePower *= 2; + + gBattlescriptCurrInstr++; + } +} + +static void atkB6_happinesstodamagecalculation(void) +{ + if (gBattleMoves[gCurrentMove].effect == EFFECT_RETURN) + gDynamicBasePower = 10 * (gBattleMons[gBankAttacker].friendship) / 25; + else // EFFECT_FRUSTRATION + gDynamicBasePower = 10 * (255 - gBattleMons[gBankAttacker].friendship) / 25; + + gBattlescriptCurrInstr++; +} + +static void atkB7_presentdamagecalculation(void) +{ + s32 rand = Random() & 0xFF; + + if (rand < 102) + gDynamicBasePower = 40; + else if (rand < 178) + gDynamicBasePower = 80; + else if (rand < 204) + gDynamicBasePower = 120; + else + { + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + } + if (rand < 204) + gBattlescriptCurrInstr = BattleScript_PresentDamageTarget; + else if (gBattleMons[gBankTarget].maxHP == gBattleMons[gBankTarget].hp) + gBattlescriptCurrInstr = BattleScript_AlreadyAtFullHp; + else + { + gBattleMoveFlags &= ~(MOVESTATUS_NOTAFFECTED); + gBattlescriptCurrInstr = BattleScript_PresentHealTarget; + } +} + +static void atkB8_set_safeguard(void) +{ + if (gSideAffecting[GET_BANK_SIDE(gBankAttacker)] & SIDE_STATUS_SAFEGUARD) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gSideAffecting[GET_BANK_SIDE(gBankAttacker)] |= SIDE_STATUS_SAFEGUARD; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].safeguardTimer = 5; + gSideTimers[GET_BANK_SIDE(gBankAttacker)].safeguardBank = gBankAttacker; + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + } + + gBattlescriptCurrInstr++; +} + +static void atkB9_magnitudedamagecalculation(void) +{ + s32 magnitude = Random() % 100; + + if (magnitude < 5) + { + gDynamicBasePower = 10; + magnitude = 4; + } + else if (magnitude < 15) + { + gDynamicBasePower = 30; + magnitude = 5; + } + else if (magnitude < 35) + { + gDynamicBasePower = 50; + magnitude = 6; + } + else if (magnitude < 65) + { + gDynamicBasePower = 70; + magnitude = 7; + } + else if (magnitude < 85) + { + gDynamicBasePower = 90; + magnitude = 8; + } + else if (magnitude < 95) + { + gDynamicBasePower = 110; + magnitude = 9; + } + else + { + gDynamicBasePower = 150; + magnitude = 10; + } + + + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 2, magnitude) + + for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBankFlags & gBitTable[gBankTarget])) // a valid target was found + break; + } + + gBattlescriptCurrInstr++; +} + +static void atkBA_jumpifnopursuitswitchdmg(void) +{ + if (gMultiHitCounter == 1) + { + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + gBankTarget = GetBankByIdentity(IDENTITY_OPPONENT_MON1); + else + gBankTarget = GetBankByIdentity(IDENTITY_PLAYER_MON1); + } + else + { + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + gBankTarget = GetBankByIdentity(IDENTITY_OPPONENT_MON2); + else + gBankTarget = GetBankByIdentity(IDENTITY_PLAYER_MON2); + } + + if (gActionForBanks[gBankTarget] == 0 + && gBankAttacker == *(gBattleStruct->moveTarget + gBankTarget) + && !(gBattleMons[gBankTarget].status1 & (STATUS_SLEEP | STATUS_FREEZE)) + && gBattleMons[gBankAttacker].hp + && !gDisableStructs[gBankTarget].truantCounter + && gChosenMovesByBanks[gBankTarget] == MOVE_PURSUIT) + { + s32 i; + + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gTurnOrder[i] == gBankTarget) + gUnknown_0202407A[i] = 11; + } + + gCurrentMove = MOVE_PURSUIT; + gCurrMovePos = gUnknown_020241E9 = *(gBattleStruct->chosenMovesIds + gBankTarget); + gBattlescriptCurrInstr += 5; + gBattleScripting.animTurn = 1; + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkBB_setsunny(void) +{ + if (gBattleWeather & WEATHER_SUN_ANY) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_SUN_TEMPORARY; + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + gWishFutureKnock.weatherDuration = 5; + } + + gBattlescriptCurrInstr++; +} + +static void atkBC_maxattackhalvehp(void) // belly drum +{ + u32 halfHp = gBattleMons[gBankAttacker].maxHP / 2; + + if (!(gBattleMons[gBankAttacker].maxHP / 2)) + halfHp = 1; + + if (gBattleMons[gBankAttacker].statStages[STAT_STAGE_ATK] < 12 + && gBattleMons[gBankAttacker].hp > halfHp) + { + gBattleMons[gBankAttacker].statStages[STAT_STAGE_ATK] = 12; + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkBD_copyfoestats(void) // psych up +{ + s32 i; + + for (i = 0; i < BATTLE_STATS_NO; i++) + { + gBattleMons[gBankAttacker].statStages[i] = gBattleMons[gBankTarget].statStages[i]; + } + + gBattlescriptCurrInstr += 5; // Has an unused jump ptr(possibly for a failed attempt) parameter. +} + +static void atkBE_rapidspinfree(void) +{ + if (gBattleMons[gBankAttacker].status2 & STATUS2_WRAPPED) + { + gBattleScripting.bank = gBankTarget; + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_WRAPPED); + gBankTarget = *(gBattleStruct->wrappedBy + gBankAttacker); + + gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN; + gBattleTextBuff1[1] = B_BUFF_MOVE; + gBattleTextBuff1[2] = *(gBattleStruct->wrappedMove + gBankAttacker * 2 + 0); + gBattleTextBuff1[3] = *(gBattleStruct->wrappedMove + gBankAttacker * 2 + 1); + gBattleTextBuff1[4] = B_BUFF_EOS; + + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_WrapFree; + } + else if (gStatuses3[gBankAttacker] & STATUS3_LEECHSEED) + { + gStatuses3[gBankAttacker] &= ~(STATUS3_LEECHSEED); + gStatuses3[gBankAttacker] &= ~(STATUS3_LEECHSEED_BANK); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_LeechSeedFree; + } + else if (gSideAffecting[GetBankSide(gBankAttacker)] & SIDE_STATUS_SPIKES) + { + gSideAffecting[GetBankSide(gBankAttacker)] &= ~(SIDE_STATUS_SPIKES); + gSideTimers[GetBankSide(gBankAttacker)].spikesAmount = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SpikesFree; + } + else + { + gBattlescriptCurrInstr++; + } +} + +static void atkBF_set_defense_curl(void) +{ + gBattleMons[gBankAttacker].status2 |= STATUS2_DEFENSE_CURL; + gBattlescriptCurrInstr++; +} + +static void atkC0_recoverbasedonsunlight(void) +{ + gBankTarget = gBankAttacker; + + if (gBattleMons[gBankAttacker].hp != gBattleMons[gBankAttacker].maxHP) + { + if (gBattleWeather == 0 || !WEATHER_HAS_EFFECT) + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; + else if (gBattleWeather & WEATHER_SUN_ANY) + gBattleMoveDamage = 20 * gBattleMons[gBankAttacker].maxHP / 30; + else // not sunny weather + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4; + + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +#ifdef NONMATCHING +static void atkC1_hidden_power(void) +{ + s32 powerBits; + s32 typeBits; + + powerBits = ((gBattleMons[gBankAttacker].hpIV & 2) >> 1) + | ((gBattleMons[gBankAttacker].attackIV & 2) << 0) + | ((gBattleMons[gBankAttacker].defenseIV & 2) << 1) + | ((gBattleMons[gBankAttacker].speedIV & 2) << 2) + | ((gBattleMons[gBankAttacker].spAttackIV & 2) << 3) + | ((gBattleMons[gBankAttacker].spDefenseIV & 2) << 4); + + typeBits = ((gBattleMons[gBankAttacker].hpIV & 1) << 0) + | ((gBattleMons[gBankAttacker].attackIV & 1) << 1) + | ((gBattleMons[gBankAttacker].defenseIV & 1) << 2) + | ((gBattleMons[gBankAttacker].speedIV & 1) << 3) + | ((gBattleMons[gBankAttacker].spAttackIV & 1) << 4) + | ((gBattleMons[gBankAttacker].spDefenseIV & 1) << 5); + + gDynamicBasePower = (40 * powerBits) / 63 + 30; + + gBattleStruct->dynamicMoveType = (15 * typeBits) / 63 + 1; + if (gBattleStruct->dynamicMoveType > 8) + gBattleStruct->dynamicMoveType++; + gBattleStruct->dynamicMoveType |= 0xC0; + + gBattlescriptCurrInstr++; +} + +#else +__attribute__((naked)) +static void atkC1_hidden_power(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + ldr r2, =gBattleMons\n\ + ldr r0, =gBankAttacker\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + adds r4, r1, 0\n\ + muls r4, r0\n\ + adds r4, r2\n\ + ldrb r0, [r4, 0x14]\n\ + mov r10, r0\n\ + mov r7, r10\n\ + lsls r7, 27\n\ + adds r0, r7, 0\n\ + lsrs r0, 27\n\ + mov r10, r0\n\ + movs r1, 0x2\n\ + mov r2, r10\n\ + ands r2, r1\n\ + asrs r2, 1\n\ + ldrh r7, [r4, 0x14]\n\ + mov r9, r7\n\ + mov r0, r9\n\ + lsls r0, 22\n\ + mov r9, r0\n\ + lsrs r3, r0, 27\n\ + adds r0, r1, 0\n\ + ands r0, r3\n\ + orrs r2, r0\n\ + ldrb r7, [r4, 0x15]\n\ + mov r8, r7\n\ + mov r0, r8\n\ + lsls r0, 25\n\ + mov r8, r0\n\ + lsrs r3, r0, 27\n\ + adds r0, r1, 0\n\ + ands r0, r3\n\ + lsls r0, 1\n\ + orrs r2, r0\n\ + ldr r6, [r4, 0x14]\n\ + lsls r6, 12\n\ + lsrs r3, r6, 27\n\ + adds r0, r1, 0\n\ + ands r0, r3\n\ + lsls r0, 2\n\ + orrs r2, r0\n\ + ldrh r5, [r4, 0x16]\n\ + lsls r5, 23\n\ + lsrs r3, r5, 27\n\ + adds r0, r1, 0\n\ + ands r0, r3\n\ + lsls r0, 3\n\ + orrs r2, r0\n\ + ldrb r3, [r4, 0x17]\n\ + lsls r3, 26\n\ + lsrs r0, r3, 27\n\ + ands r1, r0\n\ + lsls r1, 4\n\ + orrs r2, r1\n\ + movs r1, 0x1\n\ + adds r4, r1, 0\n\ + mov r7, r10\n\ + ands r4, r7\n\ + mov r0, r9\n\ + lsrs r0, 27\n\ + mov r9, r0\n\ + adds r0, r1, 0\n\ + mov r7, r9\n\ + ands r0, r7\n\ + lsls r0, 1\n\ + orrs r4, r0\n\ + mov r0, r8\n\ + lsrs r0, 27\n\ + mov r8, r0\n\ + adds r0, r1, 0\n\ + mov r7, r8\n\ + ands r0, r7\n\ + lsls r0, 2\n\ + orrs r4, r0\n\ + lsrs r6, 27\n\ + adds r0, r1, 0\n\ + ands r0, r6\n\ + lsls r0, 3\n\ + orrs r4, r0\n\ + lsrs r5, 27\n\ + adds r0, r1, 0\n\ + ands r0, r5\n\ + lsls r0, 4\n\ + orrs r4, r0\n\ + lsrs r3, 27\n\ + ands r1, r3\n\ + lsls r1, 5\n\ + orrs r4, r1\n\ + ldr r5, =gDynamicBasePower\n\ + lsls r0, r2, 2\n\ + adds r0, r2\n\ + lsls r0, 3\n\ + movs r1, 0x3F\n\ + bl __divsi3\n\ + adds r0, 0x1E\n\ + strh r0, [r5]\n\ + ldr r6, =gBattleStruct\n\ + ldr r5, [r6]\n\ + lsls r0, r4, 4\n\ + subs r0, r4\n\ + movs r1, 0x3F\n\ + bl __divsi3\n\ + adds r0, 0x1\n\ + strb r0, [r5, 0x13]\n\ + ldr r1, [r6]\n\ + ldrb r0, [r1, 0x13]\n\ + cmp r0, 0x8\n\ + bls _080544F0\n\ + adds r0, 0x1\n\ + strb r0, [r1, 0x13]\n\ +_080544F0:\n\ + ldr r2, [r6]\n\ + ldrb r0, [r2, 0x13]\n\ + movs r1, 0xC0\n\ + orrs r0, r1\n\ + strb r0, [r2, 0x13]\n\ + ldr r1, =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x1\n\ + str r0, [r1]\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} +#endif // NONMATCHING + +static void atkC2_selectnexttarget(void) +{ + for (gBankTarget = 0; gBankTarget < gNoOfAllBanks; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBankFlags & gBitTable[gBankTarget])) + break; + } + gBattlescriptCurrInstr++; +} + +static void atkC3_setfutureattack(void) +{ + if (gWishFutureKnock.futureSightCounter[gBankTarget] != 0) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gSideAffecting[GET_BANK_SIDE(gBankTarget)] |= SIDE_STATUS_FUTUREATTACK; + gWishFutureKnock.futureSightMove[gBankTarget] = gCurrentMove; + gWishFutureKnock.futureSightAttacker[gBankTarget] = gBankAttacker; + gWishFutureKnock.futureSightCounter[gBankTarget] = 3; + gWishFutureKnock.futureSightDmg[gBankTarget] = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, + gSideAffecting[GET_BANK_SIDE(gBankTarget)], 0, + 0, gBankAttacker, gBankTarget); + + if (gProtectStructs[gBankAttacker].helpingHand) + gWishFutureKnock.futureSightDmg[gBankTarget] = gWishFutureKnock.futureSightDmg[gBankTarget] * 15 / 10; + + if (gCurrentMove == MOVE_DOOM_DESIRE) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + + gBattlescriptCurrInstr += 5; + } +} + +static void atkC4_beat_up(void) +{ + struct Pokemon* party; + + if (GetBankSide(gBankAttacker) == SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + if (gBattleMons[gBankTarget].hp == 0) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + u8 beforeLoop = gBattleCommunication[0]; + for (;gBattleCommunication[0] < 6; gBattleCommunication[0]++) + { + if (GetMonData(&party[gBattleCommunication[0]], MON_DATA_HP) + && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) + && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) != SPECIES_EGG + && !GetMonData(&party[gBattleCommunication[0]], MON_DATA_STATUS)) + break; + } + if (gBattleCommunication[0] < 6) + { + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBankAttacker, gBattleCommunication[0]) + + gBattlescriptCurrInstr += 9; + + gBattleMoveDamage = gBaseStats[GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES)].baseAttack; + gBattleMoveDamage *= gBattleMoves[gCurrentMove].power; + gBattleMoveDamage *= (GetMonData(&party[gBattleCommunication[0]], MON_DATA_LEVEL) * 2 / 5 + 2); + gBattleMoveDamage /= gBaseStats[gBattleMons[gBankTarget].species].baseDefense; + gBattleMoveDamage = (gBattleMoveDamage / 50) + 2; + if (gProtectStructs[gBankAttacker].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; + + gBattleCommunication[0]++; + } + else if (beforeLoop != 0) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 5); + } +} + +static void atkC5_setsemiinvulnerablebit(void) +{ + switch (gCurrentMove) + { + case MOVE_FLY: + case MOVE_BOUNCE: + gStatuses3[gBankAttacker] |= STATUS3_ON_AIR; + break; + case MOVE_DIG: + gStatuses3[gBankAttacker] |= STATUS3_UNDERGROUND; + break; + case MOVE_DIVE: + gStatuses3[gBankAttacker] |= STATUS3_UNDERWATER; + break; + } + + gBattlescriptCurrInstr++; +} + +static void atkC6_clearsemiinvulnerablebit(void) +{ + switch (gCurrentMove) + { + case MOVE_FLY: + case MOVE_BOUNCE: + gStatuses3[gBankAttacker] &= ~STATUS3_ON_AIR; + break; + case MOVE_DIG: + gStatuses3[gBankAttacker] &= ~STATUS3_UNDERGROUND; + break; + case MOVE_DIVE: + gStatuses3[gBankAttacker] &= ~STATUS3_UNDERWATER; + break; + } + + gBattlescriptCurrInstr++; +} + +static void atkC7_setminimize(void) +{ + if (gHitMarker & HITMARKER_OBEYS) + gStatuses3[gBankAttacker] |= STATUS3_MINIMIZED; + + gBattlescriptCurrInstr++; +} + +static void atkC8_sethail(void) +{ + if (gBattleWeather & WEATHER_HAIL_ANY) + { + gBattleMoveFlags |= MOVESTATUS_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_HAIL; + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + gWishFutureKnock.weatherDuration = 5; + } + + gBattlescriptCurrInstr++; +} + +static void atkC9_jumpifattackandspecialattackcannotfall(void) // memento +{ + if (gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] == 0 + && gBattleMons[gBankTarget].statStages[STAT_STAGE_SPATK] == 0 + && gBattleCommunication[6] != 1) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gActiveBank = gBankAttacker; + gBattleMoveDamage = gBattleMons[gActiveBank].hp; + EmitHealthBarUpdate(0, 0x7FFF); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr += 5; + } +} + +static void atkCA_setforcedtarget(void) // follow me +{ + gSideTimers[GetBankSide(gBankAttacker)].followmeTimer = 1; + gSideTimers[GetBankSide(gBankAttacker)].followmeTarget = gBankAttacker; + gBattlescriptCurrInstr++; +} + +static void atkCB_setcharge(void) +{ + gStatuses3[gBankAttacker] |= STATUS3_CHARGED_UP; + gDisableStructs[gBankAttacker].chargeTimer1 = 2; + gDisableStructs[gBankAttacker].chargeTimer2 = 2; + gBattlescriptCurrInstr++; +} + +static void atkCC_callterrainattack(void) // nature power +{ + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gCurrentMove = sNaturePowerMoves[gBattleTerrain]; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); + gBattlescriptCurrInstr++; +} + +static void atkCD_cureifburnedparalysedorpoisoned(void) // refresh +{ + if (gBattleMons[gBankAttacker].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON)) + { + gBattleMons[gBankAttacker].status1 = 0; + gBattlescriptCurrInstr += 5; + gActiveBank = gBankAttacker; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkCE_settorment(void) +{ + if (gBattleMons[gBankTarget].status2 & STATUS2_TORMENT) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMons[gBankTarget].status2 |= STATUS2_TORMENT; + gBattlescriptCurrInstr += 5; + } +} + +static void atkCF_jumpifnodamage(void) +{ + if (gProtectStructs[gBankAttacker].physicalDmg || gProtectStructs[gBankAttacker].specialDmg) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); +} + +static void atkD0_settaunt(void) +{ + if (gDisableStructs[gBankTarget].tauntTimer1 == 0) + { + gDisableStructs[gBankTarget].tauntTimer1 = 2; + gDisableStructs[gBankTarget].tauntTimer2 = 2; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkD1_set_helpinghand(void) +{ + gBankTarget = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !(gAbsentBankFlags & gBitTable[gBankTarget]) + && !gProtectStructs[gBankAttacker].helpingHand + && !gProtectStructs[gBankTarget].helpingHand) + { + gProtectStructs[gBankTarget].helpingHand = 1; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkD2_swap_items(void) // trick +{ + // opponent can't swap items with player in regular battles + if (gBattleTypeFlags & BATTLE_TYPE_x4000000 + || (GetBankSide(gBankAttacker) == SIDE_OPPONENT + && !(gBattleTypeFlags & (BATTLE_TYPE_LINK + | BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_SECRET_BASE + | BATTLE_TYPE_x2000000)))) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + u8 sideAttacker = GetBankSide(gBankAttacker); + u8 sideTarget = GetBankSide(gBankTarget); + + // you can't swap items if they were knocked off in regular battles + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK + | BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_SECRET_BASE + | BATTLE_TYPE_x2000000)) + && (gWishFutureKnock.knockedOffPokes[sideAttacker] & gBitTable[gBattlePartyID[gBankAttacker]] + || gWishFutureKnock.knockedOffPokes[sideTarget] & gBitTable[gBattlePartyID[gBankTarget]])) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + // can't swap if two pokemon don't have an item + // or if either of them is an enigma berry or a mail + else if ((gBattleMons[gBankAttacker].item == 0 && gBattleMons[gBankTarget].item == 0) + || gBattleMons[gBankAttacker].item == ITEM_ENIGMA_BERRY + || gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY + || IS_ITEM_MAIL(gBattleMons[gBankAttacker].item) + || IS_ITEM_MAIL(gBattleMons[gBankTarget].item)) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + // check if ability prevents swapping + else if (gBattleMons[gBankTarget].ability == ABILITY_STICKY_HOLD) + { + gBattlescriptCurrInstr = BattleScript_StickyHoldActivates; + gLastUsedAbility = gBattleMons[gBankTarget].ability; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + // took a while, but all checks passed and items can be safely swapped + else + { + u16 oldItemAtk, *newItemAtk; + + newItemAtk = &gBattleStruct->changedItems[gBankAttacker]; + oldItemAtk = gBattleMons[gBankAttacker].item; + *newItemAtk = gBattleMons[gBankTarget].item; + + gBattleMons[gBankAttacker].item = 0; + gBattleMons[gBankTarget].item = oldItemAtk; + + gActiveBank = gBankAttacker; + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, newItemAtk); + MarkBufferBankForExecution(gBankAttacker); + + gActiveBank = gBankTarget; + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); + MarkBufferBankForExecution(gBankTarget); + + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 0) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankTarget]) + 1) = 0; + + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankAttacker]) + 0) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gBankAttacker]) + 1) = 0; + + gBattlescriptCurrInstr += 5; + + PREPARE_ITEM_BUFFER(gBattleTextBuff1, *newItemAtk) + PREPARE_ITEM_BUFFER(gBattleTextBuff2, oldItemAtk) + + if (oldItemAtk != 0 && *newItemAtk != 0) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; // attacker's item -> <- target's item + else if (oldItemAtk == 0 && *newItemAtk != 0) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; // nothing -> <- target's item + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; // attacker's item -> <- nothing + } + } +} + +static void atkD3_copy_ability(void) // role play +{ + if (gBattleMons[gBankTarget].ability != 0 + && gBattleMons[gBankTarget].ability != ABILITY_WONDER_GUARD) + { + gBattleMons[gBankAttacker].ability = gBattleMons[gBankTarget].ability; + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkD4_wish_effect(void) +{ + switch (gBattlescriptCurrInstr[1]) + { + case 0: // use wish + if (gWishFutureKnock.wishCounter[gBankAttacker] == 0) + { + gWishFutureKnock.wishCounter[gBankAttacker] = 2; + gWishFutureKnock.wishUserID[gBankAttacker] = gBattlePartyID[gBankAttacker]; + gBattlescriptCurrInstr += 6; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + } + break; + case 1: // heal effect + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBankTarget, gWishFutureKnock.wishUserID[gBankTarget]) + + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + + if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + + break; + } +} + +static void atkD5_setroots(void) // ingrain +{ + if (gStatuses3[gBankAttacker] & STATUS3_ROOTED) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gStatuses3[gBankAttacker] |= STATUS3_ROOTED; + gBattlescriptCurrInstr += 5; + } +} + +static void atkD6_doubledamagedealtifdamaged(void) +{ + if ((gProtectStructs[gBankAttacker].physicalDmg + && gProtectStructs[gBankAttacker].physicalBank == gBankTarget) + || (gProtectStructs[gBankAttacker].specialDmg + && gProtectStructs[gBankAttacker].specialBank == gBankTarget)) + { + gBattleScripting.dmgMultiplier = 2; + } + + gBattlescriptCurrInstr++; +} + +static void atkD7_setyawn(void) +{ + if (gStatuses3[gBankTarget] & STATUS3_YAWN + || gBattleMons[gBankTarget].status1 & STATUS_ANY) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gStatuses3[gBankTarget] |= 0x1000; + gBattlescriptCurrInstr += 5; + } +} + +static void atkD8_setdamagetohealthdifference(void) +{ + if (gBattleMons[gBankTarget].hp <= gBattleMons[gBankAttacker].hp) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMoveDamage = gBattleMons[gBankTarget].hp - gBattleMons[gBankAttacker].hp; + gBattlescriptCurrInstr += 5; + } +} + +static void atkD9_scaledamagebyhealthratio(void) +{ + if (gDynamicBasePower == 0) + { + u8 power = gBattleMoves[gCurrentMove].power; + gDynamicBasePower = gBattleMons[gBankAttacker].hp * power / gBattleMons[gBankAttacker].maxHP; + if (gDynamicBasePower == 0) + gDynamicBasePower = 1; + } + gBattlescriptCurrInstr++; +} + +static void atkDA_abilityswap(void) // skill swap +{ + if ((gBattleMons[gBankAttacker].ability == 0 + && gBattleMons[gBankTarget].ability == 0) + || gBattleMons[gBankAttacker].ability == ABILITY_WONDER_GUARD + || gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD + || gBattleMoveFlags & MOVESTATUS_NOEFFECT) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + u8 abilityAtk = gBattleMons[gBankAttacker].ability; + gBattleMons[gBankAttacker].ability = gBattleMons[gBankTarget].ability; + gBattleMons[gBankTarget].ability = abilityAtk; + + gBattlescriptCurrInstr += 5; + } +} + +static void atkDB_imprisoneffect(void) +{ + if ((gStatuses3[gBankAttacker] & STATUS3_IMPRISONED_OTHERS)) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + u8 bank, sideAttacker; + + sideAttacker = GetBankSide(gBankAttacker); + PressurePPLoseOnUsingImprision(gBankAttacker); + for (bank = 0; bank < gNoOfAllBanks; bank++) + { + if (sideAttacker != GetBankSide(bank)) + { + s32 attackerMoveId; + for (attackerMoveId = 0; attackerMoveId < 4; attackerMoveId++) + { + s32 i; + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankAttacker].moves[attackerMoveId] == gBattleMons[bank].moves[i] + && gBattleMons[gBankAttacker].moves[attackerMoveId] != MOVE_NONE) + break; + } + if (i != 4) + break; + } + if (attackerMoveId != 4) + { + gStatuses3[gBankAttacker] |= STATUS3_IMPRISONED_OTHERS; + gBattlescriptCurrInstr += 5; + break; + } + } + } + if (bank == gNoOfAllBanks) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkDC_setgrudge(void) +{ + if (gStatuses3[gBankAttacker] & STATUS3_GRUDGE) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gStatuses3[gBankAttacker] |= STATUS3_GRUDGE; + gBattlescriptCurrInstr += 5; + } +} + +static void atkDD_weightdamagecalculation(void) +{ + s32 i; + for (i = 0; sWeightToDamageTable[i] != 0xFFFF; i += 2) + { + if (sWeightToDamageTable[i] > GetPokedexHeightWeight(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 1)) + break; + } + + if (sWeightToDamageTable[i] != 0xFFFF) + gDynamicBasePower = sWeightToDamageTable[i + 1]; + else + gDynamicBasePower = 120; + + gBattlescriptCurrInstr++; +} + +static void atkDE_asistattackselect(void) +{ + s32 chooseableMovesNo = 0; + struct Pokemon* party; + s32 monId, moveId; + u16* movesArray = gBattleStruct->assistPossibleMoves; + + if (GET_BANK_SIDE(gBankAttacker) != SIDE_PLAYER) + party = gEnemyParty; + else + party = gPlayerParty; + + for (monId = 0; monId < 6; monId++) + { + if (monId == gBattlePartyID[gBankAttacker]) + continue; + if (GetMonData(&party[monId], MON_DATA_SPECIES2) == SPECIES_NONE) + continue; + if (GetMonData(&party[monId], MON_DATA_SPECIES2) == SPECIES_EGG) + continue; + + for (moveId = 0; moveId < 4; moveId++) + { + s32 i = 0; + u16 move = GetMonData(&party[monId], MON_DATA_MOVE1 + moveId); + + if (IsInvalidForSleepTalkOrAssist(move)) + continue; + + for (; sMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END && move != sMovesForbiddenToCopy[i]; i++); + + if (sMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END) + continue; + if (move == MOVE_NONE) + continue; + + movesArray[chooseableMovesNo] = move; + chooseableMovesNo++; + } + } + if (chooseableMovesNo) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gRandomMove = movesArray[((Random() & 0xFF) * chooseableMovesNo) >> 8]; + gBankTarget = GetMoveTarget(gRandomMove, 0); + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkDF_setmagiccoat(void) +{ + gBankTarget = gBankAttacker; + gSpecialStatuses[gBankAttacker].flag20 = 1; + if (gCurrentMoveTurn == gNoOfAllBanks - 1) // moves last turn + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gProtectStructs[gBankAttacker].bounceMove = 1; + gBattlescriptCurrInstr += 5; + } +} + +static void atkE0_setstealstatchange(void) // snatch +{ + gSpecialStatuses[gBankAttacker].flag20 = 1; + if (gCurrentMoveTurn == gNoOfAllBanks - 1) // moves last turn + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + gProtectStructs[gBankAttacker].stealMove = 1; + gBattlescriptCurrInstr += 5; + } +} + +static void atkE1_intimidate_string_loader(void) +{ + u8 side; + + gBattleScripting.bank = gBattleStruct->intimidateBank; + side = GetBankSide(gBattleScripting.bank); + + PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gBattleMons[gBattleScripting.bank].ability) + + for (;gBankTarget < gNoOfAllBanks; gBankTarget++) + { + if (GetBankSide(gBankTarget) == side) + continue; + if (!(gAbsentBankFlags & gBitTable[gBankTarget])) + break; + } + + if (gBankTarget >= gNoOfAllBanks) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; +} + +static void atkE2_switchout_abilities(void) +{ + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + switch (gBattleMons[gActiveBank].ability) + { + case ABILITY_NATURAL_CURE: + gBattleMons[gActiveBank].status1 = 0; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBank)], 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + break; + } + + gBattlescriptCurrInstr += 2; +} + +static void atkE3_jumpifhasnohp(void) +{ + gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]); + + if (gBattleMons[gActiveBank].hp == 0) + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; +} + +static void atkE4_getsecretpowereffect(void) +{ + switch (gBattleTerrain) + { + case BATTLE_TERRAIN_GRASS: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_POISON; + break; + case BATTLE_TERRAIN_LONG_GRASS: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_SLEEP; + break; + case BATTLE_TERRAIN_SAND: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_ACC_MINUS_1; + break; + case BATTLE_TERRAIN_UNDERWATER: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_DEF_MINUS_1; + break; + case BATTLE_TERRAIN_WATER: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_ATK_MINUS_1; + break; + case BATTLE_TERRAIN_POND: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_SPD_MINUS_1; + break; + case BATTLE_TERRAIN_ROCK: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_CONFUSION; + break; + case BATTLE_TERRAIN_CAVE: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_FLINCH; + break; + default: + gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_PARALYSIS; + break; + } + gBattlescriptCurrInstr++; +} + +static void atkE5_pickup(void) +{ + if (!InBattlePike()) + { + s32 i; + u16 species, heldItem; + u8 ability; + + if (InBattlePyramid()) + { + for (i = 0; i < 6; i++) + { + species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); + heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + + if (GetMonData(&gPlayerParty[i], MON_DATA_ALT_ABILITY)) + ability = gBaseStats[species].ability2; + else + ability = gBaseStats[species].ability1; + + if (ability == ABILITY_PICKUP + && species != 0 + && species != SPECIES_EGG + && heldItem == ITEM_NONE + && (Random() % 10) == 0) + { + heldItem = GetBattlePyramidPickupItemId(); + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &heldItem); + } + } + } + else + { + for (i = 0; i < 6; i++) + { + species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); + heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + + if (GetMonData(&gPlayerParty[i], MON_DATA_ALT_ABILITY)) + ability = gBaseStats[species].ability2; + else + ability = gBaseStats[species].ability1; + + if (ability == ABILITY_PICKUP + && species != 0 + && species != SPECIES_EGG + && heldItem == ITEM_NONE + && (Random() % 10) == 0) + { + s32 j; + s32 rand = Random() % 100; + u8 lvlDivBy10 = (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL) - 1) / 10; + if (lvlDivBy10 > 9) + lvlDivBy10 = 9; + + for (j = 0; j < 9; j++) + { + if (sPickupProbabilities[j] > rand) + { + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sPickupItems[lvlDivBy10 + j]); + break; + } + else if (rand == 99 || rand == 98) + { + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sRarePickupItems[lvlDivBy10 + (99 - rand)]); + break; + } + } + } + } + } + } + + gBattlescriptCurrInstr++; +} + +static void atkE6_castform_change_animation(void) +{ + gActiveBank = gBattleScripting.bank; + + if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE) + *(&gBattleStruct->formToChangeInto) |= 0x80; + + EmitBattleAnimation(0, B_ANIM_CASTFORM_CHANGE, gBattleStruct->formToChangeInto); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr++; +} + +static void atkE7_castform_data_change(void) +{ + u8 form; + + gBattlescriptCurrInstr++; + form = CastformDataTypeChange(gBattleScripting.bank); + if (form) + { + BattleScriptPushCursorAndCallback(BattleScript_CastformChange); + *(&gBattleStruct->formToChangeInto) = form - 1; + } +} + +static void atkE8_settypebasedhalvers(void) // water and mud sport +{ + bool8 worked = FALSE; + + if (gBattleMoves[gCurrentMove].effect == EFFECT_MUD_SPORT) + { + if (!(gStatuses3[gBankAttacker] & STATUS3_MUDSPORT)) + { + gStatuses3[gBankAttacker] |= STATUS3_MUDSPORT; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + worked = TRUE; + } + } + else // water sport + { + if (!(gStatuses3[gBankAttacker] & STATUS3_WATERSPORT)) + { + gStatuses3[gBankAttacker] |= STATUS3_WATERSPORT; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + worked = TRUE; + } + } + + if (worked) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); +} + +static void atkE9_setweatherballtype(void) +{ + if (WEATHER_HAS_EFFECT) + { + if (gBattleWeather & WEATHER_ANY) + gBattleScripting.dmgMultiplier = 2; + if (gBattleWeather & WEATHER_RAIN_ANY) + *(&gBattleStruct->dynamicMoveType) = TYPE_WATER | 0x80; + else if (gBattleWeather & WEATHER_SANDSTORM_ANY) + *(&gBattleStruct->dynamicMoveType) = TYPE_ROCK | 0x80; + else if (gBattleWeather & WEATHER_SUN_ANY) + *(&gBattleStruct->dynamicMoveType) = TYPE_FIRE | 0x80; + else if (gBattleWeather & WEATHER_HAIL_ANY) + *(&gBattleStruct->dynamicMoveType) = TYPE_ICE | 0x80; + else + *(&gBattleStruct->dynamicMoveType) = TYPE_NORMAL | 0x80; + } + + gBattlescriptCurrInstr++; +} + +static void atkEA_recycleitem(void) +{ + u16 *usedHeldItem; + + gActiveBank = gBankAttacker; + usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBank]; + if (*usedHeldItem != 0 && gBattleMons[gActiveBank].item == 0) + { + gLastUsedItem = *usedHeldItem; + *usedHeldItem = 0; + gBattleMons[gActiveBank].item = gLastUsedItem; + + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBank].item); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkEB_settypetoterrain(void) +{ + if (gBattleMons[gBankAttacker].type1 != sTerrainToType[gBattleTerrain] + && gBattleMons[gBankAttacker].type2 != sTerrainToType[gBattleTerrain]) + { + gBattleMons[gBankAttacker].type1 = sTerrainToType[gBattleTerrain]; + gBattleMons[gBankAttacker].type2 = sTerrainToType[gBattleTerrain]; + + PREPARE_TYPE_BUFFER(gBattleTextBuff1, sTerrainToType[gBattleTerrain]) + + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkEC_pursuit_sth(void) +{ + gActiveBank = GetBankByIdentity(GetBankIdentity(gBankAttacker) ^ BIT_MON); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && !(gAbsentBankFlags & gBitTable[gActiveBank]) + && gActionForBanks[gActiveBank] == 0 + && gChosenMovesByBanks[gActiveBank] == MOVE_PURSUIT) + { + gUnknown_0202407A[gActiveBank] = 11; + gCurrentMove = MOVE_PURSUIT; + gBattlescriptCurrInstr += 5; + gBattleScripting.animTurn = 1; + gBattleScripting.field_20 = gBankAttacker; + gBankAttacker = gActiveBank; + } + else + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } +} + +static void atkED_802B4B4(void) +{ + gEffectBank = gBankAttacker; + + if (gBankAttacker == gBankTarget) + gBankAttacker = gBankTarget = gBattleScripting.bank; + else + gBankTarget = gBattleScripting.bank; + + gBattleScripting.bank = gEffectBank; + gBattlescriptCurrInstr++; +} + +static void atkEE_removelightscreenreflect(void) // brick break +{ + u8 opposingSide = GetBankSide(gBankAttacker) ^ BIT_SIDE; + + if (gSideTimers[opposingSide].reflectTimer || gSideTimers[opposingSide].lightscreenTimer) + { + gSideAffecting[opposingSide] &= ~(SIDE_STATUS_REFLECT); + gSideAffecting[opposingSide] &= ~(SIDE_STATUS_LIGHTSCREEN); + gSideTimers[opposingSide].reflectTimer = 0; + gSideTimers[opposingSide].lightscreenTimer = 0; + gBattleScripting.animTurn = 1; + gBattleScripting.animTargetsHit = 1; + } + else + { + gBattleScripting.animTurn = 0; + gBattleScripting.animTargetsHit = 0; + } + + gBattlescriptCurrInstr++; +} + +static void atkEF_pokeball_catch_calculation(void) +{ + u8 ballMultiplier = 0; + + if (gBattleExecBuffer) + return; + + gActiveBank = gBankAttacker; + gBankTarget = gBankAttacker ^ BIT_SIDE; + + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + EmitBallThrow(0, BALL_TRAINER_BLOCK); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr = BattleScript_TrainerBallBlock; + } + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) + { + EmitBallThrow(0, BALL_3_SHAKES_SUCCESS); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr = BattleScript_WallyBallThrow; + } + else + { + u32 odds; + u8 catchRate; + + if (gLastUsedItem == ITEM_SAFARI_BALL) + catchRate = gBattleStruct->field_7C * 1275 / 100; + else + catchRate = gBaseStats[gBattleMons[gBankTarget].species].catchRate; + + if (gLastUsedItem > ITEM_SAFARI_BALL) + { + switch (gLastUsedItem) + { + case ITEM_NET_BALL: + if (gBattleMons[gBankTarget].type1 == TYPE_WATER + || gBattleMons[gBankTarget].type2 == TYPE_WATER + || gBattleMons[gBankTarget].type1 == TYPE_BUG + || gBattleMons[gBankTarget].type2 == TYPE_BUG) + ballMultiplier = 30; + else + ballMultiplier = 10; + break; + case ITEM_DIVE_BALL: + if (sav1_map_get_light_level() == 5) + ballMultiplier = 35; + else + ballMultiplier = 10; + break; + case ITEM_NEST_BALL: + if (gBattleMons[gBankTarget].level <= 39) + { + ballMultiplier = 40 - gBattleMons[gBankTarget].level; + if (ballMultiplier <= 9) + ballMultiplier = 10; + } + else + { + ballMultiplier = 10; + } + break; + case ITEM_REPEAT_BALL: + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), FLAG_GET_CAUGHT)) + ballMultiplier = 30; + else + ballMultiplier = 10; + break; + case ITEM_TIMER_BALL: + ballMultiplier = gBattleResults.battleTurnCounter + 10; + if (ballMultiplier > 40) + ballMultiplier = 40; + break; + case ITEM_LUXURY_BALL: + case ITEM_PREMIER_BALL: + ballMultiplier = 10; + break; + } + } + else + ballMultiplier = sBallCatchBonuses[gLastUsedItem - 2]; + + odds = (catchRate * ballMultiplier / 10) + * (gBattleMons[gBankTarget].maxHP * 3 - gBattleMons[gBankTarget].hp * 2) + / (3 * gBattleMons[gBankTarget].maxHP); + + if (gBattleMons[gBankTarget].status1 & (STATUS_SLEEP | STATUS_FREEZE)) + odds *= 2; + if (gBattleMons[gBankTarget].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON)) + odds = (odds * 15) / 10; + + if (gLastUsedItem != ITEM_SAFARI_BALL) + { + if (gLastUsedItem == ITEM_MASTER_BALL) + { + gBattleResults.unk5_1 = 1; + } + else + { + if (gBattleResults.catchAttempts[gLastUsedItem - ITEM_ULTRA_BALL] < 0xFF) + gBattleResults.catchAttempts[gLastUsedItem - ITEM_ULTRA_BALL]++; + } + } + + if (odds > 254) // mon caught + { + EmitBallThrow(0, BALL_3_SHAKES_SUCCESS); + MarkBufferBankForExecution(gActiveBank); + gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; + SetMonData(&gEnemyParty[gBattlePartyID[gBankTarget]], MON_DATA_POKEBALL, &gLastUsedItem); + + if (CalculatePlayerPartyCount() == 6) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else // mon may be caught, calculate shakes + { + u8 shakes; + + odds = Sqrt(Sqrt(16711680 / odds)); + odds = 1048560 / odds; + + for (shakes = 0; shakes < 4 && Random() < odds; shakes++); + + if (gLastUsedItem == ITEM_MASTER_BALL) + shakes = BALL_3_SHAKES_SUCCESS; // why calculate the shakes before that check? + + EmitBallThrow(0, shakes); + MarkBufferBankForExecution(gActiveBank); + + if (shakes == BALL_3_SHAKES_SUCCESS) // mon caught, copy of the code above + { + gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; + SetMonData(&gEnemyParty[gBattlePartyID[gBankTarget]], MON_DATA_POKEBALL, &gLastUsedItem); + + if (CalculatePlayerPartyCount() == 6) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else // not caught + { + gBattleCommunication[MULTISTRING_CHOOSER] = shakes; + gBattlescriptCurrInstr = BattleScript_ShakeBallThrow; + } + } + } +} + +static void atkF0_give_caught_mon(void) +{ + if (GiveMonToPlayer(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]]) != MON_GIVEN_TO_PARTY) + { + if (!sub_813B21C()) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + StringCopy(gStringVar1, GetBoxNamePtr(VarGet(VAR_STORAGE_UNKNOWN))); + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gStringVar2); + } + else + { + StringCopy(gStringVar1, GetBoxNamePtr(VarGet(VAR_STORAGE_UNKNOWN))); + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gStringVar2); + StringCopy(gStringVar3, GetBoxNamePtr(get_unknown_box_id())); + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + + if (FlagGet(SYS_PC_LANETTE)) + gBattleCommunication[MULTISTRING_CHOOSER]++; + } + + gBattleResults.caughtMonSpecies = GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_SPECIES, NULL); + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleResults.caughtMonNick); + gBattleResults.caughtMonBall = GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_POKEBALL, NULL); + + gBattlescriptCurrInstr++; +} + +static void atkF1_set_caught_mon_dex_flags(void) +{ + u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL); + u32 personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY, NULL); + + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)) + { + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + else + { + HandleSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_SET_CAUGHT, personality); + gBattlescriptCurrInstr += 5; + } +} + +static void atkF2_display_dex_info(void) +{ + u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL); + + switch (gBattleCommunication[0]) + { + case 0: + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + gBattleCommunication[0]++; + break; + case 1: + if (!gPaletteFade.active) + { + FreeAllWindowBuffers(); + gBattleCommunication[TASK_ID] = CreateDexDisplayMonDataTask(SpeciesToNationalPokedexNum(species), + gBattleMons[gBankTarget].otId, + gBattleMons[gBankTarget].personality); + gBattleCommunication[0]++; + } + break; + case 2: + if (!gPaletteFade.active + && gMain.callback2 == BattleMainCB2 + && !gTasks[gBattleCommunication[TASK_ID]].isActive) + { + SetVBlankCallback(VBlankCB_Battle); + gBattleCommunication[0]++; + } + break; + case 3: + c2_berry_program_update_menu(); + sub_8035AA4(); + gBattle_BG3_X = 0x100; + gBattleCommunication[0]++; + break; + case 4: + if (!IsDma3ManagerBusyWithBgCopy()) + { + BeginNormalPaletteFade(0xFFFF, 0, 0x10, 0, 0); + ShowBg(0); + ShowBg(3); + gBattleCommunication[0]++; + } + break; + case 5: + if (!gPaletteFade.active) + gBattlescriptCurrInstr++; + break; + } +} + +void sub_8056A3C(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags) +{ + s32 destY, destX; + u16 var = 0; + + for (destY = yStart; destY <= yEnd; destY++) + { + for (destX = xStart; destX <= xEnd; destX++) + { + if (destY == yStart) + { + if (destX == xStart) + var = 0x1022; + else if (destX == xEnd) + var = 0x1024; + else + var = 0x1023; + } + else if (destY == yEnd) + { + if (destX == xStart) + var = 0x1028; + else if (destX == xEnd) + var = 0x102A; + else + var = 0x1029; + } + else + { + if (destX == xStart) + var = 0x1025; + else if (destX == xEnd) + var = 0x1027; + else + var = 0x1026; + } + + if (flags & 1) + var = 0; + + if (flags & 0x80) + CopyToBgTilemapBufferRect_ChangePalette(1, &var, destX, destY, 1, 1, 0x11); + else + CopyToBgTilemapBufferRect_ChangePalette(0, &var, destX, destY, 1, 1, 0x11); + } + } +} + +void BattleCreateCursorAt(u8 cursorPosition) +{ + u16 src[2]; + src[0] = 1; + src[1] = 2; + + CopyToBgTilemapBufferRect_ChangePalette(0, src, 0x19, 9 + (2 * cursorPosition), 1, 2, 0x11); + CopyBgTilemapBufferToVram(0); +} + +void BattleDestroyCursorAt(u8 cursorPosition) +{ + u16 src[2]; + src[0] = 0x1016; + src[1] = 0x1016; + + CopyToBgTilemapBufferRect_ChangePalette(0, src, 0x19, 9 + (2 * cursorPosition), 1, 2, 0x11); + CopyBgTilemapBufferToVram(0); +} + +static void atkF3_nickname_caught_poke(void) +{ + switch (gBattleCommunication[MULTIUSE_STATE]) + { + case 0: + sub_8056A3C(0x18, 8, 0x1D, 0xD, 0); + sub_814F9EC(gText_BattleYesNoChoice, 0xC); + gBattleCommunication[MULTIUSE_STATE]++; + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 0; + BattleCreateCursorAt(0); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0) + { + PlaySE(SE_SELECT); + BattleDestroyCursorAt(gBattleCommunication[CURSOR_POSITION]); + gBattleCommunication[CURSOR_POSITION] = 1; + BattleCreateCursorAt(1); + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (gBattleCommunication[CURSOR_POSITION] == 0) + { + gBattleCommunication[MULTIUSE_STATE]++; + BeginFastPaletteFade(3); + } + else + { + gBattleCommunication[MULTIUSE_STATE] = 4; + } + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gBattleCommunication[MULTIUSE_STATE] = 4; + } + break; + case 2: + if (!gPaletteFade.active) + { + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleStruct->caughtMonNick); + FreeAllWindowBuffers(); + + DoNamingScreen(NAMING_SCREEN_CAUGHT_MON, gBattleStruct->caughtMonNick, + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_SPECIES), + GetMonGender(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]]), + GetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_PERSONALITY, NULL), + BattleMainCB2); + + gBattleCommunication[MULTIUSE_STATE]++; + } + break; + case 3: + if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active ) + { + SetMonData(&gEnemyParty[gBattlePartyID[gBankAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleStruct->caughtMonNick); + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + } + break; + case 4: + if (CalculatePlayerPartyCount() == 6) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); + break; + } +} + +static void atkF4_subattackerhpbydmg(void) +{ + gBattleMons[gBankAttacker].hp -= gBattleMoveDamage; + gBattlescriptCurrInstr++; +} + +static void atkF5_removeattackerstatus1(void) +{ + gBattleMons[gBankAttacker].status1 = 0; + gBattlescriptCurrInstr++; +} + +static void atkF6_802BF48(void) +{ + gFightStateTracker = 0xC; +} + +static void atkF7_802BF54(void) +{ + gFightStateTracker = 0xC; + gCurrentMoveTurn = gNoOfAllBanks; +} + +static void atkF8_trainer_slide_back(void) +{ + gActiveBank = GetBankByIdentity(gBattlescriptCurrInstr[1]); + EmitTrainerSlideBack(0); + MarkBufferBankForExecution(gActiveBank); + + gBattlescriptCurrInstr += 2; +} -- cgit v1.2.3 From 4dad58648fe65b7df90da45972518222853b2e98 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 28 Sep 2017 19:34:13 +0200 Subject: take revo suggestion --- src/battle_script_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 2e6b3dbae..e0cb3e941 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -11043,7 +11043,7 @@ static void atkEF_pokeball_catch_calculation(void) ballMultiplier = 10; break; case ITEM_NEST_BALL: - if (gBattleMons[gBankTarget].level <= 39) + if (gBattleMons[gBankTarget].level < 40) { ballMultiplier = 40 - gBattleMons[gBankTarget].level; if (ballMultiplier <= 9) -- cgit v1.2.3 From f1fe0c217d5366123c057da85b28b5c10ac9798d Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 28 Sep 2017 20:52:36 +0200 Subject: decompile roamer --- src/roamer.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 src/roamer.c (limited to 'src') diff --git a/src/roamer.c b/src/roamer.c new file mode 100644 index 000000000..cbe1b6312 --- /dev/null +++ b/src/roamer.c @@ -0,0 +1,218 @@ +#include "global.h" +#include "roamer.h" +#include "pokemon.h" +#include "rng.h" +#include "species.h" +#include "event_data.h" + +enum +{ + MAP_GRP = 0, // map group + MAP_NUM = 1, // map number +}; + +EWRAM_DATA static u8 sLocationHistory[3][2] = {0}; +EWRAM_DATA static u8 sRoamerLocation[2] = {0}; + +static const u8 sRoamerLocations[][6] = +{ + { 0x19, 0x1A, 0x20, 0x21, 0x31, 0xFF }, + { 0x1A, 0x19, 0x20, 0x21, 0xFF, 0xFF }, + { 0x20, 0x1A, 0x19, 0x21, 0xFF, 0xFF }, + { 0x21, 0x20, 0x19, 0x1A, 0x22, 0x26 }, + { 0x22, 0x21, 0x23, 0xFF, 0xFF, 0xFF }, + { 0x23, 0x22, 0x24, 0xFF, 0xFF, 0xFF }, + { 0x24, 0x23, 0x25, 0x26, 0xFF, 0xFF }, + { 0x25, 0x24, 0x26, 0xFF, 0xFF, 0xFF }, + { 0x26, 0x25, 0x21, 0xFF, 0xFF, 0xFF }, + { 0x27, 0x24, 0x28, 0x29, 0xFF, 0xFF }, + { 0x28, 0x27, 0x2A, 0xFF, 0xFF, 0xFF }, + { 0x29, 0x27, 0x2A, 0xFF, 0xFF, 0xFF }, + { 0x2A, 0x28, 0x29, 0x2B, 0xFF, 0xFF }, + { 0x2B, 0x2A, 0x2C, 0xFF, 0xFF, 0xFF }, + { 0x2C, 0x2B, 0x2D, 0xFF, 0xFF, 0xFF }, + { 0x2D, 0x2C, 0x2E, 0xFF, 0xFF, 0xFF }, + { 0x2E, 0x2D, 0x2F, 0xFF, 0xFF, 0xFF }, + { 0x2F, 0x2E, 0x30, 0xFF, 0xFF, 0xFF }, + { 0x30, 0x2F, 0x31, 0xFF, 0xFF, 0xFF }, + { 0x31, 0x30, 0x19, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, +}; + +void ClearRoamerData(void) +{ + memset(&gSaveBlock1Ptr->roamer, 0, sizeof(struct Roamer)); + (&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIAS; +} + +void ClearRoamerLocationData(void) +{ + u8 i; + + for (i = 0; i < 3; i++) + { + sLocationHistory[i][MAP_GRP] = 0; + sLocationHistory[i][MAP_NUM] = 0; + } + + sRoamerLocation[MAP_GRP] = 0; + sRoamerLocation[MAP_NUM] = 0; +} + +static void CreateInitialRoamerMon(bool16 createLatios) +{ + if (!createLatios) + (&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIAS; + else + (&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIOS; + + CreateMon(&gEnemyParty[0], (&gSaveBlock1Ptr->roamer)->species, 40, 0x20, 0, 0, 0, 0); + (&gSaveBlock1Ptr->roamer)->level = 40; + (&gSaveBlock1Ptr->roamer)->status = 0; + (&gSaveBlock1Ptr->roamer)->active = TRUE; + (&gSaveBlock1Ptr->roamer)->ivs = GetMonData(&gEnemyParty[0], MON_DATA_IVS); + (&gSaveBlock1Ptr->roamer)->personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY); + (&gSaveBlock1Ptr->roamer)->hp = GetMonData(&gEnemyParty[0], MON_DATA_MAX_HP); + (&gSaveBlock1Ptr->roamer)->cool = GetMonData(&gEnemyParty[0], MON_DATA_COOL); + (&gSaveBlock1Ptr->roamer)->beauty = GetMonData(&gEnemyParty[0], MON_DATA_BEAUTY); + (&gSaveBlock1Ptr->roamer)->cute = GetMonData(&gEnemyParty[0], MON_DATA_CUTE); + (&gSaveBlock1Ptr->roamer)->smart = GetMonData(&gEnemyParty[0], MON_DATA_SMART); + (&gSaveBlock1Ptr->roamer)->tough = GetMonData(&gEnemyParty[0], MON_DATA_TOUGH); + sRoamerLocation[MAP_GRP] = 0; + sRoamerLocation[MAP_NUM] = sRoamerLocations[Random() % 20][0]; +} + +void InitRoamer(void) +{ + ClearRoamerData(); + ClearRoamerLocationData(); + CreateInitialRoamerMon(gSpecialVar_0x8004); +} + +void UpdateLocationHistoryForRoamer(void) +{ + sLocationHistory[2][MAP_GRP] = sLocationHistory[1][MAP_GRP]; + sLocationHistory[2][MAP_NUM] = sLocationHistory[1][MAP_NUM]; + + sLocationHistory[1][MAP_GRP] = sLocationHistory[0][MAP_GRP]; + sLocationHistory[1][MAP_NUM] = sLocationHistory[0][MAP_NUM]; + + sLocationHistory[0][MAP_GRP] = gSaveBlock1Ptr->location.mapGroup; + sLocationHistory[0][MAP_NUM] = gSaveBlock1Ptr->location.mapNum; +} + +void RoamerMoveToOtherLocationSet(void) +{ + u8 val = 0; + struct Roamer *roamer = &gSaveBlock1Ptr->roamer; + + if (!roamer->active) + return; + + sRoamerLocation[MAP_GRP] = val; + + while (1) + { + val = sRoamerLocations[Random() % 20][0]; + if (sRoamerLocation[MAP_NUM] != val) + { + sRoamerLocation[MAP_NUM] = val; + return; + } + } +} + +void RoamerMove(void) +{ + u8 locSet = 0; + + if ((Random() % 16) == 0) + { + RoamerMoveToOtherLocationSet(); + } + else + { + struct Roamer *roamer = &gSaveBlock1Ptr->roamer; + + if (!roamer->active) + return; + + while (locSet < 20) + { + if (sRoamerLocation[MAP_NUM] == sRoamerLocations[locSet][0]) + { + u8 mapNum; + while (1) + { + mapNum = sRoamerLocations[locSet][(Random() % 5) + 1]; + if (!(sLocationHistory[2][MAP_GRP] == 0 && sLocationHistory[2][MAP_NUM] == mapNum) && mapNum != 0xFF) + break; + } + sRoamerLocation[MAP_NUM] = mapNum; + return; + } + locSet++; + } + } +} + +bool8 IsRoamerAt(u8 mapGroup, u8 mapNum) +{ + struct Roamer *roamer = &gSaveBlock1Ptr->roamer; + + if (roamer->active && mapGroup == sRoamerLocation[MAP_GRP] && mapNum == sRoamerLocation[MAP_NUM]) + return TRUE; + else + return FALSE; +} + +void CreateRoamerMonInstance(void) +{ + struct Pokemon *mon; + struct Roamer *roamer; + + mon = &gEnemyParty[0]; + ZeroEnemyPartyMons(); + roamer = &gSaveBlock1Ptr->roamer; + CreateMonWithIVsPersonality(mon, roamer->species, roamer->level, roamer->ivs, roamer->personality); + SetMonData(mon, MON_DATA_STATUS, &gSaveBlock1Ptr->roamer.status); + SetMonData(mon, MON_DATA_HP, &gSaveBlock1Ptr->roamer.hp); + SetMonData(mon, MON_DATA_COOL, &gSaveBlock1Ptr->roamer.cool); + SetMonData(mon, MON_DATA_BEAUTY, &gSaveBlock1Ptr->roamer.beauty); + SetMonData(mon, MON_DATA_CUTE, &gSaveBlock1Ptr->roamer.cute); + SetMonData(mon, MON_DATA_SMART, &gSaveBlock1Ptr->roamer.smart); + SetMonData(mon, MON_DATA_TOUGH, &gSaveBlock1Ptr->roamer.tough); +} + +bool8 TryStartRoamerEncounter(void) +{ + if (IsRoamerAt(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum) == TRUE && (Random() % 4) == 0) + { + CreateRoamerMonInstance(); + return TRUE; + } + else + { + return FALSE; + } +} + +void UpdateRoamerHPStatus(struct Pokemon *mon) +{ + (&gSaveBlock1Ptr->roamer)->hp = GetMonData(mon, MON_DATA_HP); + (&gSaveBlock1Ptr->roamer)->status = GetMonData(mon, MON_DATA_STATUS); + + RoamerMoveToOtherLocationSet(); +} + +void SetRoamerInactive(void) +{ + struct Roamer *roamer = &gSaveBlock1Ptr->roamer; + roamer->active = FALSE; +} + +void GetRoamerLocation(u8 *mapGroup, u8 *mapNum) +{ + *mapGroup = sRoamerLocation[MAP_GRP]; + *mapNum = sRoamerLocation[MAP_NUM]; +} -- cgit v1.2.3 From e41b9cbbb37c908f77a9ce440f33b76b35139311 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Fri, 29 Sep 2017 00:11:42 +0200 Subject: decompile money --- src/coins.c | 3 +- src/money.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/coins.c b/src/coins.c index 84a79f5f2..4ee601b22 100644 --- a/src/coins.c +++ b/src/coins.c @@ -4,14 +4,13 @@ #include "window.h" #include "text_window.h" #include "string_util.h" +#include "menu.h" #define MAX_COINS 9999 EWRAM_DATA u8 sCoinsWindowId = 0; extern s32 GetStringRightAlignXOffset(u8 fontId, u8 *str, s32 totalWidth); -extern void SetWindowTemplateFields(struct WindowTemplate* template, u8 priority, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height, u8 palNum, u16 baseBlock); -extern void SetWindowBorderStyle(u8 windowId, bool8 copyToVram, s16 tileStart, s8 palette); extern void sub_819746C(u8 windowId, bool8 copyToVram); extern const u8 gText_Coins[]; diff --git a/src/money.c b/src/money.c index be64d9633..65a45b158 100644 --- a/src/money.c +++ b/src/money.c @@ -1,8 +1,77 @@ #include "global.h" #include "money.h" +#include "event_data.h" +#include "string_util.h" +#include "text.h" +#include "menu.h" +#include "window.h" +#include "sprite.h" +#include "decompress.h" + +extern const u8 gText_PokedollarVar1[]; + +extern const u8 gMenuMoneyGfx[]; +extern const u8 gMenuMoneyPal[]; #define MAX_MONEY 999999 +EWRAM_DATA static u8 sMoneyBoxWindowId = 0; +EWRAM_DATA static u8 sMoneyLabelSpriteId = 0; + +#define MONEY_LABEL_TAG 0x2722 + +static const struct OamData sOamData_MoneyLabel = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 1, + .x = 0, + .matrixNum = 0, + .size = 2, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_MoneyLabel[] = +{ + ANIMCMD_FRAME(0, 0), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_MoneyLabel[] = +{ + sSpriteAnim_MoneyLabel, +}; + +static const struct SpriteTemplate sSpriteTemplate_MoneyLabel = +{ + .tileTag = MONEY_LABEL_TAG, + .paletteTag = MONEY_LABEL_TAG, + .oam = &sOamData_MoneyLabel, + .anims = sSpriteAnimTable_MoneyLabel, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct CompressedSpriteSheet sSpriteSheet_MoneyLabel = +{ + .data = gMenuMoneyGfx, + .size = 256, + .tag = MONEY_LABEL_TAG, +}; + +static const struct CompressedSpritePalette sSpritePalette_MoneyLabel = +{ + .data = gMenuMoneyPal, + .tag = MONEY_LABEL_TAG +}; + u32 GetMoney(u32* moneyPtr) { return *moneyPtr ^ gSaveBlock2Ptr->encryptionKey; @@ -53,3 +122,79 @@ void SubtractMoney(u32* moneyPtr, u32 toSub) SetMoney(moneyPtr, toSet); } + +bool8 IsEnoughForCostInVar0x8005(void) +{ + return IsEnoughMoney(&gSaveBlock1Ptr->money, gSpecialVar_0x8005); +} + +void SubtractMoneyFromVar0x8005(void) +{ + SubtractMoney(&gSaveBlock1Ptr->money, gSpecialVar_0x8005); +} + +void PrintMoneyAmountInMoneyBox(u8 windowId, int amount, u8 speed) +{ + PrintMoneyAmount(windowId, 0x26, 1, amount, speed); +} + +void PrintMoneyAmount(u8 windowId, u8 x, u8 y, int amount, u8 speed) +{ + u8 *txtPtr; + s32 strLength; + + ConvertIntToDecimalStringN(gStringVar1, amount, STR_CONV_MODE_LEFT_ALIGN, 6); + + strLength = 6 - StringLength(gStringVar1); + txtPtr = gStringVar4; + + while (strLength-- > 0) + *(txtPtr++) = 0x77; + + StringExpandPlaceholders(txtPtr, gText_PokedollarVar1); + PrintTextOnWindow(windowId, 1, gStringVar4, x, y, speed, NULL); +} + +void PrintMoneyAmountInMoneyBoxWithBorder(u8 windowId, u16 tileStart, u8 pallete, int amount) +{ + SetWindowBorderStyle(windowId, FALSE, tileStart, pallete); + PrintMoneyAmountInMoneyBox(windowId, amount, 0); +} + +void ChangeAmountInMoneyBox(int amount) +{ + PrintMoneyAmountInMoneyBox(sMoneyBoxWindowId, amount, 0); +} + +void DrawMoneyBox(int amount, u8 x, u8 y) +{ + struct WindowTemplate template; + + SetWindowTemplateFields(&template, 0, x + 1, y + 1, 10, 2, 15, 8); + sMoneyBoxWindowId = AddWindow(&template); + FillWindowPixelBuffer(sMoneyBoxWindowId, 0); + PutWindowTilemap(sMoneyBoxWindowId); + CopyWindowToVram(sMoneyBoxWindowId, 1); + PrintMoneyAmountInMoneyBoxWithBorder(sMoneyBoxWindowId, 0x214, 14, amount); + AddMoneyLabelObject((8 * x) + 19, (8 * y) + 11); +} + +void HideMoneyBox(void) +{ + RemoveMoneyLabelObject(); + sub_8198070(sMoneyBoxWindowId, FALSE); + CopyWindowToVram(sMoneyBoxWindowId, 2); + RemoveWindow(sMoneyBoxWindowId); +} + +void AddMoneyLabelObject(u16 x, u16 y) +{ + LoadCompressedObjectPic(&sSpriteSheet_MoneyLabel); + LoadCompressedObjectPalette(&sSpritePalette_MoneyLabel); + sMoneyLabelSpriteId = CreateSprite(&sSpriteTemplate_MoneyLabel, x, y, 0); +} + +void RemoveMoneyLabelObject(void) +{ + DestroySpriteAndFreeResources(&gSprites[sMoneyLabelSpriteId]); +} -- cgit v1.2.3 From 7b72c8376250f1f417f21fda34348fd1268e23f7 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Fri, 29 Sep 2017 10:06:36 +0200 Subject: finish save.c --- src/save.c | 162 ++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 95 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/save.c b/src/save.c index 5ca855247..aee20d451 100644 --- a/src/save.c +++ b/src/save.c @@ -2,12 +2,15 @@ #include "gba/flash_internal.h" #include "save.h" #include "game_stat.h" +#include "task.h" -extern struct SaveSectionOffsets gSaveSectionOffsets[0xE]; extern struct SaveSectionLocation gRamSaveSectionLocations[0xE]; extern u8 gDecompressionBuffer[]; extern u32 gFlashMemoryPresent; extern u16 gUnknown_03006294; +extern bool8 gSoftResetDisabled; + +extern const struct SaveSectionOffsets gSaveSectionOffsets[0xE]; extern void DoSaveFailedScreen(u8); // save_failed_screen extern void LoadSerializedGame(void); // load_save @@ -576,84 +579,27 @@ u16 CalculateChecksum(void *data, u16 size) return ((checksum >> 16) + checksum); } -#ifdef NONMATCHING -// the initial allocation of the pointer and toAdd variable doesnt match up with the original function. however, forcing it is impossible since gRamSaveSectionLocations is loaded first. void UpdateSaveAddresses(void) { int i = 0; - gRamSaveSectionLocations[i].data = gSaveBlock2Ptr + gSaveSectionOffsets[0].toAdd; - gRamSaveSectionLocations[i].size = gSaveSectionOffsets[0].size; - for(i = 1; i < 5; i++) + gRamSaveSectionLocations[i].data = (void*)(gSaveBlock2Ptr) + gSaveSectionOffsets[i].toAdd; + gRamSaveSectionLocations[i].size = gSaveSectionOffsets[i].size; + + for (i = 1; i < 5; i++) { - gRamSaveSectionLocations[i].data = gSaveBlock1Ptr + gSaveSectionOffsets[i].toAdd; + gRamSaveSectionLocations[i].data = (void*)(gSaveBlock1Ptr) + gSaveSectionOffsets[i].toAdd; gRamSaveSectionLocations[i].size = gSaveSectionOffsets[i].size; } - for(i = 5; i < 14; i++) + for (i = 5; i < 14; i++) { - gRamSaveSectionLocations[i].data = gPokemonStoragePtr + gSaveSectionOffsets[i].toAdd; + gRamSaveSectionLocations[i].data = (void*)(gPokemonStoragePtr) + gSaveSectionOffsets[i].toAdd; gRamSaveSectionLocations[i].size = gSaveSectionOffsets[i].size; + + i++;i--; // needed to match } } -#else -__attribute__((naked)) -void UpdateSaveAddresses(void) -{ - asm(".syntax unified\n\ - push {r4,r5,lr}\n\ - ldr r3, =gRamSaveSectionLocations\n\ - ldr r0, =gSaveBlock2Ptr\n\ - ldr r2, =gSaveSectionOffsets\n\ - ldrh r1, [r2]\n\ - ldr r0, [r0]\n\ - adds r0, r1\n\ - str r0, [r3]\n\ - ldrh r0, [r2, 0x2]\n\ - strh r0, [r3, 0x4]\n\ - ldr r5, =gSaveBlock1Ptr\n\ - adds r3, 0x8\n\ - adds r2, 0x4\n\ - movs r4, 0x3\n\ -_081531AC:\n\ - ldrh r0, [r2]\n\ - ldr r1, [r5]\n\ - adds r1, r0\n\ - str r1, [r3]\n\ - ldrh r0, [r2, 0x2]\n\ - strh r0, [r3, 0x4]\n\ - adds r3, 0x8\n\ - adds r2, 0x4\n\ - subs r4, 0x1\n\ - cmp r4, 0\n\ - bge _081531AC\n\ - movs r4, 0x5\n\ - ldr r1, =gRamSaveSectionLocations\n\ - ldr r5, =gPokemonStoragePtr\n\ - ldr r0, =gSaveSectionOffsets\n\ - adds r3, r1, 0\n\ - adds r3, 0x28\n\ - adds r2, r0, 0\n\ - adds r2, 0x14\n\ -_081531D2:\n\ - ldrh r0, [r2]\n\ - ldr r1, [r5]\n\ - adds r1, r0\n\ - str r1, [r3]\n\ - ldrh r0, [r2, 0x2]\n\ - strh r0, [r3, 0x4]\n\ - adds r3, 0x8\n\ - adds r2, 0x4\n\ - adds r4, 0x1\n\ - cmp r4, 0xD\n\ - ble _081531D2\n\ - pop {r4,r5}\n\ - pop {r0}\n\ - bx r0\n\ - .pool\n\ - .syntax divided"); -} -#endif extern u32 GetGameStat(u8 index); // rom4 extern void IncrementGameStat(u8 index); // rom4 @@ -894,3 +840,85 @@ u32 sub_8153634(u8 sector, u8* src) return 0xFF; return 1; } + +extern void save_serialize_map(void); +extern void sub_8076D5C(void); +extern void sav2_gender2_inplace_and_xFE(void); +extern void sub_800ADF8(void); +extern bool8 sub_800A520(void); + +void sub_8153688(u8 taskId) +{ + s16* taskData = gTasks[taskId].data; + + switch (taskData[0]) + { + case 0: + gSoftResetDisabled = TRUE; + taskData[0] = 1; + break; + case 1: + sub_800ADF8(); + taskData[0] = 2; + break; + case 2: + if (sub_800A520()) + { + if (taskData[2] == 0) + save_serialize_map(); + taskData[0] = 3; + } + break; + case 3: + if (taskData[2] == 0) + sub_8076D5C(); + sub_8153380(); + taskData[0] = 4; + break; + case 4: + if (++taskData[1] == 5) + { + taskData[1] = 0; + taskData[0] = 5; + } + break; + case 5: + if (sub_81533AC()) + taskData[0] = 6; + else + taskData[0] = 4; + break; + case 6: + sub_81533E0(); + taskData[0] = 7; + break; + case 7: + if (taskData[2] == 0) + sav2_gender2_inplace_and_xFE(); + sub_800ADF8(); + taskData[0] = 8; + break; + case 8: + if (sub_800A520()) + { + sub_8153408(); + taskData[0] = 9; + } + break; + case 9: + sub_800ADF8(); + taskData[0] = 10; + break; + case 10: + if (sub_800A520()) + taskData[0]++; + break; + case 11: + if (++taskData[1] > 5) + { + gSoftResetDisabled = FALSE; + DestroyTask(taskId); + } + break; + } +} -- cgit v1.2.3 From 5d56361973de99d20e099e787da6d587ffb8d35f Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Fri, 29 Sep 2017 11:02:18 +0200 Subject: finish pokemon 2 file --- src/pokemon_2.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/pokemon_2.c b/src/pokemon_2.c index cf073570d..1f5098830 100644 --- a/src/pokemon_2.c +++ b/src/pokemon_2.c @@ -1308,10 +1308,9 @@ void sub_805EF84(u8 bank, bool8); extern struct BattlePokemon gBattleMons[4]; -/* - void CopyPlayerPartyMonToBattleData(u8 bank, u8 partyIndex) { + u16* hpSwitchout; s32 i; u8 nickname[POKEMON_NAME_LENGTH * 2]; @@ -1352,15 +1351,9 @@ void CopyPlayerPartyMonToBattleData(u8 bank, u8 partyIndex) GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, nickname); StringCopy10(gBattleMons[bank].nickname, nickname); GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_NAME, gBattleMons[bank].otName); - // ewram memes from Ruby return - #ifdef NONMATCHING - gBattleStruct->hpOnSwitchout[GetBankSide(bank)] = gBattleMons[bank].hp; - #else - { - u32 side = GetBankSide(bank); - *(u16*)((void*)(gBattleStruct) + side) = gBattleMons[bank].hp; - } - #endif // NONMATCHING + + hpSwitchout = &gBattleStruct->hpOnSwitchout[GetBankSide(bank)]; + *hpSwitchout = gBattleMons[bank].hp; for (i = 0; i < 8; i++) gBattleMons[bank].statStages[i] = 6; @@ -1369,4 +1362,3 @@ void CopyPlayerPartyMonToBattleData(u8 bank, u8 partyIndex) sub_803FA70(bank); sub_805EF84(bank, FALSE); } -*/ -- cgit v1.2.3 From f5387cf6b18b57f3620c05d652a9cf5b8bc2f347 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Fri, 29 Sep 2017 19:03:50 +0200 Subject: decompile metatile behav --- src/field_map_obj.c | 2 +- src/metatile_behavior.c | 1436 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1437 insertions(+), 1 deletion(-) create mode 100644 src/metatile_behavior.c (limited to 'src') diff --git a/src/field_map_obj.c b/src/field_map_obj.c index 26bc513fb..e80e402c8 100755 --- a/src/field_map_obj.c +++ b/src/field_map_obj.c @@ -3413,7 +3413,7 @@ bool8 mss_08062EA4(struct MapObject *mapObject, struct Sprite *sprite) { return FALSE; } - return gUnknown_0850DA64[player_get_x22()](mapObject, sprite, player_get_direction_upper_nybble(), sub_8088E64); + return gUnknown_0850DA64[player_get_x22()](mapObject, sprite, player_get_direction_upper_nybble(), MetatileBehavior_IsPokeGrass); } bool8 sub_80925AC(struct MapObject *, struct Sprite *); diff --git a/src/metatile_behavior.c b/src/metatile_behavior.c new file mode 100644 index 000000000..b9760f522 --- /dev/null +++ b/src/metatile_behavior.c @@ -0,0 +1,1436 @@ +#include "global.h" +#include "metatile_behavior.h" +#include "metatile_behaviors.h" + +#define TILE_FLAG_ENCOUNTER_TILE 1 +#define TILE_FLAG_SURFABLE 2 + +#define TILE_ATTRIBUTES(three, two, one) (((one) ? 1 : 0) | ((two) ? 2 : 0) | ((three) ? 4 : 0)) + +// wonder what the third flag is supposed to do +static const u8 sTileBitAttributes[] = +{ + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_NORMAL 0x00 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x01 + TILE_ATTRIBUTES(TRUE, FALSE, TRUE), // MB_TALL_GRASS 0x02 + TILE_ATTRIBUTES(TRUE, FALSE, TRUE), // MB_LONG_GRASS 0x03 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_04 0x04 + TILE_ATTRIBUTES(FALSE, FALSE, TRUE), // MB_05 0x05 + TILE_ATTRIBUTES(TRUE, FALSE, TRUE), // MB_DEEP_SAND 0x06 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SHORT_GRASS 0x07 + TILE_ATTRIBUTES(TRUE, FALSE, TRUE), // MB_CAVE 0x08 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_LONG_GRASS_SOUTH_EDGE 0x09 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_NO_RUNNING 0x0A + TILE_ATTRIBUTES(TRUE, FALSE, TRUE), // MB_0B 0x0B + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_MOUNTAIN_TOP 0x0C + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_BATTLE_PYRAMID_WARP 0x0D + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_MOSSDEEP_GYM_WARP 0x0E + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_MT_PYRE_HOLE 0x0F + TILE_ATTRIBUTES(TRUE, TRUE, TRUE), // MB_POND_WATER 0x10 + TILE_ATTRIBUTES(TRUE, TRUE, TRUE), // MB_SEMI_DEEP_WATER 0x11 + TILE_ATTRIBUTES(TRUE, TRUE, TRUE), // MB_DEEP_WATER 0x12 + TILE_ATTRIBUTES(TRUE, TRUE, FALSE), // MB_WATERFALL 0x13 + TILE_ATTRIBUTES(TRUE, TRUE, FALSE), // MB_SOOTOPOLIS_DEEP_WATER 0x14 + TILE_ATTRIBUTES(TRUE, TRUE, TRUE), // MB_OCEAN_WATER 0x15 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_PUDDLE 0x16 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SHALLOW_WATER 0x17 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_18 0x18 + TILE_ATTRIBUTES(TRUE, TRUE, FALSE), // MB_NO_SURFACING 0x19 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_1A 0x1A + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_STAIRS_OUTSIDE_ABANDONED_SHIP 0x1B + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SHOAL_CAVE_ENTRANCE 0x1C + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x1D + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x1E + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x1F + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ICE 0x20 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SAND 0x21 + TILE_ATTRIBUTES(TRUE, TRUE, TRUE), // MB_SEAWEED 0x22 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // ? 0x23 + TILE_ATTRIBUTES(TRUE, FALSE, TRUE), // MB_ASHGRASS 0x24 + TILE_ATTRIBUTES(TRUE, FALSE, TRUE), // MB_25 0x25 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_THIN_ICE 0x26 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_CRACKED_ICE 0x27 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_HOT_SPRINGS 0x28 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_LAVARIDGE_GYM_B1F_WARP 0x29 + TILE_ATTRIBUTES(TRUE, TRUE, TRUE), // MB_SEAWEED_NO_SURFACING 0x2A + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_REFLECTION_UNDER_BRIDGE 0x2B + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x2C + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x2D + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x2E + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x2F + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_IMPASSABLE_EAST 0x30 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_IMPASSABLE_WEST 0x31 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_IMPASSABLE_NORTH 0x32 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_IMPASSABLE_SOUTH 0x33 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_IMPASSABLE_NORTHEAST 0x34 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_IMPASSABLE_NORTHWEST 0x35 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_IMPASSABLE_SOUTHEAST 0x36 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_IMPASSABLE_SOUTHWEST 0x37 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_JUMP_EAST 0x38 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_JUMP_WEST 0x39 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_JUMP_NORTH 0x3A + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_JUMP_SOUTH 0x3B + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // ? 0x3C + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // ? 0x3D + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_JUMP_SOUTHEAST 0x3E + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_JUMP_SOUTHWEST 0x3F + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_WALK_EAST 0x40 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_WALK_WEST 0x41 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_WALK_NORTH 0x42 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_WALK_SOUTH 0x43 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SLIDE_EAST 0x44 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SLIDE_WEST 0x45 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SLIDE_NORTH 0x46 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SLIDE_SOUTH 0x47 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_TRICK_HOUSE_PUZZLE_8_FLOOR 0x48 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // ? 0x49 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // ? 0x4A + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x4B + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x4C + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x4D + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x4E + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x4F + TILE_ATTRIBUTES(TRUE, TRUE, FALSE), // MB_EASTWARD_CURRENT 0x50 + TILE_ATTRIBUTES(TRUE, TRUE, FALSE), // MB_WESTWARD_CURRENT 0x51 + TILE_ATTRIBUTES(TRUE, TRUE, FALSE), // MB_NORTHWARD_CURRENT 0x52 + TILE_ATTRIBUTES(TRUE, TRUE, FALSE), // MB_SOUTHWARD_CURRENT 0x53 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x54 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x55 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x56 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x57 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x58 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x59 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x5A + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x5B + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x5C + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x5D + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x5E + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x5F + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_NON_ANIMATED_DOOR 0x60 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_LADDER 0x61 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_EAST_ARROW_WARP 0x62 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_WEST_ARROW_WARP 0x63 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_NORTH_ARROW_WARP 0x64 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SOUTH_ARROW_WARP 0x65 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_CRACKED_FLOOR_HOLE 0x66 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_AQUA_HIDEOUT_WARP 0x67 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_LAVARIDGE_GYM_1F_WARP 0x68 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ANIMATED_DOOR 0x69 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_UP_ESCALATOR 0x6A + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_DOWN_ESCALATOR 0x6B + TILE_ATTRIBUTES(TRUE, TRUE, FALSE), // MB_WATER_DOOR 0x6C + TILE_ATTRIBUTES(TRUE, TRUE, FALSE), // MB_WATER_SOUTH_ARROW_WARP 0x6D + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_DEEP_SOUTH_WARP 0x6E + TILE_ATTRIBUTES(TRUE, TRUE, FALSE), // ? 0x6F + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_WARP_OR_BRIDGE 0x70 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_71 0x71 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ROUTE120_NORTH_BRIDGE_1 0x72 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ROUTE120_NORTH_BRIDGE_2 0x73 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_PACIFIDLOG_VERTICAL_LOG_1 0x74 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_PACIFIDLOG_VERTICAL_LOG_2 0x75 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_PACIFIDLOG_HORIZONTAL_LOG_1 0x76 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_PACIFIDLOG_HORIZONTAL_LOG_2 0x77 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_FORTREE_BRIDGE 0x78 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x79 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ROUTE120_SOUTH_BRIDGE_1 0x7A + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ROUTE120_SOUTH_BRIDGE_2 0x7B + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ROUTE120_NORTH_BRIDGE_3 0x7C + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ROUTE120_NORTH_BRIDGE_4 0x7D + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_7E 0x7E + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ROUTE110_BRIDGE 0x7F + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_COUNTER 0x80 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x81 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x82 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_PC 0x83 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_CABLE_BOX_RESULTS_1 0x84 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_REGION_MAP 0x85 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_TELEVISION 0x86 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_POKEBLOCK_FEEDER 0x87 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x88 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SLOT_MACHINE 0x89 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_ROULETTE 0x8A + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_CLOSED_SOOTOPOLIS_GYM_DOOR 0x8B + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_TRICK_HOUSE_PUZZLE_DOOR 0x8C + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_8D 0x8D + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_RUNNING_SHOES_INSTRUCTION 0x8E + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_QUESTIONNAIRE 0x8F + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_RED_CAVE 0x90 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_RED_CAVE_OPEN 0x91 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_BROWN_CAVE 0x92 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_BROWN_CAVE_OPEN 0x93 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_YELLOW_CAVE 0x94 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_YELLOW_CAVE_OPEN 0x95 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_TREE_LEFT 0x96 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_TREE_LEFT_OPEN 0x97 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_SHRUB 0x98 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_SHRUB_OPEN 0x99 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_BLUE_CAVE 0x9A + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_BLUE_CAVE_OPEN 0x9B + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_TREE_RIGHT 0x9C + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_SPOT_TREE_RIGHT_OPEN 0x9D + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x9E + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0x9F + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_BERRY_TREE_SOIL 0xA0 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xA1 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xA2 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xA3 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xA4 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xA5 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xA6 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xA7 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xA8 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xA9 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xAA + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xAB + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xAC + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xAD + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xAE + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xAF A + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_PC 0xB0 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_REGISTER_PC 0xB1 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_B2 0xB2 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_B3 0xB3 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_B4 0xB4 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_B5 0xB5 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_B6 0xB6 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_B7 0xB7 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SECRET_BASE_BALLOON 0xB8 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_B9 0xB9 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SECRET_BASE_GLITTER_MAT 0xBA + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SECRET_BASE_JUMP_MAT 0xBB + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SECRET_BASE_SPIN_MAT 0xBC + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SECRET_BASE_SOUND_MAT 0xBD + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_BE 0xBE + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_BF 0xBF + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_BED 0xC0 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_C1 0xC1 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_C2 0xC2 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_C3 0xC3 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_SECRET_BASE_TV_SHIELD 0xC4 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_C5 0xC5 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_C6 0xC6 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SECRET_BASE_POSTER 0xC7 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_C8 0xC8 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_C9 0xC9 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_CA 0xCA + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_CB 0xCB + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_CC 0xCC + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_CD 0xCD + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_CE 0xCE + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_CF 0xCF + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_MUDDY_SLOPE 0xD0 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_BUMPY_SLOPE 0xD1 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_CRACKED_FLOOR 0xD2 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ISOLATED_VERTICAL_RAIL 0xD3 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_ISOLATED_HORIZONTAL_RAIL 0xD4 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_VERTICAL_RAIL 0xD5 + TILE_ATTRIBUTES(TRUE, FALSE, FALSE), // MB_HORIZONTAL_RAIL 0xD6 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xD7 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xD8 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xD9 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xDA + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xDB + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xDC + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xDD + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xDE + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xDF + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_PICTURE_BOOK_SHELF 0xE0 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_BOOKSHELF 0xE1 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_POKEMON_CENTER_BOOKSHELF 0xE2 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_VASE 0xE3 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_TRASH_CAN 0xE4 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_SHOP_SHELF 0xE5 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_BLUEPRINT 0xE6 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_CABLE_BOX_RESULTS_2 0xE7 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_WIRELESS_BOX_RESULTS 0xE8 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_TRAINER_HILL_TIMER 0xE9 + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // MB_UNKNOWN_CLOSED_DOOR 0xEA + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xEB + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xEC + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xED + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xEE + TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xEF +}; + +// only used as default case for checking jump landing in field_ground_effect. +bool8 ShouldDoJumpLandingDustEffect(u8 var) +{ + return TRUE; +} + +bool8 MetatileBehavior_IsEncounterTile(u8 var) +{ + if ((sTileBitAttributes[var] & TILE_FLAG_ENCOUNTER_TILE) != 0) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsJumpEast(u8 var) +{ + if (var == MB_JUMP_EAST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsJumpWest(u8 var) +{ + if (var == MB_JUMP_WEST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsJumpNorth(u8 var) +{ + if (var == MB_JUMP_NORTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsJumpSouth(u8 var) +{ + if (var == MB_JUMP_SOUTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPokeGrass(u8 var) +{ + if (var == MB_TALL_GRASS || var == MB_LONG_GRASS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSandOrDeepSand(u8 var) +{ + if (var == MB_SAND || var == MB_DEEP_SAND) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsDeepSand(u8 var) +{ + if (var == MB_DEEP_SAND) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsReflective(u8 var) +{ + if (var == MB_POND_WATER || var == MB_PUDDLE || var == MB_1A || var == MB_ICE || var == MB_SOOTOPOLIS_DEEP_WATER || var == MB_REFLECTION_UNDER_BRIDGE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsIce(u8 var) +{ + if (var == MB_ICE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWarpDoor(u8 var) +{ + if (var == MB_ANIMATED_DOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsDoor(u8 var) +{ + if (var == MB_8D || var == MB_ANIMATED_DOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsEscalator(u8 var) +{ + if (var == MB_UP_ESCALATOR || var == MB_DOWN_ESCALATOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_04(u8 var) // unused +{ + if (var == MB_04) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsLadder(u8 var) +{ + if (var == MB_LADDER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsNonAnimDoor(u8 var) +{ + if (var == MB_NON_ANIMATED_DOOR || var == MB_WATER_DOOR || var == MB_DEEP_SOUTH_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsDeepSouthWarp(u8 var) +{ + if (var == MB_DEEP_SOUTH_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSurfableWaterOrUnderwater(u8 var) +{ + if ((sTileBitAttributes[var] & TILE_FLAG_SURFABLE) != 0) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsEastArrowWarp(u8 var) +{ + if (var == MB_EAST_ARROW_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWestArrowWarp(u8 var) +{ + if (var == MB_WEST_ARROW_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsNorthArrowWarp(u8 var) +{ + if (var == MB_NORTH_ARROW_WARP || var == MB_STAIRS_OUTSIDE_ABANDONED_SHIP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSouthArrowWarp(u8 var) +{ + if (var == MB_SOUTH_ARROW_WARP || var == MB_WATER_SOUTH_ARROW_WARP || var == MB_SHOAL_CAVE_ENTRANCE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsArrowWarp(u8 var) // unused +{ + u8 ret = FALSE; + + if (MetatileBehavior_IsEastArrowWarp(var) + || MetatileBehavior_IsWestArrowWarp(var) + || MetatileBehavior_IsNorthArrowWarp(var) + || MetatileBehavior_IsSouthArrowWarp(var)) + { + ret = TRUE; + } + + return ret; +} + +bool8 MetatileBehavior_IsMoveTile(u8 var) +{ + if ((var >= MB_WALK_EAST && var <= MB_TRICK_HOUSE_PUZZLE_8_FLOOR) || (var >= MB_EASTWARD_CURRENT && var <= MB_SOUTHWARD_CURRENT) + || var == MB_MUDDY_SLOPE || var == MB_CRACKED_FLOOR || var == MB_WATERFALL || var == MB_ICE || var == MB_SECRET_BASE_JUMP_MAT || var == MB_SECRET_BASE_SPIN_MAT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsIce_2(u8 var) +{ + if (var == MB_ICE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsTrickHouseSlipperyFloor(u8 var) +{ + if (var == MB_TRICK_HOUSE_PUZZLE_8_FLOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_05(u8 var) +{ + if (var == MB_05) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWalkNorth(u8 var) +{ + if (var == MB_WALK_NORTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWalkSouth(u8 var) +{ + if (var == MB_WALK_SOUTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWalkWest(u8 var) +{ + if (var == MB_WALK_WEST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWalkEast(u8 var) +{ + if (var == MB_WALK_EAST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsNorthwardCurrent(u8 var) +{ + if (var == MB_NORTHWARD_CURRENT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSouthwardCurrent(u8 var) +{ + if (var == MB_SOUTHWARD_CURRENT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWestwardCurrent(u8 var) +{ + if (var == MB_WESTWARD_CURRENT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsEastwardCurrent(u8 var) +{ + if (var == MB_EASTWARD_CURRENT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSlideNorth(u8 var) +{ + if (var == MB_SLIDE_NORTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSlideSouth(u8 var) +{ + if (var == MB_SLIDE_SOUTH) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSlideWest(u8 var) +{ + if (var == MB_SLIDE_WEST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSlideEast(u8 var) +{ + if (var == MB_SLIDE_EAST) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCounter(u8 var) +{ + if (var == MB_COUNTER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPlayerFacingTVScreen(u8 tile, u8 playerDir) +{ + if (playerDir != CONNECTION_NORTH) // if the player isn't facing north, forget about it. + return FALSE; + else if (tile == MB_TELEVISION) // is the player's north tile a TV? + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPC(u8 var) +{ + if (var == MB_PC) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCableBoxResults1(u8 var) +{ + if (var == MB_CABLE_BOX_RESULTS_1) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseOpen(u8 var) +{ + if (var == MB_SECRET_BASE_SPOT_RED_CAVE_OPEN || var == MB_SECRET_BASE_SPOT_BROWN_CAVE_OPEN + || var == MB_SECRET_BASE_SPOT_YELLOW_CAVE_OPEN || var == MB_SECRET_BASE_SPOT_TREE_LEFT_OPEN + || var == MB_SECRET_BASE_SPOT_SHRUB_OPEN || var == MB_SECRET_BASE_SPOT_BLUE_CAVE_OPEN + || var == MB_SECRET_BASE_SPOT_TREE_RIGHT_OPEN) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseCave(u8 var) +{ + if (var == MB_SECRET_BASE_SPOT_RED_CAVE || var == MB_SECRET_BASE_SPOT_BROWN_CAVE || var == MB_SECRET_BASE_SPOT_YELLOW_CAVE || var == MB_SECRET_BASE_SPOT_BLUE_CAVE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseTree(u8 var) +{ + if (var == MB_SECRET_BASE_SPOT_TREE_LEFT || var == MB_SECRET_BASE_SPOT_TREE_RIGHT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseShrub(u8 var) +{ + if (var == MB_SECRET_BASE_SPOT_SHRUB) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBasePC(u8 var) +{ + if (var == MB_SECRET_BASE_PC) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseRegisterPC(u8 var) +{ + if (var == MB_SECRET_BASE_REGISTER_PC) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_B2(u8 var) // unused +{ + if (var == MB_B2) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_B3(u8 var) +{ + if (var == MB_B3) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_B9(u8 var) +{ + if (var == MB_B9) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_C6(u8 var) +{ + if (var == MB_C6) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBasePoster(u8 var) +{ + if (var == MB_SECRET_BASE_POSTER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsNormal(u8 var) +{ + if (var == MB_NORMAL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_B7(u8 var) +{ + if (var == MB_B7) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_B2_Duplicate(u8 var) // unused +{ + if (var == MB_B2) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_B5(u8 var) +{ + if (var == MB_B5) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_C3(u8 var) +{ + if (var == MB_C3) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_C2(u8 var) +{ + if (var == MB_C2) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseBalloon(u8 var) +{ + if (var == MB_SECRET_BASE_BALLOON) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_BE(u8 var) +{ + if (var == MB_BE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseSoundMat(u8 var) +{ + if (var == MB_SECRET_BASE_SOUND_MAT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseGlitterMat(u8 var) +{ + if (var == MB_SECRET_BASE_GLITTER_MAT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_BF(u8 var) +{ + if (var == MB_BF) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseTvOrShield(u8 var) +{ + if (var == MB_SECRET_BASE_TV_SHIELD) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_C5(u8 var) +{ + if (var == MB_C5) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_HasRipples(u8 var) +{ + if (var == MB_POND_WATER || var == MB_PUDDLE || var == MB_SOOTOPOLIS_DEEP_WATER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPuddle(u8 var) +{ + if (var == MB_PUDDLE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsTallGrass(u8 var) +{ + if (var == MB_TALL_GRASS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsLongGrass(u8 var) +{ + if (var == MB_LONG_GRASS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBerryTreeSoil(u8 var) +{ + if (var == MB_BERRY_TREE_SOIL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsAsh(u8 var) +{ + if (var == MB_ASHGRASS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsUnusedFootprintMetatile(u8 var) +{ + if (var == MB_25) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBridge(u8 var) +{ + if ((var == MB_WARP_OR_BRIDGE || var == MB_71 || var == MB_ROUTE120_NORTH_BRIDGE_1 || var == MB_ROUTE120_NORTH_BRIDGE_2) + || (var == MB_ROUTE120_NORTH_BRIDGE_3 || var == MB_ROUTE120_NORTH_BRIDGE_4 || var == MB_7E || var == MB_ROUTE110_BRIDGE)) + return TRUE; + else + return FALSE; +} + +u8 MetatileBehavior_GetBridgeSth(u8 var) +{ + u8 result = var - MB_WARP_OR_BRIDGE; + if (result < 4) + return result; + + result = var - MB_ROUTE120_SOUTH_BRIDGE_1; + if (result < 2) + return 2; + + result = var - MB_ROUTE120_NORTH_BRIDGE_3; + if (result < 2) + return 3; + + return 0; +} + +u8 MetatileBehavior_8089510(u8 var) +{ + u8 result = var - MB_WARP_OR_BRIDGE; + + if (result < 4) + return 1; + else + return 0; +} + +bool8 MetatileBehavior_IsLandWildEncounter(u8 var) +{ + if (MetatileBehavior_IsSurfableWaterOrUnderwater(var) == FALSE && MetatileBehavior_IsEncounterTile(var) == TRUE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWaterWildEncounter(u8 var) +{ + if (MetatileBehavior_IsSurfableWaterOrUnderwater(var) == TRUE && MetatileBehavior_IsEncounterTile(var) == TRUE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_0B(u8 var) +{ + if (var == MB_0B) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMountain(u8 var) +{ + if (var == MB_MOUNTAIN_TOP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsDiveable(u8 var) +{ + if (var == MB_SEMI_DEEP_WATER || var == MB_DEEP_WATER || var == MB_SOOTOPOLIS_DEEP_WATER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsUnableToEmerge(u8 var) +{ + if (var == MB_NO_SURFACING || var == MB_SEAWEED_NO_SURFACING) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsShallowFlowingWater(u8 var) +{ + if (var == MB_SHALLOW_WATER || var == MB_STAIRS_OUTSIDE_ABANDONED_SHIP || var == MB_SHOAL_CAVE_ENTRANCE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsThinIce(u8 var) +{ + if (var == MB_THIN_ICE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCrackedIce(u8 var) +{ + if (var == MB_CRACKED_ICE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsDeepOrOceanWater(u8 var) +{ + if (var == MB_OCEAN_WATER || var == MB_SEMI_DEEP_WATER || var == MB_DEEP_WATER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMB_18_OrMB_1A(u8 var) // unused +{ + if (var == MB_18 || var == MB_1A) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSurfableAndNotWaterfall(u8 var) +{ + if (MetatileBehavior_IsSurfableWaterOrUnderwater(var) && MetatileBehavior_IsWaterfall(var) == FALSE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsEastBlocked(u8 var) +{ + if (var == MB_IMPASSABLE_EAST || var == MB_IMPASSABLE_NORTHEAST || var == MB_IMPASSABLE_SOUTHEAST || var == MB_C1 || var == MB_BE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWestBlocked(u8 var) +{ + if (var == MB_IMPASSABLE_WEST || var == MB_IMPASSABLE_NORTHWEST || var == MB_IMPASSABLE_SOUTHWEST || var == MB_C1 || var == MB_BE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsNorthBlocked(u8 var) +{ + if (var == MB_IMPASSABLE_NORTH || var == MB_IMPASSABLE_NORTHEAST || var == MB_IMPASSABLE_NORTHWEST || var == MB_BED) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSouthBlocked(u8 var) +{ + if (var == MB_IMPASSABLE_SOUTH || var == MB_IMPASSABLE_SOUTHEAST || var == MB_IMPASSABLE_SOUTHWEST || var == MB_BED) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsShortGrass(u8 var) +{ + if (var == MB_SHORT_GRASS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsHotSprings(u8 var) +{ + if (var == MB_HOT_SPRINGS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWaterfall(u8 var) +{ + if (var == MB_WATERFALL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsFortreeBridge(u8 var) +{ + if (var == MB_FORTREE_BRIDGE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPacifilogVerticalLog1(u8 var) +{ + if (var == MB_PACIFIDLOG_VERTICAL_LOG_1) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPacifilogVerticalLog2(u8 var) +{ + if (var == MB_PACIFIDLOG_VERTICAL_LOG_2) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPacifilogHorizontalLog1(u8 var) +{ + if (var == MB_PACIFIDLOG_HORIZONTAL_LOG_1) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPacifilogHorizontalLog2(u8 var) +{ + if (var == MB_PACIFIDLOG_HORIZONTAL_LOG_2) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPacifidlogLog(u8 var) +{ + if (var == MB_PACIFIDLOG_VERTICAL_LOG_1 || var == MB_PACIFIDLOG_VERTICAL_LOG_2 + || var == MB_PACIFIDLOG_HORIZONTAL_LOG_1 || var == MB_PACIFIDLOG_HORIZONTAL_LOG_2) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsTrickHousePuzzleDoor(u8 var) +{ + if (var == MB_TRICK_HOUSE_PUZZLE_DOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsRegionMap(u8 var) +{ + if (var == MB_REGION_MAP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsClosedSootopolisGymDoor(u8 var) +{ + if (var == MB_CLOSED_SOOTOPOLIS_GYM_DOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsUnknownClosedDoor(u8 var) +{ + if (var == MB_UNKNOWN_CLOSED_DOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsRoulette(u8 var) // unused +{ + if (var == MB_ROULETTE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPokeblockFeeder(u8 var) +{ + if (var == MB_POKEBLOCK_FEEDER) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseJumpMat(u8 var) +{ + if (var == MB_SECRET_BASE_JUMP_MAT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSecretBaseSpinMat(u8 var) +{ + if (var == MB_SECRET_BASE_SPIN_MAT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsLavaridgeB1FWarp(u8 var) +{ + if (var == MB_LAVARIDGE_GYM_B1F_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsLavaridge1FWarp(u8 var) +{ + if (var == MB_LAVARIDGE_GYM_1F_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsAquaHideoutWarp(u8 var) +{ + if (var == MB_AQUA_HIDEOUT_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsWarpOrBridge(u8 var) +{ + if (var == MB_WARP_OR_BRIDGE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMossdeepGymWarp(u8 var) +{ + if (var == MB_MOSSDEEP_GYM_WARP) + return TRUE; + else + return FALSE; +} + + +bool8 MetatileBehavior_IsSurfableFishableWater(u8 var) +{ + if (var == MB_POND_WATER || var == MB_OCEAN_WATER || var == MB_SEMI_DEEP_WATER || var == MB_DEEP_WATER + || var == MB_SOOTOPOLIS_DEEP_WATER || (var == MB_EASTWARD_CURRENT || var == MB_WESTWARD_CURRENT + || var == MB_NORTHWARD_CURRENT || var == MB_SOUTHWARD_CURRENT)) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMtPyreHole(u8 var) +{ + if (var == MB_MT_PYRE_HOLE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCrackedFloorHole(u8 var) +{ + if (var == MB_CRACKED_FLOOR_HOLE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCrackedFloor(u8 var) +{ + if (var == MB_CRACKED_FLOOR) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsMuddySlope(u8 var) +{ + if (var == MB_MUDDY_SLOPE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBumpySlope(u8 var) +{ + if (var == MB_BUMPY_SLOPE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsIsolatedVerticalRail(u8 var) +{ + if (var == MB_ISOLATED_VERTICAL_RAIL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsIsolatedHorizontalRail(u8 var) +{ + if (var == MB_ISOLATED_HORIZONTAL_RAIL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsVerticalRail(u8 var) +{ + if (var == MB_VERTICAL_RAIL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsHorizontalRail(u8 var) +{ + if (var == MB_HORIZONTAL_RAIL) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSeaweed(u8 var) +{ + if (var == MB_SEAWEED || var == MB_SEAWEED_NO_SURFACING) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsRunningDisallowed(u8 var) +{ + if (var == MB_NO_RUNNING || var == MB_LONG_GRASS || var == MB_HOT_SPRINGS || MetatileBehavior_IsPacifidlogLog(var) != FALSE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCuttableGrass(u8 var) +{ + if (var == MB_TALL_GRASS || var == MB_LONG_GRASS || var == MB_ASHGRASS || var == MB_LONG_GRASS_SOUTH_EDGE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsRunningShoesInstruction(u8 var) +{ + if (var == MB_RUNNING_SHOES_INSTRUCTION) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPictureBookShelf(u8 var) +{ + if (var == MB_PICTURE_BOOK_SHELF) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBookShelf(u8 var) +{ + if (var == MB_BOOKSHELF) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPokeCenterBookShelf(u8 var) +{ + if (var == MB_POKEMON_CENTER_BOOKSHELF) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsVase(u8 var) +{ + if (var == MB_VASE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsTrashCan(u8 var) +{ + if (var == MB_TRASH_CAN) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsShopShelf(u8 var) +{ + if (var == MB_SHOP_SHELF) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBlueprint(u8 var) +{ + if (var == MB_BLUEPRINT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsBattlePyramidWarp(u8 var) +{ + if (var == MB_BATTLE_PYRAMID_WARP) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsPlayerFacingWirelessBoxResults(u8 tile, u8 playerDir) +{ + if (playerDir != CONNECTION_NORTH) // if the player isn't facing north, forget about it. + return FALSE; + else if (tile == MB_WIRELESS_BOX_RESULTS) // is the player's north tile the monitor with results? + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsCableBoxResults2(u8 tile, u8 playerDir) +{ + if (playerDir != CONNECTION_NORTH) // if the player isn't facing north, forget about it. + return FALSE; + else if (tile == MB_CABLE_BOX_RESULTS_2) // is the player's north tile the monitor with results? + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsQuestionnaire(u8 var) +{ + if (var == MB_QUESTIONNAIRE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsLongGrass_Duplicate(u8 var) +{ + if (var == MB_LONG_GRASS) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsLongGrassSouthEdge(u8 var) +{ + if (var == MB_LONG_GRASS_SOUTH_EDGE) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsTrainerHillTimer(u8 var) +{ + if (var == MB_TRAINER_HILL_TIMER) + return TRUE; + else + return FALSE; +} -- cgit v1.2.3 From 7db6b48aa083ecffd2e3d991bd983fd9be004316 Mon Sep 17 00:00:00 2001 From: ProjectRevoTPP Date: Sat, 30 Sep 2017 02:05:47 -0400 Subject: move externs --- src/field_special_scene.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/field_special_scene.c b/src/field_special_scene.c index 20331f37c..9c35a33da 100755 --- a/src/field_special_scene.c +++ b/src/field_special_scene.c @@ -12,6 +12,16 @@ #define SECONDS(value) ((signed) (60.0 * value + 0.5)) +extern u8 GetSSTidalLocation(s8 *, s8 *, s16 *, s16 *); // should be in field_specials.h +extern void warp1_set(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y); +extern bool8 sub_80D3340(u8, u8, u8); +extern bool32 CountSSTidalStep(u16); +extern bool8 exec_movement(u8, u8, u8, u8 *); +extern void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused); +extern void sp13E_warp_to_last_warp(void); +extern void saved_warp2_set(int unused, s8 mapGroup, s8 mapNum, s8 warpId); +extern void sub_80AF8B8(void); + // porthole states enum { @@ -243,9 +253,6 @@ void EndTruckSequence(u8 taskId) } } -extern u8 GetSSTidalLocation(s8 *, s8 *, s16 *, s16 *); // should be in field_specials.h -extern void warp1_set(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y); - bool8 sub_80FB59C(void) { s8 mapGroup, mapNum; @@ -262,12 +269,6 @@ bool8 sub_80FB59C(void) } } -extern bool8 sub_80D3340(u8, u8, u8); -extern bool32 CountSSTidalStep(u16); -extern bool8 exec_movement(u8, u8, u8, u8 *); -extern void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused); -extern void sp13E_warp_to_last_warp(void); - void Task_HandlePorthole(u8 taskId) { s16 *data = gTasks[taskId].data; @@ -351,9 +352,6 @@ void sub_80FB768(void) ScriptContext2_Enable(); } -extern void saved_warp2_set(int unused, s8 mapGroup, s8 mapNum, s8 warpId); -extern void sub_80AF8B8(void); - void sub_80FB7A4(void) { FlagSet(SYS_CRUISE_MODE); -- cgit v1.2.3 From ef0b022707bd6e4167f43fa0c9396dc507ef9042 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 30 Sep 2017 09:32:46 -0400 Subject: BSS: src/main.o, src/dma3_manager.o --- src/dma3_manager.c | 18 ++++++++++++++---- src/main.c | 2 +- src/malloc.c | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/dma3_manager.c b/src/dma3_manager.c index 7cce06c15..bb015c5cf 100644 --- a/src/dma3_manager.c +++ b/src/dma3_manager.c @@ -1,12 +1,23 @@ #include "global.h" #include "dma3.h" +IWRAM_DATA struct { + /* 0x00 */ const u8 *src; + /* 0x04 */ u8 *dest; + /* 0x08 */ u16 size; + /* 0x0A */ u16 mode; + /* 0x0C */ u32 value; +} gDma3Requests[128]; + +static bool8 gDma3ManagerLocked; +static u8 gDma3RequestCursor; + void ClearDma3Requests(void) { int i; gDma3ManagerLocked = TRUE; - gDma3RequestCursor = FALSE; + gDma3RequestCursor = 0; for(i = 0; i < (u8)ARRAY_COUNT(gDma3Requests); i++) { @@ -22,7 +33,6 @@ void ClearDma3Requests(void) void ProcessDma3Requests(void) { // NOTE: the fillerA member of the DMA struct is actually u32 value; - // NOTE: gUnknown_0300001C is just a pointer inside the gDma3Requests structure, not a true symbol; feel free to remove u16 total_size; if (gDma3ManagerLocked) @@ -331,7 +341,7 @@ _08000DB2:\n\ mov r5, r12\n\ ldrb r0, [r5]\n\ lsls r0, 4\n\ - ldr r3, =gUnknown_0300001C\n\ + ldr r3, =gDma3Requests + 0x0C\n\ adds r0, r3\n\ ldr r0, [r0]\n\ strh r0, [r1]\n\ @@ -347,7 +357,7 @@ _08000DB2:\n\ bhi _08000DB2\n\ ldrb r0, [r5]\n\ lsls r0, 4\n\ - ldr r5, =gUnknown_0300001C\n\ + ldr r5, =gDma3Requests + 0x0C\n\ adds r0, r5\n\ ldr r0, [r0]\n\ strh r0, [r1]\n\ diff --git a/src/main.c b/src/main.c index 5707e18af..665a4dd84 100644 --- a/src/main.c +++ b/src/main.c @@ -77,7 +77,7 @@ const IntrFunc gIntrTableTemplate[] = #define INTR_COUNT ((int)(sizeof(gIntrTableTemplate)/sizeof(IntrFunc))) -extern u16 gUnknown_03000000; +static u16 gUnknown_03000000; extern u16 gKeyRepeatStartDelay; extern u8 gUnknown_030022B4; diff --git a/src/malloc.c b/src/malloc.c index ccb2f7d20..1d64351c3 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -2,6 +2,7 @@ static void *sHeapStart; static u32 sHeapSize; +static u32 malloc_c_unused_0300000c; // needed to align dma3_manager.o(.bss) #define MALLOC_SYSTEM_ID 0xA3A3 -- cgit v1.2.3 From f4827632f2c2e78cdc798176f61e7ff26539a957 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 30 Sep 2017 09:56:08 -0400 Subject: BSS: link.o --- src/link.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/link.c (limited to 'src') diff --git a/src/link.c b/src/link.c new file mode 100644 index 000000000..ae2cd1992 --- /dev/null +++ b/src/link.c @@ -0,0 +1,56 @@ + +// Includes +#include "global.h" + +// Static type declarations + +struct BlockTransfer +{ + u16 pos; + u16 size; + void *src; + bool8 active; + u8 multiplayerId; +}; + +struct LinkTestBGInfo +{ + u32 screenBaseBlock; + u32 paletteNum; + u32 dummy_8; + u32 dummy_C; +}; + +// Static RAM declarations + +IWRAM_DATA struct BlockTransfer gUnknown_03000D10; +IWRAM_DATA u32 link_c_unused_03000d1c; +IWRAM_DATA struct BlockTransfer gUnknown_03000D20[4]; +IWRAM_DATA u32 gUnknown_03000D50; +IWRAM_DATA u32 gUnknown_03000D54; +IWRAM_DATA u8 gUnknown_03000D58; +IWRAM_DATA u32 gUnknown_03000D5C; +IWRAM_DATA u32 gUnknown_03000D60; +IWRAM_DATA u8 gUnknown_03000D64[4]; // not really, but won't match otherwise +IWRAM_DATA u8 gUnknown_03000D68[4]; +IWRAM_DATA u8 gUnknown_03000D6C; +IWRAM_DATA bool8 gUnknown_03000D6D; +IWRAM_DATA u16 gUnknown_03000D6E; +IWRAM_DATA u16 gUnknown_03000D70; +IWRAM_DATA u8 gUnknown_03000D72; +IWRAM_DATA u8 gUnknown_03000D73; +IWRAM_DATA u8 gUnknown_03000D74[4]; // not really, but won't match otherwise +IWRAM_DATA u8 gUnknown_03000D78[8]; // not really, but won't match otherwise +IWRAM_DATA u8 gUnknown_03000D80[16]; +IWRAM_DATA u16 gUnknown_03000D90[8]; +IWRAM_DATA u32 gUnknown_03000DA0; +IWRAM_DATA u32 gUnknown_03000DA4; +IWRAM_DATA void *gUnknown_03000DA8; +IWRAM_DATA void *gUnknown_03000DAC; +IWRAM_DATA bool32 gUnknown_03000DB0; + +// Static ROM declarations + +// .rodata + +// .text -- cgit v1.2.3 From 24da6e48ffe63916d1ffeb8fec720c63fdfac172 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 30 Sep 2017 10:01:52 -0400 Subject: BSS: main_menu.o, battle_1.o --- src/battle_1.c | 17 +++++++++++++++++ src/main_menu.c | 15 +++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/battle_1.c create mode 100644 src/main_menu.c (limited to 'src') diff --git a/src/battle_1.c b/src/battle_1.c new file mode 100644 index 000000000..5e4ef5583 --- /dev/null +++ b/src/battle_1.c @@ -0,0 +1,17 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations + +IWRAM_DATA u32 gUnknown_03000DD4; +IWRAM_DATA u32 gUnknown_03000DD8; +IWRAM_DATA u32 gUnknown_03000DDC; + +// Static ROM declarations + +// .rodata + +// .text diff --git a/src/main_menu.c b/src/main_menu.c new file mode 100644 index 000000000..8608159c2 --- /dev/null +++ b/src/main_menu.c @@ -0,0 +1,15 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations + +IWRAM_DATA u8 gUnknown_03000DD0; + +// Static ROM declarations + +// .rodata + +// .text -- cgit v1.2.3 From 8620b9203d876764404622d2d6d8711812928979 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 30 Sep 2017 10:12:35 -0400 Subject: BSS: berry_blender.o --- src/berry_blender.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/berry_blender.c (limited to 'src') diff --git a/src/berry_blender.c b/src/berry_blender.c new file mode 100644 index 000000000..d9cc86f7f --- /dev/null +++ b/src/berry_blender.c @@ -0,0 +1,18 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations +IWRAM_DATA u32 berry_blender_c_unused_03000de4; +IWRAM_DATA s16 gUnknown_03000DE8[8]; +IWRAM_DATA s16 gUnknown_03000DF8[6]; +IWRAM_DATA s16 gUnknown_03000E04; +IWRAM_DATA s16 gUnknown_03000E06; + +// Static ROM declarations + +// .rodata + +// .text -- cgit v1.2.3 From 64631bac9365cf8df3798d9d3be8746d4d641685 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 30 Sep 2017 13:08:28 -0400 Subject: BSS: rom4.o, field_camera.o --- src/berry_blender.c | 2 +- src/field_camera.c | 28 ++++++++++++++++++++++++++++ src/rom4.c | 19 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/field_camera.c create mode 100644 src/rom4.c (limited to 'src') diff --git a/src/berry_blender.c b/src/berry_blender.c index d9cc86f7f..db50fe4c4 100644 --- a/src/berry_blender.c +++ b/src/berry_blender.c @@ -5,7 +5,7 @@ // Static type declarations // Static RAM declarations -IWRAM_DATA u32 berry_blender_c_unused_03000de4; +IWRAM_DATA void *berry_blender_c_unused_03000de4; IWRAM_DATA s16 gUnknown_03000DE8[8]; IWRAM_DATA s16 gUnknown_03000DF8[6]; IWRAM_DATA s16 gUnknown_03000E04; diff --git a/src/field_camera.c b/src/field_camera.c new file mode 100644 index 000000000..17ced6aa5 --- /dev/null +++ b/src/field_camera.c @@ -0,0 +1,28 @@ + +// Includes +#include "global.h" + +// Static type declarations + +struct FieldCameraUnknownStruct +{ + u8 unk0; + u8 unk1; + u8 unk2; + u8 unk3; + bool8 unk4; +}; + +// Static RAM declarations + +IWRAM_DATA struct FieldCameraUnknownStruct gUnknown_03000E20; +IWRAM_DATA s16 gUnknown_03000E28; +IWRAM_DATA s16 gUnknown_03000E2A; +IWRAM_DATA u8 gUnknown_03000E2C; +IWRAM_DATA void (*gUnknown_03000E30)(void); + +// Static ROM declarations + +// .rodata + +// .text diff --git a/src/rom4.c b/src/rom4.c new file mode 100644 index 000000000..c538595f2 --- /dev/null +++ b/src/rom4.c @@ -0,0 +1,19 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations +IWRAM_DATA void *gUnknown_03000E0C; +IWRAM_DATA u8 gUnknown_03000E10[4]; +IWRAM_DATA u8 (*gUnknown_03000E14)(u32); +IWRAM_DATA u8 gUnknown_03000E18; +IWRAM_DATA u8 gUnknown_03000E19; +IWRAM_DATA void *rom4_c_unused_03000e1c; + +// Static ROM declarations + +// .rodata + +// .text -- cgit v1.2.3 From 20ed9ad0ac92cddcbfe66ccc9c2ae3cb1000ed71 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 30 Sep 2017 21:19:29 -0400 Subject: Decompile asm/tileset.s into src/palette.c --- src/palette.c | 880 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/scrcmd.c | 15 + 2 files changed, 871 insertions(+), 24 deletions(-) create mode 100644 src/scrcmd.c (limited to 'src') diff --git a/src/palette.c b/src/palette.c index aa9a84e4c..4c09206ba 100644 --- a/src/palette.c +++ b/src/palette.c @@ -28,7 +28,7 @@ struct PaletteStructTemplate struct PaletteStruct { - struct PaletteStructTemplate *base; + const struct PaletteStructTemplate *base; u32 ps_field_4_0:1; u16 ps_field_4_1:1; u32 baseDestOffset:9; @@ -48,6 +48,11 @@ extern void _call_via_r1(u32 a1, void *a2); extern void BlendPalette(u16, u16, u8, u16); +static EWRAM_DATA struct { + const u16 *src; + u16 *dest; + u16 size; +} sTilesetDMA3TransferBuffer[20] = {0}; EWRAM_DATA u16 gPlttBufferUnfaded[0x200] = {0}; EWRAM_DATA u16 gPlttBufferFaded[0x200] = {0}; EWRAM_DATA struct PaletteStruct sPaletteStructs[0x10] = {0}; @@ -56,13 +61,72 @@ EWRAM_DATA u32 gFiller_2037FE0 = 0; EWRAM_DATA u32 sPlttBufferTransferPending = 0; EWRAM_DATA u8 gPaletteDecompressionBuffer[0x400] = {0}; -extern struct PaletteStructTemplate gDummyPaletteStructTemplate; -extern void *gUnknown_0852487C; -extern u8 gUnknown_0852489C[]; +extern const u16 *const gUnknown_08510764[]; +extern const u16 *const gUnknown_085112C4[]; +extern const u16 *const gUnknown_08511BCC[]; +extern const u16 *const gUnknown_08512574[]; +extern const u16 *const gUnknown_08512E54[]; +extern const u16 *const gUnknown_08513174[]; +extern const u16 *const gUnknown_08513684[]; +extern const u16 *const gUnknown_08513894[]; +extern const u16 *const gUnknown_085143E4[]; +extern const u16 *const gUnknown_085145F4[]; +extern const u16 *const gUnknown_08514E04[]; +extern u16 *const gUnknown_08515344[]; +extern u16 *const gUnknown_08515364[]; +extern const u16 *const gUnknown_08515384[]; +extern const u16 *const gUnknown_085153B4[]; +extern const u16 *const gUnknown_085153E4[]; +extern const u16 *const gUnknown_085153F4[]; +extern u16 *const gUnknown_08515804[]; +extern const u16 *const gUnknown_08515824[]; +extern const u16 *const gUnknown_08515964[]; +extern const u16 *const gUnknown_08515D8C[]; +extern u16 *const gUnknown_085161BC[]; +extern const u16 *const gUnknown_085161DC[]; +extern const u16 *const gUnknown_085164FC[]; +extern const u16 *const gUnknown_0851680C[]; +extern const u16 *const gUnknown_08516B1C[]; +extern const u16 *const gUnknown_08516D2C[]; +extern const u16 *const gUnknown_08516E3C[]; +extern const u16 *const gUnknown_08517A44[]; +extern const u16 *const gUnknown_08517A50[]; +extern const u16 *const gUnknown_08517BFC[]; +extern const u16 *const gUnknown_08517C0C[]; +extern const u16 *const gUnknown_08518034[]; +extern const u16 *const gUnknown_0851829C[]; +extern const u16 *const gUnknown_085202C4[]; +extern const u16 *const gUnknown_08524864[]; +extern const u16 *const gUnknown_08524870[]; + +extern const u16 gUnknown_08D85640[]; +extern const u16 gUnknown_08D85660[]; +extern const u16 gUnknown_08D85680[]; +extern const u16 gUnknown_08D856A0[]; + +static const u16 *const gUnknown_0852487C[] = { + gUnknown_08D85640, + gUnknown_08D85660, + gUnknown_08D85680, + gUnknown_08D856A0, +}; -extern u16 gUnknown_03000F3C; -extern void *gUnknown_03000F44; +static const struct PaletteStructTemplate gDummyPaletteStructTemplate = { + .uid = 0xFFFF, + .pst_field_B_5 = 1 +}; +static const u8 gUnknown_0852489C[] = { + 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, + 11, 11, 11, 11, 11, + 16, 16, 16, 16, 16, + 21, 21, 21, 21, 21, + 27, 27, 27, 27, 27, + 31, 31 +}; +void cur_mapheader_run_tileset1_func(void); +void cur_mapheader_run_tileset2_func(void); static void unused_sub_80A1CDC(struct PaletteStruct *, u32 *); static void unused_sub_80A1E40(struct PaletteStruct *, u32 *); static void unused_sub_80A1F00(struct PaletteStruct *); @@ -74,30 +138,798 @@ static u8 UpdateHardwarePaletteFade(void); static void UpdateBlendRegisters(void); static bool8 IsSoftwarePaletteFadeFinishing(void); +// tileset + +IWRAM_DATA u8 sTilesetDMA3TransferBufferSize; +IWRAM_DATA u16 sPrimaryTilesetCBCounter; +IWRAM_DATA u16 sPrimaryTilesetCBBufferSize; +IWRAM_DATA u16 sSecondaryTilesetCBCounter; +IWRAM_DATA u16 sSecondaryTilesetCBBufferSize; +IWRAM_DATA void (*sPrimaryTilesetCB)(u16); +IWRAM_DATA void (*sSecondaryTilesetCB)(u16); + +void sub_80A0954(void) +{ + sTilesetDMA3TransferBufferSize = 0; + CpuFill32(0, sTilesetDMA3TransferBuffer, sizeof sTilesetDMA3TransferBuffer); +} + +void sub_80A0980(const u16 *a0, u16 *a1, u16 a2) +{ + if (sTilesetDMA3TransferBufferSize < 20) + { + sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].src = a0; + sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].dest = a1; + sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].size = a2; + sTilesetDMA3TransferBufferSize ++; + } +} + +void sub_80A09D0(void) +{ + int i; + + for (i = 0; i < sTilesetDMA3TransferBufferSize; i ++) + { + DmaCopy16(3, sTilesetDMA3TransferBuffer[i].src, sTilesetDMA3TransferBuffer[i].dest, sTilesetDMA3TransferBuffer[i].size); + } + sTilesetDMA3TransferBufferSize = 0; +} + +void cur_mapheader_run_tileset_funcs_after_some_cpuset(void) +{ + sub_80A0954(); + cur_mapheader_run_tileset1_func(); + cur_mapheader_run_tileset2_func(); +} + +void sub_80A0A2C(void) +{ + cur_mapheader_run_tileset2_func(); +} + +void sub_80A0A38(void) +{ + sub_80A0954(); + if (++sPrimaryTilesetCBCounter >= sPrimaryTilesetCBBufferSize) + sPrimaryTilesetCBCounter = 0; + if (++sSecondaryTilesetCBCounter >= sSecondaryTilesetCBBufferSize) + sSecondaryTilesetCBCounter = 0; + if (sPrimaryTilesetCB) + sPrimaryTilesetCB(sPrimaryTilesetCBCounter); + if (sSecondaryTilesetCB) + sSecondaryTilesetCB(sSecondaryTilesetCBCounter); +} + +void cur_mapheader_run_tileset1_func(void) +{ + sPrimaryTilesetCBCounter = 0; + sPrimaryTilesetCBBufferSize = 0; + sPrimaryTilesetCB = NULL; + if (gMapHeader.mapData->primaryTileset && gMapHeader.mapData->primaryTileset->callback) + gMapHeader.mapData->primaryTileset->callback(); +} + +void cur_mapheader_run_tileset2_func(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = 0; + sSecondaryTilesetCB = NULL; + if (gMapHeader.mapData->secondaryTileset && gMapHeader.mapData->secondaryTileset->callback) + gMapHeader.mapData->secondaryTileset->callback(); +} + +void TilesetCb_General(void) +{ + void sub_80A0B70(u16); + + sPrimaryTilesetCBCounter = 0; + sPrimaryTilesetCBBufferSize = 0x100; + sPrimaryTilesetCB = sub_80A0B70; +} + +void TilesetCb_InsideBuilding(void) +{ + void sub_80A0BB4(u16); + + sPrimaryTilesetCBCounter = 0; + sPrimaryTilesetCBBufferSize = 0x100; + sPrimaryTilesetCB = sub_80A0BB4; +} + +void sub_80A0B70(u16 timer) +{ + void sub_80A0BCC(u16); + void sub_80A0BF4(u16); + void sub_80A0C1C(u16); + void sub_80A0C44(u16); + void sub_80A12AC(u16); + + if ((timer & 0x0F) == 0) + sub_80A0BCC(timer >> 4); + if ((timer & 0x0F) == 1) + sub_80A0BF4(timer >> 4); + if ((timer & 0x0F) == 2) + sub_80A0C1C(timer >> 4); + if ((timer & 0x0F) == 3) + sub_80A0C44(timer >> 4); + if ((timer & 0x0F) == 4) + sub_80A12AC(timer >> 4); +} + +void sub_80A0BB4(u16 timer) +{ + void sub_80A1688(u16); + if ((timer & 0x7) == 0) + sub_80A1688(timer >> 3); +} + +void sub_80A0BCC(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08510764[idx], (u16 *)(VRAM + 0x3F80), 0x80); +} + +void sub_80A0BF4(u16 timer) +{ + u8 idx; + + idx = timer % 8; + sub_80A0980(gUnknown_08512574[idx], (u16 *)(VRAM + 0x3600), 0x3C0); +} + +void sub_80A0C1C(u16 timer) +{ + u16 idx; + + idx = timer % 8; + sub_80A0980(gUnknown_08512E54[idx], (u16 *)(VRAM + 0x3a00), 0x140); +} + +void sub_80A0C44(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08513174[idx], (u16 *)(VRAM + 0x3e00), 0xc0); +} + +void TilesetCb_Petalburg(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = NULL; +} + +void TilesetCb_Rustboro(void) +{ + void sub_80A103C(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A103C; +} + +void TilesetCb_Dewford(void) +{ + void sub_80A10B8(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A10B8; +} + +void TilesetCb_Slateport(void) +{ + void sub_80A10D0(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A10D0; +} + +void TilesetCb_Mauville(void) +{ + void sub_80A10E8(u16); + + sSecondaryTilesetCBCounter = sPrimaryTilesetCBCounter; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A10E8; +} + +void TilesetCb_Lavaridge(void) +{ + void sub_80A115C(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A115C; +} + +void TilesetCb_Fallarbor(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = NULL; +} + +void TilesetCb_Fortree(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = NULL; +} + +void TilesetCb_Lilycove(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = NULL; +} + +void TilesetCb_Mossdeep(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = NULL; +} + +void TilesetCb_EverGrande(void) +{ + void sub_80A1188(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A1188; +} + +void TilesetCb_Pacifidlog(void) +{ + void sub_80A11FC(u16); + + sSecondaryTilesetCBCounter = sPrimaryTilesetCBCounter; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A11FC; +} + +void TilesetCb_Sootopolis(void) +{ + void sub_80A122C(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A122C; +} + +void TilesetCb_BattleFrontierOutsideWest(void) +{ + void sub_80A127C(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A127C; +} + +void TilesetCb_BattleFrontierOutsideEast(void) +{ + void sub_80A1294(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A1294; +} + +void TilesetCb_Underwater(void) +{ + void sub_80A1244(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = 128; + sSecondaryTilesetCB = sub_80A1244; +} + +void TilesetCb_SootopolisGym(void) +{ + void sub_80A15D8(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = 240; + sSecondaryTilesetCB = sub_80A15D8; +} + +void TilesetCb_Cave(void) +{ + void sub_80A1260(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A1260; +} + +void TilesetCb_EliteFour(void) +{ + void sub_80A15F0(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = 128; + sSecondaryTilesetCB = sub_80A15F0; +} + +void TilesetCb_MauvilleGym(void) +{ + void sub_80A15C0(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A15C0; +} + +void TilesetCb_BikeShop(void) +{ + void sub_80A161C(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A161C; +} + +void TilesetCb_BattlePyramid(void) +{ + void sub_80A1634(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A1634; +} + +void TilesetCb_BattleDome(void) +{ + void sub_80A1658(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A1658; +} + +void sub_80A103C(u16 timer) +{ + void sub_80A1434(u16, u8); + void sub_80A1470(u16); + + if ((timer & 0x07) == 0) + { + sub_80A1434(timer >> 3, 0); + sub_80A1470(timer >> 3); + } + if ((timer & 0x07) == 1) + sub_80A1434(timer >> 3, 1); + if ((timer & 0x07) == 2) + sub_80A1434(timer >> 3, 2); + if ((timer & 0x07) == 3) + sub_80A1434(timer >> 3, 3); + if ((timer & 0x07) == 4) + sub_80A1434(timer >> 3, 4); + if ((timer & 0x07) == 5) + sub_80A1434(timer >> 3, 5); + if ((timer & 0x07) == 6) + sub_80A1434(timer >> 3, 6); + if ((timer & 0x07) == 7) + sub_80A1434(timer >> 3, 7); +} + +void sub_80A10B8(u16 timer) +{ + void sub_80A1520(u16); + + if ((timer & 7) == 0) + sub_80A1520(timer >> 3); +} + +void sub_80A10D0(u16 timer) +{ + void sub_80A1598(u16); + + if ((timer & 15) == 0) + sub_80A1598(timer >> 4); +} + +void sub_80A10E8(u16 timer) +{ + void sub_80A1394(u16, u8); + + if ((timer & 0x07) == 0) + sub_80A1394(timer >> 3, 0); + if ((timer & 0x07) == 1) + sub_80A1394(timer >> 3, 1); + if ((timer & 0x07) == 2) + sub_80A1394(timer >> 3, 2); + if ((timer & 0x07) == 3) + sub_80A1394(timer >> 3, 3); + if ((timer & 0x07) == 4) + sub_80A1394(timer >> 3, 4); + if ((timer & 0x07) == 5) + sub_80A1394(timer >> 3, 5); + if ((timer & 0x07) == 6) + sub_80A1394(timer >> 3, 6); + if ((timer & 0x07) == 7) + sub_80A1394(timer >> 3, 7); +} + +void sub_80A115C(u16 timer) +{ + void sub_80A12D4(u8); + void sub_80A1498(u16); + + if ((timer & 0x0F) == 0) + sub_80A12D4(timer >> 4); + if ((timer & 0x0F) == 1) + sub_80A1498(timer >> 4); +} + +void sub_80A1188(u16 timer) +{ + void sub_80A14C0(u16, u8); + + if ((timer & 0x07) == 0) + sub_80A14C0(timer >> 3, 0); + if ((timer & 0x07) == 1) + sub_80A14C0(timer >> 3, 1); + if ((timer & 0x07) == 2) + sub_80A14C0(timer >> 3, 2); + if ((timer & 0x07) == 3) + sub_80A14C0(timer >> 3, 3); + if ((timer & 0x07) == 4) + sub_80A14C0(timer >> 3, 4); + if ((timer & 0x07) == 5) + sub_80A14C0(timer >> 3, 5); + if ((timer & 0x07) == 6) + sub_80A14C0(timer >> 3, 6); + if ((timer & 0x07) == 7) + sub_80A14C0(timer >> 3, 7); +} + +void sub_80A11FC(u16 timer) +{ + void sub_80A131C(u8); + void sub_80A136C(u8); + + if ((timer & 0x0F) == 0) + sub_80A131C(timer >> 4); + if ((timer & 0x0F) == 1) + sub_80A136C(timer >> 4); +} + +void sub_80A122C(u16 timer) +{ + void sub_80A1798(u16); + + if ((timer & 0x0F) == 0) + sub_80A1798(timer >> 4); +} + +void sub_80A1244(u16 timer) +{ + void sub_80A1344(u8); + + if ((timer & 0x0F) == 0) + sub_80A1344(timer >> 4); +} + +void sub_80A1260(u16 timer) +{ + void sub_80A14F8(u16); + + if ((timer & 0x0F) == 1) + sub_80A14F8(timer >> 4); +} + +void sub_80A127C(u16 timer) +{ + void sub_80A1548(u16); + + if ((timer & 0x07) == 0) + sub_80A1548(timer >> 3); +} + +void sub_80A1294(u16 timer) +{ + void sub_80A1570(u16); + + if ((timer & 0x07) == 0) + sub_80A1570(timer >> 3); +} + +void sub_80A12AC(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08513684[idx], (u16 *)(VRAM + 0x3c00), 0x140); +} + +void sub_80A12D4(u8 timer) +{ + u8 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08513894[idx], (u16 *)(VRAM + 0x6400), 0x80); + + idx = (timer + 2) % 4; + sub_80A0980(gUnknown_08513894[idx], (u16 *)(VRAM + 0x6480), 0x80); +} + +void sub_80A131C(u8 timer) +{ + u8 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_085143E4[idx], (u16 *)(VRAM + 0x7a00), 0x3C0); +} + +void sub_80A1344(u8 timer) +{ + u8 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_085145F4[idx], (u16 *)(VRAM + 0x7e00), 0x80); +} + +void sub_80A136C(u8 timer) +{ + u8 idx; + + idx = timer % 8; + sub_80A0980(gUnknown_08514E04[idx], (u16 *)(VRAM + 0x7e00), 0x100); +} + +void sub_80A1394(u16 timer_div, u8 timer_mod) +{ + timer_div -= timer_mod; + if (timer_div < 12) // almost certainly a typo + { + timer_div %= 12; + sub_80A0980(gUnknown_08515384[timer_div], gUnknown_08515344[timer_mod], 0x80); + sub_80A0980(gUnknown_085153B4[timer_div], gUnknown_08515364[timer_mod], 0x80); + } + else + { + timer_div &= 3; + sub_80A0980(gUnknown_085153E4[timer_div], gUnknown_08515344[timer_mod], 0x80); + sub_80A0980(gUnknown_085153F4[timer_div], gUnknown_08515364[timer_mod], 0x80); + } +} + +void sub_80A1434(u16 timer_div, u8 timer_mod) +{ + timer_div -= timer_mod; + timer_div &= 0x7; + if (gUnknown_08515824[timer_div]) + sub_80A0980(gUnknown_08515824[timer_div], gUnknown_08515804[timer_mod], 0x80); +} + +void sub_80A1470(u16 timer) +{ + u16 idx; + + idx = timer % 2; + sub_80A0980(gUnknown_08515964[idx], (u16 *)(VRAM + 0x7800), 0x80); +} + +void sub_80A1498(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(VRAM + 0x5400), 0x80); +} + +void sub_80A14C0(u16 timer_div, u8 timer_mod) +{ + timer_div -= timer_mod; + timer_div &= 7; + + sub_80A0980(gUnknown_085161DC[timer_div], gUnknown_085161BC[timer_mod], 0x80); +} + +void sub_80A14F8(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(VRAM + 0x7400), 0x80); +} + +void sub_80A1520(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_085164FC[idx], (u16 *)(VRAM + 0x5540), 0xC0); +} + +void sub_80A1548(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_0851680C[idx], (u16 *)(VRAM + 0x5b40), 0xC0); +} + +void sub_80A1570(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08516B1C[idx], (u16 *)(VRAM + 0x5b40), 0xC0); +} + +void sub_80A1598(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08516D2C[idx], (u16 *)(VRAM + 0x5c00), 0x80); +} + +void sub_80A15C0(u16 timer) +{ + void sub_80A1748(u16); + + if ((timer & 1) == 0) + sub_80A1748(timer >> 1); +} + +void sub_80A15D8(u16 timer) +{ + void sub_80A16B0(u16); + + if ((timer & 7) == 0) + sub_80A16B0(timer >> 3); +} + +void sub_80A15F0(u16 timer) +{ + void sub_80A1720(u16); + void sub_80A16F8(u16); + + if ((timer & 0x3f) == 1) + sub_80A1720(timer >> 6); + if ((timer & 0x07) == 1) + sub_80A16F8(timer >> 3); +} +void sub_80A161C(u16 timer) +{ + void sub_80A1770(u16); + + if ((timer & 3) == 0) + sub_80A1770(timer >> 2); +} + +void sub_80A1634(u16 timer) +{ + void sub_80A17C0(u16); + void sub_80A17EC(u16); + + if ((timer & 7) == 0) + { + sub_80A17C0(timer >> 3); + sub_80A17EC(timer >> 3); + } +} + +void sub_80A1658(u16 timer) +{ + void sub_80A1818(u16); + + if ((timer & 3) == 0) + sub_80A1818(timer >> 2); +} + +void sub_80A1670(u16 timer) +{ + void sub_80A1884(u16); + + if ((timer & 3) == 0) + sub_80A1884(timer >> 2); +} + +void sub_80A1688(u16 timer) +{ + u16 idx; + + idx = timer % 2; + sub_80A0980(gUnknown_08516E3C[idx], (u16 *)(VRAM + 0x3e00), 0x80); +} + +void sub_80A16B0(u16 timer) +{ + u16 idx; + + idx = timer % 3; + sub_80A0980(gUnknown_08517A44[idx], (u16 *)(VRAM + 0x7e00), 0x180); + sub_80A0980(gUnknown_08517A50[idx], (u16 *)(VRAM + 0x7a00), 0x280); +} + +void sub_80A16F8(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08517BFC[idx], (u16 *)(VRAM + 0x7f00), 0x20); +} + +void sub_80A1720(u16 timer) +{ + u16 idx; + + idx = timer % 2; + sub_80A0980(gUnknown_08517C0C[idx], (u16 *)(VRAM + 0x7c00), 0x80); +} + +void sub_80A1748(u16 timer) +{ + u16 idx; + + idx = timer % 2; + sub_80A0980(gUnknown_08518034[idx], (u16 *)(VRAM + 0x5200), 0x200); +} + +void sub_80A1770(u16 timer) +{ + u16 idx; + + idx = timer % 2; + sub_80A0980(gUnknown_0851829C[idx], (u16 *)(VRAM + 0x7e00), 0x120); +} + +void sub_80A1798(u16 timer) +{ + u16 idx; + + idx = timer % 8; + sub_80A0980(gUnknown_085202C4[idx], (u16 *)(VRAM + 0x5e00), 0xc00); +} + +void sub_80A17C0(u16 timer) +{ + u16 idx; + + idx = timer % 3; + sub_80A0980(gUnknown_08524864[idx], (u16 *)(VRAM + 0x52e0), 0x100); +} + +void sub_80A17EC(u16 timer) +{ + u16 idx; + + idx = timer % 3; + sub_80A0980(gUnknown_08524870[idx], (u16 *)(VRAM + 0x50e0), 0x100); +} + +// palette + void sub_80A1818(u16 a1) { - void **v1 = &gUnknown_0852487C; - CpuSet(v1[a1 & 0x3], gPlttBufferUnfaded + 0x80, 0x10); - BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); - if ((u8)FindTaskIdByFunc(sub_8149DFC) != 0xFF ) - { - gUnknown_03000F44 = sub_80A1670; - gUnknown_03000F3C = 0x20; - } - return; + CpuCopy16(gUnknown_0852487C[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); + BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); + if ((u8)FindTaskIdByFunc(sub_8149DFC) != 0xFF ) + { + sSecondaryTilesetCB = sub_80A1670; + sSecondaryTilesetCBBufferSize = 0x20; + } } void sub_80A1884(u16 a1) { - void **v1 = &gUnknown_0852487C; - CpuSet(v1[a1 & 0x3], gPlttBufferUnfaded + 0x80, 0x10); - if ((u8)FindTaskIdByFunc(sub_8149DFC) == 0xFF ) - { - BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); - if (!--gUnknown_03000F3C) - gUnknown_03000F44 = 0; - } - return; + CpuCopy16(gUnknown_0852487C[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); + if ((u8)FindTaskIdByFunc(sub_8149DFC) == 0xFF ) + { + BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); + if (!--sSecondaryTilesetCBBufferSize) + sSecondaryTilesetCB = NULL; + } } void LoadCompressedPalette(const void *src, u16 offset, u16 size) diff --git a/src/scrcmd.c b/src/scrcmd.c new file mode 100644 index 000000000..b56a53caf --- /dev/null +++ b/src/scrcmd.c @@ -0,0 +1,15 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations + +IWRAM_DATA u8 gUnknown_03000F30; + +// Static ROM declarations + +// .rodata + +// .text -- cgit v1.2.3 From a1ccd78218cf920bbf62278d02f143b903f1314e Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sat, 30 Sep 2017 22:16:51 -0400 Subject: Disassemble pointer tables in data/tileset.s --- src/palette.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/palette.c b/src/palette.c index 4c09206ba..da03516d0 100644 --- a/src/palette.c +++ b/src/palette.c @@ -62,8 +62,6 @@ EWRAM_DATA u32 sPlttBufferTransferPending = 0; EWRAM_DATA u8 gPaletteDecompressionBuffer[0x400] = {0}; extern const u16 *const gUnknown_08510764[]; -extern const u16 *const gUnknown_085112C4[]; -extern const u16 *const gUnknown_08511BCC[]; extern const u16 *const gUnknown_08512574[]; extern const u16 *const gUnknown_08512E54[]; extern const u16 *const gUnknown_08513174[]; @@ -695,7 +693,7 @@ void sub_80A1394(u16 timer_div, u8 timer_mod) } else { - timer_div &= 3; + timer_div %= 4; sub_80A0980(gUnknown_085153E4[timer_div], gUnknown_08515344[timer_mod], 0x80); sub_80A0980(gUnknown_085153F4[timer_div], gUnknown_08515364[timer_mod], 0x80); } @@ -704,7 +702,7 @@ void sub_80A1394(u16 timer_div, u8 timer_mod) void sub_80A1434(u16 timer_div, u8 timer_mod) { timer_div -= timer_mod; - timer_div &= 0x7; + timer_div %= 8; if (gUnknown_08515824[timer_div]) sub_80A0980(gUnknown_08515824[timer_div], gUnknown_08515804[timer_mod], 0x80); } @@ -728,7 +726,7 @@ void sub_80A1498(u16 timer) void sub_80A14C0(u16 timer_div, u8 timer_mod) { timer_div -= timer_mod; - timer_div &= 7; + timer_div %= 8; sub_80A0980(gUnknown_085161DC[timer_div], gUnknown_085161BC[timer_mod], 0x80); } -- cgit v1.2.3 From 993d5e2a6afb8f765ddd98ac32f01253a1476696 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 1 Oct 2017 21:50:58 -0400 Subject: clean up declarations in src/palette.c --- src/palette.c | 308 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 152 insertions(+), 156 deletions(-) (limited to 'src') diff --git a/src/palette.c b/src/palette.c index da03516d0..ed7eb99b3 100644 --- a/src/palette.c +++ b/src/palette.c @@ -1,5 +1,9 @@ #include "global.h" +#include "blend_palette.h" #include "palette.h" +#include "decompress.h" +#include "gpu_regs.h" +#include "battle.h" #include "task.h" enum @@ -38,15 +42,19 @@ struct PaletteStruct u8 ps_field_9; }; -extern void LZDecompressWram(const void *src, void *dest); -extern void SetGpuReg(u8 regOffset, u16 value); -extern void sub_8149DFC(u8 a1); -extern void sub_80A1670(u16 a1); -extern void sub_80A2D54(u8 a1); -extern void SetWordTaskArg(u8 taskId, u8 dataElem, u32 value); -extern void _call_via_r1(u32 a1, void *a2); - -extern void BlendPalette(u16, u16, u8, u16); +static void cur_mapheader_run_tileset1_func(void); +static void cur_mapheader_run_tileset2_func(void); +static void unused_sub_80A1CDC(struct PaletteStruct *, u32 *); +static void unused_sub_80A1E40(struct PaletteStruct *, u32 *); +static void unused_sub_80A1F00(struct PaletteStruct *); +static u8 GetPaletteNumByUid(u16); +static u8 UpdateNormalPaletteFade(void); +static void BeginFastPaletteFadeInternal(u8); +static u8 UpdateFastPaletteFade(void); +static u8 UpdateHardwarePaletteFade(void); +static void UpdateBlendRegisters(void); +static bool8 IsSoftwarePaletteFadeFinishing(void); +static void sub_80A2D54(u8 taskId); static EWRAM_DATA struct { const u16 *src; @@ -57,8 +65,8 @@ EWRAM_DATA u16 gPlttBufferUnfaded[0x200] = {0}; EWRAM_DATA u16 gPlttBufferFaded[0x200] = {0}; EWRAM_DATA struct PaletteStruct sPaletteStructs[0x10] = {0}; EWRAM_DATA struct PaletteFadeControl gPaletteFade = {0}; -EWRAM_DATA u32 gFiller_2037FE0 = 0; -EWRAM_DATA u32 sPlttBufferTransferPending = 0; +static EWRAM_DATA u32 gFiller_2037FE0 = 0; +static EWRAM_DATA u32 sPlttBufferTransferPending = 0; EWRAM_DATA u8 gPaletteDecompressionBuffer[0x400] = {0}; extern const u16 *const gUnknown_08510764[]; @@ -123,19 +131,6 @@ static const u8 gUnknown_0852489C[] = { 31, 31 }; -void cur_mapheader_run_tileset1_func(void); -void cur_mapheader_run_tileset2_func(void); -static void unused_sub_80A1CDC(struct PaletteStruct *, u32 *); -static void unused_sub_80A1E40(struct PaletteStruct *, u32 *); -static void unused_sub_80A1F00(struct PaletteStruct *); -static u8 GetPaletteNumByUid(u16); -static u8 UpdateNormalPaletteFade(void); -static void BeginFastPaletteFadeInternal(u8); -static u8 UpdateFastPaletteFade(void); -static u8 UpdateHardwarePaletteFade(void); -static void UpdateBlendRegisters(void); -static bool8 IsSoftwarePaletteFadeFinishing(void); - // tileset IWRAM_DATA u8 sTilesetDMA3TransferBufferSize; @@ -146,13 +141,13 @@ IWRAM_DATA u16 sSecondaryTilesetCBBufferSize; IWRAM_DATA void (*sPrimaryTilesetCB)(u16); IWRAM_DATA void (*sSecondaryTilesetCB)(u16); -void sub_80A0954(void) +static void sub_80A0954(void) { sTilesetDMA3TransferBufferSize = 0; CpuFill32(0, sTilesetDMA3TransferBuffer, sizeof sTilesetDMA3TransferBuffer); } -void sub_80A0980(const u16 *a0, u16 *a1, u16 a2) +static void sub_80A0980(const u16 *a0, u16 *a1, u16 a2) { if (sTilesetDMA3TransferBufferSize < 20) { @@ -199,7 +194,7 @@ void sub_80A0A38(void) sSecondaryTilesetCB(sSecondaryTilesetCBCounter); } -void cur_mapheader_run_tileset1_func(void) +static void cur_mapheader_run_tileset1_func(void) { sPrimaryTilesetCBCounter = 0; sPrimaryTilesetCBBufferSize = 0; @@ -208,7 +203,7 @@ void cur_mapheader_run_tileset1_func(void) gMapHeader.mapData->primaryTileset->callback(); } -void cur_mapheader_run_tileset2_func(void) +static void cur_mapheader_run_tileset2_func(void) { sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = 0; @@ -219,7 +214,7 @@ void cur_mapheader_run_tileset2_func(void) void TilesetCb_General(void) { - void sub_80A0B70(u16); + static void sub_80A0B70(u16); sPrimaryTilesetCBCounter = 0; sPrimaryTilesetCBBufferSize = 0x100; @@ -228,20 +223,20 @@ void TilesetCb_General(void) void TilesetCb_InsideBuilding(void) { - void sub_80A0BB4(u16); + static void sub_80A0BB4(u16); sPrimaryTilesetCBCounter = 0; sPrimaryTilesetCBBufferSize = 0x100; sPrimaryTilesetCB = sub_80A0BB4; } -void sub_80A0B70(u16 timer) +static void sub_80A0B70(u16 timer) { - void sub_80A0BCC(u16); - void sub_80A0BF4(u16); - void sub_80A0C1C(u16); - void sub_80A0C44(u16); - void sub_80A12AC(u16); + static void sub_80A0BCC(u16); + static void sub_80A0BF4(u16); + static void sub_80A0C1C(u16); + static void sub_80A0C44(u16); + static void sub_80A12AC(u16); if ((timer & 0x0F) == 0) sub_80A0BCC(timer >> 4); @@ -255,43 +250,44 @@ void sub_80A0B70(u16 timer) sub_80A12AC(timer >> 4); } -void sub_80A0BB4(u16 timer) +static void sub_80A0BB4(u16 timer) { - void sub_80A1688(u16); + static void sub_80A1688(u16); + if ((timer & 0x7) == 0) sub_80A1688(timer >> 3); } -void sub_80A0BCC(u16 timer) +static void sub_80A0BCC(u16 timer) { u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08510764[idx], (u16 *)(VRAM + 0x3F80), 0x80); + sub_80A0980(gUnknown_08510764[idx], (u16 *)(BG_VRAM + 0x3F80), 0x80); } -void sub_80A0BF4(u16 timer) +static void sub_80A0BF4(u16 timer) { u8 idx; idx = timer % 8; - sub_80A0980(gUnknown_08512574[idx], (u16 *)(VRAM + 0x3600), 0x3C0); + sub_80A0980(gUnknown_08512574[idx], (u16 *)(BG_VRAM + 0x3600), 0x3C0); } -void sub_80A0C1C(u16 timer) +static void sub_80A0C1C(u16 timer) { u16 idx; idx = timer % 8; - sub_80A0980(gUnknown_08512E54[idx], (u16 *)(VRAM + 0x3a00), 0x140); + sub_80A0980(gUnknown_08512E54[idx], (u16 *)(BG_VRAM + 0x3a00), 0x140); } -void sub_80A0C44(u16 timer) +static void sub_80A0C44(u16 timer) { u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08513174[idx], (u16 *)(VRAM + 0x3e00), 0xc0); + sub_80A0980(gUnknown_08513174[idx], (u16 *)(BG_VRAM + 0x3e00), 0xc0); } void TilesetCb_Petalburg(void) @@ -303,7 +299,7 @@ void TilesetCb_Petalburg(void) void TilesetCb_Rustboro(void) { - void sub_80A103C(u16); + static void sub_80A103C(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -312,7 +308,7 @@ void TilesetCb_Rustboro(void) void TilesetCb_Dewford(void) { - void sub_80A10B8(u16); + static void sub_80A10B8(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -321,7 +317,7 @@ void TilesetCb_Dewford(void) void TilesetCb_Slateport(void) { - void sub_80A10D0(u16); + static void sub_80A10D0(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -330,7 +326,7 @@ void TilesetCb_Slateport(void) void TilesetCb_Mauville(void) { - void sub_80A10E8(u16); + static void sub_80A10E8(u16); sSecondaryTilesetCBCounter = sPrimaryTilesetCBCounter; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -339,7 +335,7 @@ void TilesetCb_Mauville(void) void TilesetCb_Lavaridge(void) { - void sub_80A115C(u16); + static void sub_80A115C(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -376,7 +372,7 @@ void TilesetCb_Mossdeep(void) void TilesetCb_EverGrande(void) { - void sub_80A1188(u16); + static void sub_80A1188(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -385,7 +381,7 @@ void TilesetCb_EverGrande(void) void TilesetCb_Pacifidlog(void) { - void sub_80A11FC(u16); + static void sub_80A11FC(u16); sSecondaryTilesetCBCounter = sPrimaryTilesetCBCounter; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -394,7 +390,7 @@ void TilesetCb_Pacifidlog(void) void TilesetCb_Sootopolis(void) { - void sub_80A122C(u16); + static void sub_80A122C(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -403,7 +399,7 @@ void TilesetCb_Sootopolis(void) void TilesetCb_BattleFrontierOutsideWest(void) { - void sub_80A127C(u16); + static void sub_80A127C(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -412,7 +408,7 @@ void TilesetCb_BattleFrontierOutsideWest(void) void TilesetCb_BattleFrontierOutsideEast(void) { - void sub_80A1294(u16); + static void sub_80A1294(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -421,7 +417,7 @@ void TilesetCb_BattleFrontierOutsideEast(void) void TilesetCb_Underwater(void) { - void sub_80A1244(u16); + static void sub_80A1244(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = 128; @@ -430,7 +426,7 @@ void TilesetCb_Underwater(void) void TilesetCb_SootopolisGym(void) { - void sub_80A15D8(u16); + static void sub_80A15D8(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = 240; @@ -439,7 +435,7 @@ void TilesetCb_SootopolisGym(void) void TilesetCb_Cave(void) { - void sub_80A1260(u16); + static void sub_80A1260(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -448,7 +444,7 @@ void TilesetCb_Cave(void) void TilesetCb_EliteFour(void) { - void sub_80A15F0(u16); + static void sub_80A15F0(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = 128; @@ -457,7 +453,7 @@ void TilesetCb_EliteFour(void) void TilesetCb_MauvilleGym(void) { - void sub_80A15C0(u16); + static void sub_80A15C0(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -466,7 +462,7 @@ void TilesetCb_MauvilleGym(void) void TilesetCb_BikeShop(void) { - void sub_80A161C(u16); + static void sub_80A161C(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -475,7 +471,7 @@ void TilesetCb_BikeShop(void) void TilesetCb_BattlePyramid(void) { - void sub_80A1634(u16); + static void sub_80A1634(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; @@ -484,17 +480,17 @@ void TilesetCb_BattlePyramid(void) void TilesetCb_BattleDome(void) { - void sub_80A1658(u16); + static void sub_80A1658(u16); sSecondaryTilesetCBCounter = 0; sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; sSecondaryTilesetCB = sub_80A1658; } -void sub_80A103C(u16 timer) +static void sub_80A103C(u16 timer) { - void sub_80A1434(u16, u8); - void sub_80A1470(u16); + static void sub_80A1434(u16, u8); + static void sub_80A1470(u16); if ((timer & 0x07) == 0) { @@ -517,25 +513,25 @@ void sub_80A103C(u16 timer) sub_80A1434(timer >> 3, 7); } -void sub_80A10B8(u16 timer) +static void sub_80A10B8(u16 timer) { - void sub_80A1520(u16); + static void sub_80A1520(u16); if ((timer & 7) == 0) sub_80A1520(timer >> 3); } -void sub_80A10D0(u16 timer) +static void sub_80A10D0(u16 timer) { - void sub_80A1598(u16); + static void sub_80A1598(u16); if ((timer & 15) == 0) sub_80A1598(timer >> 4); } -void sub_80A10E8(u16 timer) +static void sub_80A10E8(u16 timer) { - void sub_80A1394(u16, u8); + static void sub_80A1394(u16, u8); if ((timer & 0x07) == 0) sub_80A1394(timer >> 3, 0); @@ -555,10 +551,10 @@ void sub_80A10E8(u16 timer) sub_80A1394(timer >> 3, 7); } -void sub_80A115C(u16 timer) +static void sub_80A115C(u16 timer) { - void sub_80A12D4(u8); - void sub_80A1498(u16); + static void sub_80A12D4(u8); + static void sub_80A1498(u16); if ((timer & 0x0F) == 0) sub_80A12D4(timer >> 4); @@ -566,9 +562,9 @@ void sub_80A115C(u16 timer) sub_80A1498(timer >> 4); } -void sub_80A1188(u16 timer) +static void sub_80A1188(u16 timer) { - void sub_80A14C0(u16, u8); + static void sub_80A14C0(u16, u8); if ((timer & 0x07) == 0) sub_80A14C0(timer >> 3, 0); @@ -588,10 +584,10 @@ void sub_80A1188(u16 timer) sub_80A14C0(timer >> 3, 7); } -void sub_80A11FC(u16 timer) +static void sub_80A11FC(u16 timer) { - void sub_80A131C(u8); - void sub_80A136C(u8); + static void sub_80A131C(u8); + static void sub_80A136C(u8); if ((timer & 0x0F) == 0) sub_80A131C(timer >> 4); @@ -599,90 +595,90 @@ void sub_80A11FC(u16 timer) sub_80A136C(timer >> 4); } -void sub_80A122C(u16 timer) +static void sub_80A122C(u16 timer) { - void sub_80A1798(u16); + static void sub_80A1798(u16); if ((timer & 0x0F) == 0) sub_80A1798(timer >> 4); } -void sub_80A1244(u16 timer) +static void sub_80A1244(u16 timer) { - void sub_80A1344(u8); + static void sub_80A1344(u8); if ((timer & 0x0F) == 0) sub_80A1344(timer >> 4); } -void sub_80A1260(u16 timer) +static void sub_80A1260(u16 timer) { - void sub_80A14F8(u16); + static void sub_80A14F8(u16); if ((timer & 0x0F) == 1) sub_80A14F8(timer >> 4); } -void sub_80A127C(u16 timer) +static void sub_80A127C(u16 timer) { - void sub_80A1548(u16); + static void sub_80A1548(u16); if ((timer & 0x07) == 0) sub_80A1548(timer >> 3); } -void sub_80A1294(u16 timer) +static void sub_80A1294(u16 timer) { - void sub_80A1570(u16); + static void sub_80A1570(u16); if ((timer & 0x07) == 0) sub_80A1570(timer >> 3); } -void sub_80A12AC(u16 timer) +static void sub_80A12AC(u16 timer) { u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08513684[idx], (u16 *)(VRAM + 0x3c00), 0x140); + sub_80A0980(gUnknown_08513684[idx], (u16 *)(BG_VRAM + 0x3c00), 0x140); } -void sub_80A12D4(u8 timer) +static void sub_80A12D4(u8 timer) { u8 idx; idx = timer % 4; - sub_80A0980(gUnknown_08513894[idx], (u16 *)(VRAM + 0x6400), 0x80); + sub_80A0980(gUnknown_08513894[idx], (u16 *)(BG_VRAM + 0x6400), 0x80); idx = (timer + 2) % 4; - sub_80A0980(gUnknown_08513894[idx], (u16 *)(VRAM + 0x6480), 0x80); + sub_80A0980(gUnknown_08513894[idx], (u16 *)(BG_VRAM + 0x6480), 0x80); } -void sub_80A131C(u8 timer) +static void sub_80A131C(u8 timer) { u8 idx; idx = timer % 4; - sub_80A0980(gUnknown_085143E4[idx], (u16 *)(VRAM + 0x7a00), 0x3C0); + sub_80A0980(gUnknown_085143E4[idx], (u16 *)(BG_VRAM + 0x7a00), 0x3C0); } -void sub_80A1344(u8 timer) +static void sub_80A1344(u8 timer) { u8 idx; idx = timer % 4; - sub_80A0980(gUnknown_085145F4[idx], (u16 *)(VRAM + 0x7e00), 0x80); + sub_80A0980(gUnknown_085145F4[idx], (u16 *)(BG_VRAM + 0x7e00), 0x80); } -void sub_80A136C(u8 timer) +static void sub_80A136C(u8 timer) { u8 idx; idx = timer % 8; - sub_80A0980(gUnknown_08514E04[idx], (u16 *)(VRAM + 0x7e00), 0x100); + sub_80A0980(gUnknown_08514E04[idx], (u16 *)(BG_VRAM + 0x7e00), 0x100); } -void sub_80A1394(u16 timer_div, u8 timer_mod) +static void sub_80A1394(u16 timer_div, u8 timer_mod) { timer_div -= timer_mod; if (timer_div < 12) // almost certainly a typo @@ -699,7 +695,7 @@ void sub_80A1394(u16 timer_div, u8 timer_mod) } } -void sub_80A1434(u16 timer_div, u8 timer_mod) +static void sub_80A1434(u16 timer_div, u8 timer_mod) { timer_div -= timer_mod; timer_div %= 8; @@ -707,23 +703,23 @@ void sub_80A1434(u16 timer_div, u8 timer_mod) sub_80A0980(gUnknown_08515824[timer_div], gUnknown_08515804[timer_mod], 0x80); } -void sub_80A1470(u16 timer) +static void sub_80A1470(u16 timer) { u16 idx; idx = timer % 2; - sub_80A0980(gUnknown_08515964[idx], (u16 *)(VRAM + 0x7800), 0x80); + sub_80A0980(gUnknown_08515964[idx], (u16 *)(BG_VRAM + 0x7800), 0x80); } -void sub_80A1498(u16 timer) +static void sub_80A1498(u16 timer) { u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(VRAM + 0x5400), 0x80); + sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(BG_VRAM + 0x5400), 0x80); } -void sub_80A14C0(u16 timer_div, u8 timer_mod) +static void sub_80A14C0(u16 timer_div, u8 timer_mod) { timer_div -= timer_mod; timer_div %= 8; @@ -731,84 +727,84 @@ void sub_80A14C0(u16 timer_div, u8 timer_mod) sub_80A0980(gUnknown_085161DC[timer_div], gUnknown_085161BC[timer_mod], 0x80); } -void sub_80A14F8(u16 timer) +static void sub_80A14F8(u16 timer) { u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(VRAM + 0x7400), 0x80); + sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(BG_VRAM + 0x7400), 0x80); } -void sub_80A1520(u16 timer) +static void sub_80A1520(u16 timer) { u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_085164FC[idx], (u16 *)(VRAM + 0x5540), 0xC0); + sub_80A0980(gUnknown_085164FC[idx], (u16 *)(BG_VRAM + 0x5540), 0xC0); } -void sub_80A1548(u16 timer) +static void sub_80A1548(u16 timer) { u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_0851680C[idx], (u16 *)(VRAM + 0x5b40), 0xC0); + sub_80A0980(gUnknown_0851680C[idx], (u16 *)(BG_VRAM + 0x5b40), 0xC0); } -void sub_80A1570(u16 timer) +static void sub_80A1570(u16 timer) { u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08516B1C[idx], (u16 *)(VRAM + 0x5b40), 0xC0); + sub_80A0980(gUnknown_08516B1C[idx], (u16 *)(BG_VRAM + 0x5b40), 0xC0); } -void sub_80A1598(u16 timer) +static void sub_80A1598(u16 timer) { u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08516D2C[idx], (u16 *)(VRAM + 0x5c00), 0x80); + sub_80A0980(gUnknown_08516D2C[idx], (u16 *)(BG_VRAM + 0x5c00), 0x80); } -void sub_80A15C0(u16 timer) +static void sub_80A15C0(u16 timer) { - void sub_80A1748(u16); + static void sub_80A1748(u16); if ((timer & 1) == 0) sub_80A1748(timer >> 1); } -void sub_80A15D8(u16 timer) +static void sub_80A15D8(u16 timer) { - void sub_80A16B0(u16); + static void sub_80A16B0(u16); if ((timer & 7) == 0) sub_80A16B0(timer >> 3); } -void sub_80A15F0(u16 timer) +static void sub_80A15F0(u16 timer) { - void sub_80A1720(u16); - void sub_80A16F8(u16); + static void sub_80A1720(u16); + static void sub_80A16F8(u16); if ((timer & 0x3f) == 1) sub_80A1720(timer >> 6); if ((timer & 0x07) == 1) sub_80A16F8(timer >> 3); } -void sub_80A161C(u16 timer) +static void sub_80A161C(u16 timer) { - void sub_80A1770(u16); + static void sub_80A1770(u16); if ((timer & 3) == 0) sub_80A1770(timer >> 2); } -void sub_80A1634(u16 timer) +static void sub_80A1634(u16 timer) { - void sub_80A17C0(u16); - void sub_80A17EC(u16); + static void sub_80A17C0(u16); + static void sub_80A17EC(u16); if ((timer & 7) == 0) { @@ -817,98 +813,98 @@ void sub_80A1634(u16 timer) } } -void sub_80A1658(u16 timer) +static void sub_80A1658(u16 timer) { - void sub_80A1818(u16); + static void sub_80A1818(u16); if ((timer & 3) == 0) sub_80A1818(timer >> 2); } -void sub_80A1670(u16 timer) +static void sub_80A1670(u16 timer) { - void sub_80A1884(u16); + static void sub_80A1884(u16); if ((timer & 3) == 0) sub_80A1884(timer >> 2); } -void sub_80A1688(u16 timer) +static void sub_80A1688(u16 timer) { u16 idx; idx = timer % 2; - sub_80A0980(gUnknown_08516E3C[idx], (u16 *)(VRAM + 0x3e00), 0x80); + sub_80A0980(gUnknown_08516E3C[idx], (u16 *)(BG_VRAM + 0x3e00), 0x80); } -void sub_80A16B0(u16 timer) +static void sub_80A16B0(u16 timer) { u16 idx; idx = timer % 3; - sub_80A0980(gUnknown_08517A44[idx], (u16 *)(VRAM + 0x7e00), 0x180); - sub_80A0980(gUnknown_08517A50[idx], (u16 *)(VRAM + 0x7a00), 0x280); + sub_80A0980(gUnknown_08517A44[idx], (u16 *)(BG_VRAM + 0x7e00), 0x180); + sub_80A0980(gUnknown_08517A50[idx], (u16 *)(BG_VRAM + 0x7a00), 0x280); } -void sub_80A16F8(u16 timer) +static void sub_80A16F8(u16 timer) { u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08517BFC[idx], (u16 *)(VRAM + 0x7f00), 0x20); + sub_80A0980(gUnknown_08517BFC[idx], (u16 *)(BG_VRAM + 0x7f00), 0x20); } -void sub_80A1720(u16 timer) +static void sub_80A1720(u16 timer) { u16 idx; idx = timer % 2; - sub_80A0980(gUnknown_08517C0C[idx], (u16 *)(VRAM + 0x7c00), 0x80); + sub_80A0980(gUnknown_08517C0C[idx], (u16 *)(BG_VRAM + 0x7c00), 0x80); } -void sub_80A1748(u16 timer) +static void sub_80A1748(u16 timer) { u16 idx; idx = timer % 2; - sub_80A0980(gUnknown_08518034[idx], (u16 *)(VRAM + 0x5200), 0x200); + sub_80A0980(gUnknown_08518034[idx], (u16 *)(BG_VRAM + 0x5200), 0x200); } -void sub_80A1770(u16 timer) +static void sub_80A1770(u16 timer) { u16 idx; idx = timer % 2; - sub_80A0980(gUnknown_0851829C[idx], (u16 *)(VRAM + 0x7e00), 0x120); + sub_80A0980(gUnknown_0851829C[idx], (u16 *)(BG_VRAM + 0x7e00), 0x120); } -void sub_80A1798(u16 timer) +static void sub_80A1798(u16 timer) { u16 idx; idx = timer % 8; - sub_80A0980(gUnknown_085202C4[idx], (u16 *)(VRAM + 0x5e00), 0xc00); + sub_80A0980(gUnknown_085202C4[idx], (u16 *)(BG_VRAM + 0x5e00), 0xc00); } -void sub_80A17C0(u16 timer) +static void sub_80A17C0(u16 timer) { u16 idx; idx = timer % 3; - sub_80A0980(gUnknown_08524864[idx], (u16 *)(VRAM + 0x52e0), 0x100); + sub_80A0980(gUnknown_08524864[idx], (u16 *)(BG_VRAM + 0x52e0), 0x100); } -void sub_80A17EC(u16 timer) +static void sub_80A17EC(u16 timer) { u16 idx; idx = timer % 3; - sub_80A0980(gUnknown_08524870[idx], (u16 *)(VRAM + 0x50e0), 0x100); + sub_80A0980(gUnknown_08524870[idx], (u16 *)(BG_VRAM + 0x50e0), 0x100); } // palette -void sub_80A1818(u16 a1) +static void sub_80A1818(u16 a1) { CpuCopy16(gUnknown_0852487C[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); @@ -919,7 +915,7 @@ void sub_80A1818(u16 a1) } } -void sub_80A1884(u16 a1) +static void sub_80A1884(u16 a1) { CpuCopy16(gUnknown_0852487C[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); if ((u8)FindTaskIdByFunc(sub_8149DFC) == 0xFF ) -- cgit v1.2.3 From 3ec4d98de95a2aeb12f3c738b3496d0b3a830793 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Sun, 1 Oct 2017 21:58:47 -0400 Subject: Split palette and tileset_anims --- src/palette.c | 851 --------------------------------------------------- src/tileset_anims.c | 865 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 865 insertions(+), 851 deletions(-) create mode 100644 src/tileset_anims.c (limited to 'src') diff --git a/src/palette.c b/src/palette.c index ed7eb99b3..d60efdbc5 100644 --- a/src/palette.c +++ b/src/palette.c @@ -3,7 +3,6 @@ #include "palette.h" #include "decompress.h" #include "gpu_regs.h" -#include "battle.h" #include "task.h" enum @@ -42,8 +41,6 @@ struct PaletteStruct u8 ps_field_9; }; -static void cur_mapheader_run_tileset1_func(void); -static void cur_mapheader_run_tileset2_func(void); static void unused_sub_80A1CDC(struct PaletteStruct *, u32 *); static void unused_sub_80A1E40(struct PaletteStruct *, u32 *); static void unused_sub_80A1F00(struct PaletteStruct *); @@ -56,11 +53,6 @@ static void UpdateBlendRegisters(void); static bool8 IsSoftwarePaletteFadeFinishing(void); static void sub_80A2D54(u8 taskId); -static EWRAM_DATA struct { - const u16 *src; - u16 *dest; - u16 size; -} sTilesetDMA3TransferBuffer[20] = {0}; EWRAM_DATA u16 gPlttBufferUnfaded[0x200] = {0}; EWRAM_DATA u16 gPlttBufferFaded[0x200] = {0}; EWRAM_DATA struct PaletteStruct sPaletteStructs[0x10] = {0}; @@ -69,54 +61,6 @@ static EWRAM_DATA u32 gFiller_2037FE0 = 0; static EWRAM_DATA u32 sPlttBufferTransferPending = 0; EWRAM_DATA u8 gPaletteDecompressionBuffer[0x400] = {0}; -extern const u16 *const gUnknown_08510764[]; -extern const u16 *const gUnknown_08512574[]; -extern const u16 *const gUnknown_08512E54[]; -extern const u16 *const gUnknown_08513174[]; -extern const u16 *const gUnknown_08513684[]; -extern const u16 *const gUnknown_08513894[]; -extern const u16 *const gUnknown_085143E4[]; -extern const u16 *const gUnknown_085145F4[]; -extern const u16 *const gUnknown_08514E04[]; -extern u16 *const gUnknown_08515344[]; -extern u16 *const gUnknown_08515364[]; -extern const u16 *const gUnknown_08515384[]; -extern const u16 *const gUnknown_085153B4[]; -extern const u16 *const gUnknown_085153E4[]; -extern const u16 *const gUnknown_085153F4[]; -extern u16 *const gUnknown_08515804[]; -extern const u16 *const gUnknown_08515824[]; -extern const u16 *const gUnknown_08515964[]; -extern const u16 *const gUnknown_08515D8C[]; -extern u16 *const gUnknown_085161BC[]; -extern const u16 *const gUnknown_085161DC[]; -extern const u16 *const gUnknown_085164FC[]; -extern const u16 *const gUnknown_0851680C[]; -extern const u16 *const gUnknown_08516B1C[]; -extern const u16 *const gUnknown_08516D2C[]; -extern const u16 *const gUnknown_08516E3C[]; -extern const u16 *const gUnknown_08517A44[]; -extern const u16 *const gUnknown_08517A50[]; -extern const u16 *const gUnknown_08517BFC[]; -extern const u16 *const gUnknown_08517C0C[]; -extern const u16 *const gUnknown_08518034[]; -extern const u16 *const gUnknown_0851829C[]; -extern const u16 *const gUnknown_085202C4[]; -extern const u16 *const gUnknown_08524864[]; -extern const u16 *const gUnknown_08524870[]; - -extern const u16 gUnknown_08D85640[]; -extern const u16 gUnknown_08D85660[]; -extern const u16 gUnknown_08D85680[]; -extern const u16 gUnknown_08D856A0[]; - -static const u16 *const gUnknown_0852487C[] = { - gUnknown_08D85640, - gUnknown_08D85660, - gUnknown_08D85680, - gUnknown_08D856A0, -}; - static const struct PaletteStructTemplate gDummyPaletteStructTemplate = { .uid = 0xFFFF, .pst_field_B_5 = 1 @@ -131,801 +75,6 @@ static const u8 gUnknown_0852489C[] = { 31, 31 }; -// tileset - -IWRAM_DATA u8 sTilesetDMA3TransferBufferSize; -IWRAM_DATA u16 sPrimaryTilesetCBCounter; -IWRAM_DATA u16 sPrimaryTilesetCBBufferSize; -IWRAM_DATA u16 sSecondaryTilesetCBCounter; -IWRAM_DATA u16 sSecondaryTilesetCBBufferSize; -IWRAM_DATA void (*sPrimaryTilesetCB)(u16); -IWRAM_DATA void (*sSecondaryTilesetCB)(u16); - -static void sub_80A0954(void) -{ - sTilesetDMA3TransferBufferSize = 0; - CpuFill32(0, sTilesetDMA3TransferBuffer, sizeof sTilesetDMA3TransferBuffer); -} - -static void sub_80A0980(const u16 *a0, u16 *a1, u16 a2) -{ - if (sTilesetDMA3TransferBufferSize < 20) - { - sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].src = a0; - sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].dest = a1; - sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].size = a2; - sTilesetDMA3TransferBufferSize ++; - } -} - -void sub_80A09D0(void) -{ - int i; - - for (i = 0; i < sTilesetDMA3TransferBufferSize; i ++) - { - DmaCopy16(3, sTilesetDMA3TransferBuffer[i].src, sTilesetDMA3TransferBuffer[i].dest, sTilesetDMA3TransferBuffer[i].size); - } - sTilesetDMA3TransferBufferSize = 0; -} - -void cur_mapheader_run_tileset_funcs_after_some_cpuset(void) -{ - sub_80A0954(); - cur_mapheader_run_tileset1_func(); - cur_mapheader_run_tileset2_func(); -} - -void sub_80A0A2C(void) -{ - cur_mapheader_run_tileset2_func(); -} - -void sub_80A0A38(void) -{ - sub_80A0954(); - if (++sPrimaryTilesetCBCounter >= sPrimaryTilesetCBBufferSize) - sPrimaryTilesetCBCounter = 0; - if (++sSecondaryTilesetCBCounter >= sSecondaryTilesetCBBufferSize) - sSecondaryTilesetCBCounter = 0; - if (sPrimaryTilesetCB) - sPrimaryTilesetCB(sPrimaryTilesetCBCounter); - if (sSecondaryTilesetCB) - sSecondaryTilesetCB(sSecondaryTilesetCBCounter); -} - -static void cur_mapheader_run_tileset1_func(void) -{ - sPrimaryTilesetCBCounter = 0; - sPrimaryTilesetCBBufferSize = 0; - sPrimaryTilesetCB = NULL; - if (gMapHeader.mapData->primaryTileset && gMapHeader.mapData->primaryTileset->callback) - gMapHeader.mapData->primaryTileset->callback(); -} - -static void cur_mapheader_run_tileset2_func(void) -{ - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = 0; - sSecondaryTilesetCB = NULL; - if (gMapHeader.mapData->secondaryTileset && gMapHeader.mapData->secondaryTileset->callback) - gMapHeader.mapData->secondaryTileset->callback(); -} - -void TilesetCb_General(void) -{ - static void sub_80A0B70(u16); - - sPrimaryTilesetCBCounter = 0; - sPrimaryTilesetCBBufferSize = 0x100; - sPrimaryTilesetCB = sub_80A0B70; -} - -void TilesetCb_InsideBuilding(void) -{ - static void sub_80A0BB4(u16); - - sPrimaryTilesetCBCounter = 0; - sPrimaryTilesetCBBufferSize = 0x100; - sPrimaryTilesetCB = sub_80A0BB4; -} - -static void sub_80A0B70(u16 timer) -{ - static void sub_80A0BCC(u16); - static void sub_80A0BF4(u16); - static void sub_80A0C1C(u16); - static void sub_80A0C44(u16); - static void sub_80A12AC(u16); - - if ((timer & 0x0F) == 0) - sub_80A0BCC(timer >> 4); - if ((timer & 0x0F) == 1) - sub_80A0BF4(timer >> 4); - if ((timer & 0x0F) == 2) - sub_80A0C1C(timer >> 4); - if ((timer & 0x0F) == 3) - sub_80A0C44(timer >> 4); - if ((timer & 0x0F) == 4) - sub_80A12AC(timer >> 4); -} - -static void sub_80A0BB4(u16 timer) -{ - static void sub_80A1688(u16); - - if ((timer & 0x7) == 0) - sub_80A1688(timer >> 3); -} - -static void sub_80A0BCC(u16 timer) -{ - u16 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_08510764[idx], (u16 *)(BG_VRAM + 0x3F80), 0x80); -} - -static void sub_80A0BF4(u16 timer) -{ - u8 idx; - - idx = timer % 8; - sub_80A0980(gUnknown_08512574[idx], (u16 *)(BG_VRAM + 0x3600), 0x3C0); -} - -static void sub_80A0C1C(u16 timer) -{ - u16 idx; - - idx = timer % 8; - sub_80A0980(gUnknown_08512E54[idx], (u16 *)(BG_VRAM + 0x3a00), 0x140); -} - -static void sub_80A0C44(u16 timer) -{ - u16 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_08513174[idx], (u16 *)(BG_VRAM + 0x3e00), 0xc0); -} - -void TilesetCb_Petalburg(void) -{ - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = NULL; -} - -void TilesetCb_Rustboro(void) -{ - static void sub_80A103C(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A103C; -} - -void TilesetCb_Dewford(void) -{ - static void sub_80A10B8(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A10B8; -} - -void TilesetCb_Slateport(void) -{ - static void sub_80A10D0(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A10D0; -} - -void TilesetCb_Mauville(void) -{ - static void sub_80A10E8(u16); - - sSecondaryTilesetCBCounter = sPrimaryTilesetCBCounter; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A10E8; -} - -void TilesetCb_Lavaridge(void) -{ - static void sub_80A115C(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A115C; -} - -void TilesetCb_Fallarbor(void) -{ - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = NULL; -} - -void TilesetCb_Fortree(void) -{ - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = NULL; -} - -void TilesetCb_Lilycove(void) -{ - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = NULL; -} - -void TilesetCb_Mossdeep(void) -{ - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = NULL; -} - -void TilesetCb_EverGrande(void) -{ - static void sub_80A1188(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A1188; -} - -void TilesetCb_Pacifidlog(void) -{ - static void sub_80A11FC(u16); - - sSecondaryTilesetCBCounter = sPrimaryTilesetCBCounter; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A11FC; -} - -void TilesetCb_Sootopolis(void) -{ - static void sub_80A122C(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A122C; -} - -void TilesetCb_BattleFrontierOutsideWest(void) -{ - static void sub_80A127C(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A127C; -} - -void TilesetCb_BattleFrontierOutsideEast(void) -{ - static void sub_80A1294(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A1294; -} - -void TilesetCb_Underwater(void) -{ - static void sub_80A1244(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = 128; - sSecondaryTilesetCB = sub_80A1244; -} - -void TilesetCb_SootopolisGym(void) -{ - static void sub_80A15D8(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = 240; - sSecondaryTilesetCB = sub_80A15D8; -} - -void TilesetCb_Cave(void) -{ - static void sub_80A1260(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A1260; -} - -void TilesetCb_EliteFour(void) -{ - static void sub_80A15F0(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = 128; - sSecondaryTilesetCB = sub_80A15F0; -} - -void TilesetCb_MauvilleGym(void) -{ - static void sub_80A15C0(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A15C0; -} - -void TilesetCb_BikeShop(void) -{ - static void sub_80A161C(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A161C; -} - -void TilesetCb_BattlePyramid(void) -{ - static void sub_80A1634(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A1634; -} - -void TilesetCb_BattleDome(void) -{ - static void sub_80A1658(u16); - - sSecondaryTilesetCBCounter = 0; - sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; - sSecondaryTilesetCB = sub_80A1658; -} - -static void sub_80A103C(u16 timer) -{ - static void sub_80A1434(u16, u8); - static void sub_80A1470(u16); - - if ((timer & 0x07) == 0) - { - sub_80A1434(timer >> 3, 0); - sub_80A1470(timer >> 3); - } - if ((timer & 0x07) == 1) - sub_80A1434(timer >> 3, 1); - if ((timer & 0x07) == 2) - sub_80A1434(timer >> 3, 2); - if ((timer & 0x07) == 3) - sub_80A1434(timer >> 3, 3); - if ((timer & 0x07) == 4) - sub_80A1434(timer >> 3, 4); - if ((timer & 0x07) == 5) - sub_80A1434(timer >> 3, 5); - if ((timer & 0x07) == 6) - sub_80A1434(timer >> 3, 6); - if ((timer & 0x07) == 7) - sub_80A1434(timer >> 3, 7); -} - -static void sub_80A10B8(u16 timer) -{ - static void sub_80A1520(u16); - - if ((timer & 7) == 0) - sub_80A1520(timer >> 3); -} - -static void sub_80A10D0(u16 timer) -{ - static void sub_80A1598(u16); - - if ((timer & 15) == 0) - sub_80A1598(timer >> 4); -} - -static void sub_80A10E8(u16 timer) -{ - static void sub_80A1394(u16, u8); - - if ((timer & 0x07) == 0) - sub_80A1394(timer >> 3, 0); - if ((timer & 0x07) == 1) - sub_80A1394(timer >> 3, 1); - if ((timer & 0x07) == 2) - sub_80A1394(timer >> 3, 2); - if ((timer & 0x07) == 3) - sub_80A1394(timer >> 3, 3); - if ((timer & 0x07) == 4) - sub_80A1394(timer >> 3, 4); - if ((timer & 0x07) == 5) - sub_80A1394(timer >> 3, 5); - if ((timer & 0x07) == 6) - sub_80A1394(timer >> 3, 6); - if ((timer & 0x07) == 7) - sub_80A1394(timer >> 3, 7); -} - -static void sub_80A115C(u16 timer) -{ - static void sub_80A12D4(u8); - static void sub_80A1498(u16); - - if ((timer & 0x0F) == 0) - sub_80A12D4(timer >> 4); - if ((timer & 0x0F) == 1) - sub_80A1498(timer >> 4); -} - -static void sub_80A1188(u16 timer) -{ - static void sub_80A14C0(u16, u8); - - if ((timer & 0x07) == 0) - sub_80A14C0(timer >> 3, 0); - if ((timer & 0x07) == 1) - sub_80A14C0(timer >> 3, 1); - if ((timer & 0x07) == 2) - sub_80A14C0(timer >> 3, 2); - if ((timer & 0x07) == 3) - sub_80A14C0(timer >> 3, 3); - if ((timer & 0x07) == 4) - sub_80A14C0(timer >> 3, 4); - if ((timer & 0x07) == 5) - sub_80A14C0(timer >> 3, 5); - if ((timer & 0x07) == 6) - sub_80A14C0(timer >> 3, 6); - if ((timer & 0x07) == 7) - sub_80A14C0(timer >> 3, 7); -} - -static void sub_80A11FC(u16 timer) -{ - static void sub_80A131C(u8); - static void sub_80A136C(u8); - - if ((timer & 0x0F) == 0) - sub_80A131C(timer >> 4); - if ((timer & 0x0F) == 1) - sub_80A136C(timer >> 4); -} - -static void sub_80A122C(u16 timer) -{ - static void sub_80A1798(u16); - - if ((timer & 0x0F) == 0) - sub_80A1798(timer >> 4); -} - -static void sub_80A1244(u16 timer) -{ - static void sub_80A1344(u8); - - if ((timer & 0x0F) == 0) - sub_80A1344(timer >> 4); -} - -static void sub_80A1260(u16 timer) -{ - static void sub_80A14F8(u16); - - if ((timer & 0x0F) == 1) - sub_80A14F8(timer >> 4); -} - -static void sub_80A127C(u16 timer) -{ - static void sub_80A1548(u16); - - if ((timer & 0x07) == 0) - sub_80A1548(timer >> 3); -} - -static void sub_80A1294(u16 timer) -{ - static void sub_80A1570(u16); - - if ((timer & 0x07) == 0) - sub_80A1570(timer >> 3); -} - -static void sub_80A12AC(u16 timer) -{ - u16 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_08513684[idx], (u16 *)(BG_VRAM + 0x3c00), 0x140); -} - -static void sub_80A12D4(u8 timer) -{ - u8 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_08513894[idx], (u16 *)(BG_VRAM + 0x6400), 0x80); - - idx = (timer + 2) % 4; - sub_80A0980(gUnknown_08513894[idx], (u16 *)(BG_VRAM + 0x6480), 0x80); -} - -static void sub_80A131C(u8 timer) -{ - u8 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_085143E4[idx], (u16 *)(BG_VRAM + 0x7a00), 0x3C0); -} - -static void sub_80A1344(u8 timer) -{ - u8 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_085145F4[idx], (u16 *)(BG_VRAM + 0x7e00), 0x80); -} - -static void sub_80A136C(u8 timer) -{ - u8 idx; - - idx = timer % 8; - sub_80A0980(gUnknown_08514E04[idx], (u16 *)(BG_VRAM + 0x7e00), 0x100); -} - -static void sub_80A1394(u16 timer_div, u8 timer_mod) -{ - timer_div -= timer_mod; - if (timer_div < 12) // almost certainly a typo - { - timer_div %= 12; - sub_80A0980(gUnknown_08515384[timer_div], gUnknown_08515344[timer_mod], 0x80); - sub_80A0980(gUnknown_085153B4[timer_div], gUnknown_08515364[timer_mod], 0x80); - } - else - { - timer_div %= 4; - sub_80A0980(gUnknown_085153E4[timer_div], gUnknown_08515344[timer_mod], 0x80); - sub_80A0980(gUnknown_085153F4[timer_div], gUnknown_08515364[timer_mod], 0x80); - } -} - -static void sub_80A1434(u16 timer_div, u8 timer_mod) -{ - timer_div -= timer_mod; - timer_div %= 8; - if (gUnknown_08515824[timer_div]) - sub_80A0980(gUnknown_08515824[timer_div], gUnknown_08515804[timer_mod], 0x80); -} - -static void sub_80A1470(u16 timer) -{ - u16 idx; - - idx = timer % 2; - sub_80A0980(gUnknown_08515964[idx], (u16 *)(BG_VRAM + 0x7800), 0x80); -} - -static void sub_80A1498(u16 timer) -{ - u16 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(BG_VRAM + 0x5400), 0x80); -} - -static void sub_80A14C0(u16 timer_div, u8 timer_mod) -{ - timer_div -= timer_mod; - timer_div %= 8; - - sub_80A0980(gUnknown_085161DC[timer_div], gUnknown_085161BC[timer_mod], 0x80); -} - -static void sub_80A14F8(u16 timer) -{ - u16 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(BG_VRAM + 0x7400), 0x80); -} - -static void sub_80A1520(u16 timer) -{ - u16 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_085164FC[idx], (u16 *)(BG_VRAM + 0x5540), 0xC0); -} - -static void sub_80A1548(u16 timer) -{ - u16 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_0851680C[idx], (u16 *)(BG_VRAM + 0x5b40), 0xC0); -} - -static void sub_80A1570(u16 timer) -{ - u16 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_08516B1C[idx], (u16 *)(BG_VRAM + 0x5b40), 0xC0); -} - -static void sub_80A1598(u16 timer) -{ - u16 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_08516D2C[idx], (u16 *)(BG_VRAM + 0x5c00), 0x80); -} - -static void sub_80A15C0(u16 timer) -{ - static void sub_80A1748(u16); - - if ((timer & 1) == 0) - sub_80A1748(timer >> 1); -} - -static void sub_80A15D8(u16 timer) -{ - static void sub_80A16B0(u16); - - if ((timer & 7) == 0) - sub_80A16B0(timer >> 3); -} - -static void sub_80A15F0(u16 timer) -{ - static void sub_80A1720(u16); - static void sub_80A16F8(u16); - - if ((timer & 0x3f) == 1) - sub_80A1720(timer >> 6); - if ((timer & 0x07) == 1) - sub_80A16F8(timer >> 3); -} -static void sub_80A161C(u16 timer) -{ - static void sub_80A1770(u16); - - if ((timer & 3) == 0) - sub_80A1770(timer >> 2); -} - -static void sub_80A1634(u16 timer) -{ - static void sub_80A17C0(u16); - static void sub_80A17EC(u16); - - if ((timer & 7) == 0) - { - sub_80A17C0(timer >> 3); - sub_80A17EC(timer >> 3); - } -} - -static void sub_80A1658(u16 timer) -{ - static void sub_80A1818(u16); - - if ((timer & 3) == 0) - sub_80A1818(timer >> 2); -} - -static void sub_80A1670(u16 timer) -{ - static void sub_80A1884(u16); - - if ((timer & 3) == 0) - sub_80A1884(timer >> 2); -} - -static void sub_80A1688(u16 timer) -{ - u16 idx; - - idx = timer % 2; - sub_80A0980(gUnknown_08516E3C[idx], (u16 *)(BG_VRAM + 0x3e00), 0x80); -} - -static void sub_80A16B0(u16 timer) -{ - u16 idx; - - idx = timer % 3; - sub_80A0980(gUnknown_08517A44[idx], (u16 *)(BG_VRAM + 0x7e00), 0x180); - sub_80A0980(gUnknown_08517A50[idx], (u16 *)(BG_VRAM + 0x7a00), 0x280); -} - -static void sub_80A16F8(u16 timer) -{ - u16 idx; - - idx = timer % 4; - sub_80A0980(gUnknown_08517BFC[idx], (u16 *)(BG_VRAM + 0x7f00), 0x20); -} - -static void sub_80A1720(u16 timer) -{ - u16 idx; - - idx = timer % 2; - sub_80A0980(gUnknown_08517C0C[idx], (u16 *)(BG_VRAM + 0x7c00), 0x80); -} - -static void sub_80A1748(u16 timer) -{ - u16 idx; - - idx = timer % 2; - sub_80A0980(gUnknown_08518034[idx], (u16 *)(BG_VRAM + 0x5200), 0x200); -} - -static void sub_80A1770(u16 timer) -{ - u16 idx; - - idx = timer % 2; - sub_80A0980(gUnknown_0851829C[idx], (u16 *)(BG_VRAM + 0x7e00), 0x120); -} - -static void sub_80A1798(u16 timer) -{ - u16 idx; - - idx = timer % 8; - sub_80A0980(gUnknown_085202C4[idx], (u16 *)(BG_VRAM + 0x5e00), 0xc00); -} - -static void sub_80A17C0(u16 timer) -{ - u16 idx; - - idx = timer % 3; - sub_80A0980(gUnknown_08524864[idx], (u16 *)(BG_VRAM + 0x52e0), 0x100); -} - -static void sub_80A17EC(u16 timer) -{ - u16 idx; - - idx = timer % 3; - sub_80A0980(gUnknown_08524870[idx], (u16 *)(BG_VRAM + 0x50e0), 0x100); -} - -// palette - -static void sub_80A1818(u16 a1) -{ - CpuCopy16(gUnknown_0852487C[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); - BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); - if ((u8)FindTaskIdByFunc(sub_8149DFC) != 0xFF ) - { - sSecondaryTilesetCB = sub_80A1670; - sSecondaryTilesetCBBufferSize = 0x20; - } -} - -static void sub_80A1884(u16 a1) -{ - CpuCopy16(gUnknown_0852487C[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); - if ((u8)FindTaskIdByFunc(sub_8149DFC) == 0xFF ) - { - BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); - if (!--sSecondaryTilesetCBBufferSize) - sSecondaryTilesetCB = NULL; - } -} - void LoadCompressedPalette(const void *src, u16 offset, u16 size) { LZDecompressWram(src, gPaletteDecompressionBuffer); diff --git a/src/tileset_anims.c b/src/tileset_anims.c new file mode 100644 index 000000000..5eb470a07 --- /dev/null +++ b/src/tileset_anims.c @@ -0,0 +1,865 @@ + +// Includes +#include "global.h" +#include "palette.h" +#include "blend_palette.h" +#include "battle.h" +#include "task.h" + +// Static type declarations + +// Static RAM declarations + +static EWRAM_DATA struct { + const u16 *src; + u16 *dest; + u16 size; +} sTilesetDMA3TransferBuffer[20] = {0}; + +static u8 sTilesetDMA3TransferBufferSize; +static u16 sPrimaryTilesetCBCounter; +static u16 sPrimaryTilesetCBBufferSize; +static u16 sSecondaryTilesetCBCounter; +static u16 sSecondaryTilesetCBBufferSize; +static void (*sPrimaryTilesetCB)(u16); +static void (*sSecondaryTilesetCB)(u16); + +// Static ROM declarations + +static void cur_mapheader_run_tileset1_func(void); +static void cur_mapheader_run_tileset2_func(void); + +// .rodata + +extern const u16 *const gUnknown_08510764[]; +extern const u16 *const gUnknown_08512574[]; +extern const u16 *const gUnknown_08512E54[]; +extern const u16 *const gUnknown_08513174[]; +extern const u16 *const gUnknown_08513684[]; +extern const u16 *const gUnknown_08513894[]; +extern const u16 *const gUnknown_085143E4[]; +extern const u16 *const gUnknown_085145F4[]; +extern const u16 *const gUnknown_08514E04[]; +extern u16 *const gUnknown_08515344[]; +extern u16 *const gUnknown_08515364[]; +extern const u16 *const gUnknown_08515384[]; +extern const u16 *const gUnknown_085153B4[]; +extern const u16 *const gUnknown_085153E4[]; +extern const u16 *const gUnknown_085153F4[]; +extern u16 *const gUnknown_08515804[]; +extern const u16 *const gUnknown_08515824[]; +extern const u16 *const gUnknown_08515964[]; +extern const u16 *const gUnknown_08515D8C[]; +extern u16 *const gUnknown_085161BC[]; +extern const u16 *const gUnknown_085161DC[]; +extern const u16 *const gUnknown_085164FC[]; +extern const u16 *const gUnknown_0851680C[]; +extern const u16 *const gUnknown_08516B1C[]; +extern const u16 *const gUnknown_08516D2C[]; +extern const u16 *const gUnknown_08516E3C[]; +extern const u16 *const gUnknown_08517A44[]; +extern const u16 *const gUnknown_08517A50[]; +extern const u16 *const gUnknown_08517BFC[]; +extern const u16 *const gUnknown_08517C0C[]; +extern const u16 *const gUnknown_08518034[]; +extern const u16 *const gUnknown_0851829C[]; +extern const u16 *const gUnknown_085202C4[]; +extern const u16 *const gUnknown_08524864[]; +extern const u16 *const gUnknown_08524870[]; + +extern const u16 gUnknown_08D85640[]; +extern const u16 gUnknown_08D85660[]; +extern const u16 gUnknown_08D85680[]; +extern const u16 gUnknown_08D856A0[]; + +static const u16 *const gUnknown_0852487C[] = { + gUnknown_08D85640, + gUnknown_08D85660, + gUnknown_08D85680, + gUnknown_08D856A0, +}; + +// .text + +static void sub_80A0954(void) +{ + sTilesetDMA3TransferBufferSize = 0; + CpuFill32(0, sTilesetDMA3TransferBuffer, sizeof sTilesetDMA3TransferBuffer); +} + +static void sub_80A0980(const u16 *a0, u16 *a1, u16 a2) +{ + if (sTilesetDMA3TransferBufferSize < 20) + { + sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].src = a0; + sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].dest = a1; + sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].size = a2; + sTilesetDMA3TransferBufferSize ++; + } +} + +void sub_80A09D0(void) +{ + int i; + + for (i = 0; i < sTilesetDMA3TransferBufferSize; i ++) + { + DmaCopy16(3, sTilesetDMA3TransferBuffer[i].src, sTilesetDMA3TransferBuffer[i].dest, sTilesetDMA3TransferBuffer[i].size); + } + sTilesetDMA3TransferBufferSize = 0; +} + +void cur_mapheader_run_tileset_funcs_after_some_cpuset(void) +{ + sub_80A0954(); + cur_mapheader_run_tileset1_func(); + cur_mapheader_run_tileset2_func(); +} + +void sub_80A0A2C(void) +{ + cur_mapheader_run_tileset2_func(); +} + +void sub_80A0A38(void) +{ + sub_80A0954(); + if (++sPrimaryTilesetCBCounter >= sPrimaryTilesetCBBufferSize) + sPrimaryTilesetCBCounter = 0; + if (++sSecondaryTilesetCBCounter >= sSecondaryTilesetCBBufferSize) + sSecondaryTilesetCBCounter = 0; + if (sPrimaryTilesetCB) + sPrimaryTilesetCB(sPrimaryTilesetCBCounter); + if (sSecondaryTilesetCB) + sSecondaryTilesetCB(sSecondaryTilesetCBCounter); +} + +static void cur_mapheader_run_tileset1_func(void) +{ + sPrimaryTilesetCBCounter = 0; + sPrimaryTilesetCBBufferSize = 0; + sPrimaryTilesetCB = NULL; + if (gMapHeader.mapData->primaryTileset && gMapHeader.mapData->primaryTileset->callback) + gMapHeader.mapData->primaryTileset->callback(); +} + +static void cur_mapheader_run_tileset2_func(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = 0; + sSecondaryTilesetCB = NULL; + if (gMapHeader.mapData->secondaryTileset && gMapHeader.mapData->secondaryTileset->callback) + gMapHeader.mapData->secondaryTileset->callback(); +} + +void TilesetCb_General(void) +{ + static void sub_80A0B70(u16); + + sPrimaryTilesetCBCounter = 0; + sPrimaryTilesetCBBufferSize = 0x100; + sPrimaryTilesetCB = sub_80A0B70; +} + +void TilesetCb_InsideBuilding(void) +{ + static void sub_80A0BB4(u16); + + sPrimaryTilesetCBCounter = 0; + sPrimaryTilesetCBBufferSize = 0x100; + sPrimaryTilesetCB = sub_80A0BB4; +} + +static void sub_80A0B70(u16 timer) +{ + static void sub_80A0BCC(u16); + static void sub_80A0BF4(u16); + static void sub_80A0C1C(u16); + static void sub_80A0C44(u16); + static void sub_80A12AC(u16); + + if ((timer & 0x0F) == 0) + sub_80A0BCC(timer >> 4); + if ((timer & 0x0F) == 1) + sub_80A0BF4(timer >> 4); + if ((timer & 0x0F) == 2) + sub_80A0C1C(timer >> 4); + if ((timer & 0x0F) == 3) + sub_80A0C44(timer >> 4); + if ((timer & 0x0F) == 4) + sub_80A12AC(timer >> 4); +} + +static void sub_80A0BB4(u16 timer) +{ + static void sub_80A1688(u16); + + if ((timer & 0x7) == 0) + sub_80A1688(timer >> 3); +} + +static void sub_80A0BCC(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08510764[idx], (u16 *)(BG_VRAM + 0x3F80), 0x80); +} + +static void sub_80A0BF4(u16 timer) +{ + u8 idx; + + idx = timer % 8; + sub_80A0980(gUnknown_08512574[idx], (u16 *)(BG_VRAM + 0x3600), 0x3C0); +} + +static void sub_80A0C1C(u16 timer) +{ + u16 idx; + + idx = timer % 8; + sub_80A0980(gUnknown_08512E54[idx], (u16 *)(BG_VRAM + 0x3a00), 0x140); +} + +static void sub_80A0C44(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08513174[idx], (u16 *)(BG_VRAM + 0x3e00), 0xc0); +} + +void TilesetCb_Petalburg(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = NULL; +} + +void TilesetCb_Rustboro(void) +{ + static void sub_80A103C(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A103C; +} + +void TilesetCb_Dewford(void) +{ + static void sub_80A10B8(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A10B8; +} + +void TilesetCb_Slateport(void) +{ + static void sub_80A10D0(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A10D0; +} + +void TilesetCb_Mauville(void) +{ + static void sub_80A10E8(u16); + + sSecondaryTilesetCBCounter = sPrimaryTilesetCBCounter; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A10E8; +} + +void TilesetCb_Lavaridge(void) +{ + static void sub_80A115C(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A115C; +} + +void TilesetCb_Fallarbor(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = NULL; +} + +void TilesetCb_Fortree(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = NULL; +} + +void TilesetCb_Lilycove(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = NULL; +} + +void TilesetCb_Mossdeep(void) +{ + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = NULL; +} + +void TilesetCb_EverGrande(void) +{ + static void sub_80A1188(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A1188; +} + +void TilesetCb_Pacifidlog(void) +{ + static void sub_80A11FC(u16); + + sSecondaryTilesetCBCounter = sPrimaryTilesetCBCounter; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A11FC; +} + +void TilesetCb_Sootopolis(void) +{ + static void sub_80A122C(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A122C; +} + +void TilesetCb_BattleFrontierOutsideWest(void) +{ + static void sub_80A127C(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A127C; +} + +void TilesetCb_BattleFrontierOutsideEast(void) +{ + static void sub_80A1294(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A1294; +} + +void TilesetCb_Underwater(void) +{ + static void sub_80A1244(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = 128; + sSecondaryTilesetCB = sub_80A1244; +} + +void TilesetCb_SootopolisGym(void) +{ + static void sub_80A15D8(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = 240; + sSecondaryTilesetCB = sub_80A15D8; +} + +void TilesetCb_Cave(void) +{ + static void sub_80A1260(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A1260; +} + +void TilesetCb_EliteFour(void) +{ + static void sub_80A15F0(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = 128; + sSecondaryTilesetCB = sub_80A15F0; +} + +void TilesetCb_MauvilleGym(void) +{ + static void sub_80A15C0(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A15C0; +} + +void TilesetCb_BikeShop(void) +{ + static void sub_80A161C(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A161C; +} + +void TilesetCb_BattlePyramid(void) +{ + static void sub_80A1634(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A1634; +} + +void TilesetCb_BattleDome(void) +{ + static void sub_80A1658(u16); + + sSecondaryTilesetCBCounter = 0; + sSecondaryTilesetCBBufferSize = sPrimaryTilesetCBBufferSize; + sSecondaryTilesetCB = sub_80A1658; +} + +static void sub_80A103C(u16 timer) +{ + static void sub_80A1434(u16, u8); + static void sub_80A1470(u16); + + if ((timer & 0x07) == 0) + { + sub_80A1434(timer >> 3, 0); + sub_80A1470(timer >> 3); + } + if ((timer & 0x07) == 1) + sub_80A1434(timer >> 3, 1); + if ((timer & 0x07) == 2) + sub_80A1434(timer >> 3, 2); + if ((timer & 0x07) == 3) + sub_80A1434(timer >> 3, 3); + if ((timer & 0x07) == 4) + sub_80A1434(timer >> 3, 4); + if ((timer & 0x07) == 5) + sub_80A1434(timer >> 3, 5); + if ((timer & 0x07) == 6) + sub_80A1434(timer >> 3, 6); + if ((timer & 0x07) == 7) + sub_80A1434(timer >> 3, 7); +} + +static void sub_80A10B8(u16 timer) +{ + static void sub_80A1520(u16); + + if ((timer & 7) == 0) + sub_80A1520(timer >> 3); +} + +static void sub_80A10D0(u16 timer) +{ + static void sub_80A1598(u16); + + if ((timer & 15) == 0) + sub_80A1598(timer >> 4); +} + +static void sub_80A10E8(u16 timer) +{ + static void sub_80A1394(u16, u8); + + if ((timer & 0x07) == 0) + sub_80A1394(timer >> 3, 0); + if ((timer & 0x07) == 1) + sub_80A1394(timer >> 3, 1); + if ((timer & 0x07) == 2) + sub_80A1394(timer >> 3, 2); + if ((timer & 0x07) == 3) + sub_80A1394(timer >> 3, 3); + if ((timer & 0x07) == 4) + sub_80A1394(timer >> 3, 4); + if ((timer & 0x07) == 5) + sub_80A1394(timer >> 3, 5); + if ((timer & 0x07) == 6) + sub_80A1394(timer >> 3, 6); + if ((timer & 0x07) == 7) + sub_80A1394(timer >> 3, 7); +} + +static void sub_80A115C(u16 timer) +{ + static void sub_80A12D4(u8); + static void sub_80A1498(u16); + + if ((timer & 0x0F) == 0) + sub_80A12D4(timer >> 4); + if ((timer & 0x0F) == 1) + sub_80A1498(timer >> 4); +} + +static void sub_80A1188(u16 timer) +{ + static void sub_80A14C0(u16, u8); + + if ((timer & 0x07) == 0) + sub_80A14C0(timer >> 3, 0); + if ((timer & 0x07) == 1) + sub_80A14C0(timer >> 3, 1); + if ((timer & 0x07) == 2) + sub_80A14C0(timer >> 3, 2); + if ((timer & 0x07) == 3) + sub_80A14C0(timer >> 3, 3); + if ((timer & 0x07) == 4) + sub_80A14C0(timer >> 3, 4); + if ((timer & 0x07) == 5) + sub_80A14C0(timer >> 3, 5); + if ((timer & 0x07) == 6) + sub_80A14C0(timer >> 3, 6); + if ((timer & 0x07) == 7) + sub_80A14C0(timer >> 3, 7); +} + +static void sub_80A11FC(u16 timer) +{ + static void sub_80A131C(u8); + static void sub_80A136C(u8); + + if ((timer & 0x0F) == 0) + sub_80A131C(timer >> 4); + if ((timer & 0x0F) == 1) + sub_80A136C(timer >> 4); +} + +static void sub_80A122C(u16 timer) +{ + static void sub_80A1798(u16); + + if ((timer & 0x0F) == 0) + sub_80A1798(timer >> 4); +} + +static void sub_80A1244(u16 timer) +{ + static void sub_80A1344(u8); + + if ((timer & 0x0F) == 0) + sub_80A1344(timer >> 4); +} + +static void sub_80A1260(u16 timer) +{ + static void sub_80A14F8(u16); + + if ((timer & 0x0F) == 1) + sub_80A14F8(timer >> 4); +} + +static void sub_80A127C(u16 timer) +{ + static void sub_80A1548(u16); + + if ((timer & 0x07) == 0) + sub_80A1548(timer >> 3); +} + +static void sub_80A1294(u16 timer) +{ + static void sub_80A1570(u16); + + if ((timer & 0x07) == 0) + sub_80A1570(timer >> 3); +} + +static void sub_80A12AC(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08513684[idx], (u16 *)(BG_VRAM + 0x3c00), 0x140); +} + +static void sub_80A12D4(u8 timer) +{ + u8 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08513894[idx], (u16 *)(BG_VRAM + 0x6400), 0x80); + + idx = (timer + 2) % 4; + sub_80A0980(gUnknown_08513894[idx], (u16 *)(BG_VRAM + 0x6480), 0x80); +} + +static void sub_80A131C(u8 timer) +{ + u8 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_085143E4[idx], (u16 *)(BG_VRAM + 0x7a00), 0x3C0); +} + +static void sub_80A1344(u8 timer) +{ + u8 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_085145F4[idx], (u16 *)(BG_VRAM + 0x7e00), 0x80); +} + +static void sub_80A136C(u8 timer) +{ + u8 idx; + + idx = timer % 8; + sub_80A0980(gUnknown_08514E04[idx], (u16 *)(BG_VRAM + 0x7e00), 0x100); +} + +static void sub_80A1394(u16 timer_div, u8 timer_mod) +{ + timer_div -= timer_mod; + if (timer_div < 12) // almost certainly a typo + { + timer_div %= 12; + sub_80A0980(gUnknown_08515384[timer_div], gUnknown_08515344[timer_mod], 0x80); + sub_80A0980(gUnknown_085153B4[timer_div], gUnknown_08515364[timer_mod], 0x80); + } + else + { + timer_div %= 4; + sub_80A0980(gUnknown_085153E4[timer_div], gUnknown_08515344[timer_mod], 0x80); + sub_80A0980(gUnknown_085153F4[timer_div], gUnknown_08515364[timer_mod], 0x80); + } +} + +static void sub_80A1434(u16 timer_div, u8 timer_mod) +{ + timer_div -= timer_mod; + timer_div %= 8; + if (gUnknown_08515824[timer_div]) + sub_80A0980(gUnknown_08515824[timer_div], gUnknown_08515804[timer_mod], 0x80); +} + +static void sub_80A1470(u16 timer) +{ + u16 idx; + + idx = timer % 2; + sub_80A0980(gUnknown_08515964[idx], (u16 *)(BG_VRAM + 0x7800), 0x80); +} + +static void sub_80A1498(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(BG_VRAM + 0x5400), 0x80); +} + +static void sub_80A14C0(u16 timer_div, u8 timer_mod) +{ + timer_div -= timer_mod; + timer_div %= 8; + + sub_80A0980(gUnknown_085161DC[timer_div], gUnknown_085161BC[timer_mod], 0x80); +} + +static void sub_80A14F8(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(BG_VRAM + 0x7400), 0x80); +} + +static void sub_80A1520(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_085164FC[idx], (u16 *)(BG_VRAM + 0x5540), 0xC0); +} + +static void sub_80A1548(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_0851680C[idx], (u16 *)(BG_VRAM + 0x5b40), 0xC0); +} + +static void sub_80A1570(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08516B1C[idx], (u16 *)(BG_VRAM + 0x5b40), 0xC0); +} + +static void sub_80A1598(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08516D2C[idx], (u16 *)(BG_VRAM + 0x5c00), 0x80); +} + +static void sub_80A15C0(u16 timer) +{ + static void sub_80A1748(u16); + + if ((timer & 1) == 0) + sub_80A1748(timer >> 1); +} + +static void sub_80A15D8(u16 timer) +{ + static void sub_80A16B0(u16); + + if ((timer & 7) == 0) + sub_80A16B0(timer >> 3); +} + +static void sub_80A15F0(u16 timer) +{ + static void sub_80A1720(u16); + static void sub_80A16F8(u16); + + if ((timer & 0x3f) == 1) + sub_80A1720(timer >> 6); + if ((timer & 0x07) == 1) + sub_80A16F8(timer >> 3); +} +static void sub_80A161C(u16 timer) +{ + static void sub_80A1770(u16); + + if ((timer & 3) == 0) + sub_80A1770(timer >> 2); +} + +static void sub_80A1634(u16 timer) +{ + static void sub_80A17C0(u16); + static void sub_80A17EC(u16); + + if ((timer & 7) == 0) + { + sub_80A17C0(timer >> 3); + sub_80A17EC(timer >> 3); + } +} + +static void sub_80A1658(u16 timer) +{ + static void sub_80A1818(u16); + + if ((timer & 3) == 0) + sub_80A1818(timer >> 2); +} + +static void sub_80A1670(u16 timer) +{ + static void sub_80A1884(u16); + + if ((timer & 3) == 0) + sub_80A1884(timer >> 2); +} + +static void sub_80A1688(u16 timer) +{ + u16 idx; + + idx = timer % 2; + sub_80A0980(gUnknown_08516E3C[idx], (u16 *)(BG_VRAM + 0x3e00), 0x80); +} + +static void sub_80A16B0(u16 timer) +{ + u16 idx; + + idx = timer % 3; + sub_80A0980(gUnknown_08517A44[idx], (u16 *)(BG_VRAM + 0x7e00), 0x180); + sub_80A0980(gUnknown_08517A50[idx], (u16 *)(BG_VRAM + 0x7a00), 0x280); +} + +static void sub_80A16F8(u16 timer) +{ + u16 idx; + + idx = timer % 4; + sub_80A0980(gUnknown_08517BFC[idx], (u16 *)(BG_VRAM + 0x7f00), 0x20); +} + +static void sub_80A1720(u16 timer) +{ + u16 idx; + + idx = timer % 2; + sub_80A0980(gUnknown_08517C0C[idx], (u16 *)(BG_VRAM + 0x7c00), 0x80); +} + +static void sub_80A1748(u16 timer) +{ + u16 idx; + + idx = timer % 2; + sub_80A0980(gUnknown_08518034[idx], (u16 *)(BG_VRAM + 0x5200), 0x200); +} + +static void sub_80A1770(u16 timer) +{ + u16 idx; + + idx = timer % 2; + sub_80A0980(gUnknown_0851829C[idx], (u16 *)(BG_VRAM + 0x7e00), 0x120); +} + +static void sub_80A1798(u16 timer) +{ + u16 idx; + + idx = timer % 8; + sub_80A0980(gUnknown_085202C4[idx], (u16 *)(BG_VRAM + 0x5e00), 0xc00); +} + +static void sub_80A17C0(u16 timer) +{ + u16 idx; + + idx = timer % 3; + sub_80A0980(gUnknown_08524864[idx], (u16 *)(BG_VRAM + 0x52e0), 0x100); +} + +static void sub_80A17EC(u16 timer) +{ + u16 idx; + + idx = timer % 3; + sub_80A0980(gUnknown_08524870[idx], (u16 *)(BG_VRAM + 0x50e0), 0x100); +} + +static void sub_80A1818(u16 a1) +{ + CpuCopy16(gUnknown_0852487C[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); + BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); + if ((u8)FindTaskIdByFunc(sub_8149DFC) != 0xFF ) + { + sSecondaryTilesetCB = sub_80A1670; + sSecondaryTilesetCBBufferSize = 0x20; + } +} + +static void sub_80A1884(u16 a1) +{ + CpuCopy16(gUnknown_0852487C[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); + if ((u8)FindTaskIdByFunc(sub_8149DFC) == 0xFF ) + { + BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); + if (!--sSecondaryTilesetCBBufferSize) + sSecondaryTilesetCB = NULL; + } +} -- cgit v1.2.3 From 74951e4312b782b81324999a580bdf25fe4d31ce Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 2 Oct 2017 08:43:52 -0400 Subject: Name pointer tables --- src/tileset_anims.c | 160 ++++++++++++++++++++++++++-------------------------- 1 file changed, 80 insertions(+), 80 deletions(-) (limited to 'src') diff --git a/src/tileset_anims.c b/src/tileset_anims.c index 5eb470a07..b7f18d869 100644 --- a/src/tileset_anims.c +++ b/src/tileset_anims.c @@ -31,48 +31,48 @@ static void cur_mapheader_run_tileset2_func(void); // .rodata -extern const u16 *const gUnknown_08510764[]; -extern const u16 *const gUnknown_08512574[]; -extern const u16 *const gUnknown_08512E54[]; -extern const u16 *const gUnknown_08513174[]; -extern const u16 *const gUnknown_08513684[]; -extern const u16 *const gUnknown_08513894[]; -extern const u16 *const gUnknown_085143E4[]; -extern const u16 *const gUnknown_085145F4[]; -extern const u16 *const gUnknown_08514E04[]; -extern u16 *const gUnknown_08515344[]; -extern u16 *const gUnknown_08515364[]; -extern const u16 *const gUnknown_08515384[]; -extern const u16 *const gUnknown_085153B4[]; -extern const u16 *const gUnknown_085153E4[]; -extern const u16 *const gUnknown_085153F4[]; -extern u16 *const gUnknown_08515804[]; -extern const u16 *const gUnknown_08515824[]; -extern const u16 *const gUnknown_08515964[]; -extern const u16 *const gUnknown_08515D8C[]; -extern u16 *const gUnknown_085161BC[]; -extern const u16 *const gUnknown_085161DC[]; -extern const u16 *const gUnknown_085164FC[]; -extern const u16 *const gUnknown_0851680C[]; -extern const u16 *const gUnknown_08516B1C[]; -extern const u16 *const gUnknown_08516D2C[]; -extern const u16 *const gUnknown_08516E3C[]; -extern const u16 *const gUnknown_08517A44[]; -extern const u16 *const gUnknown_08517A50[]; -extern const u16 *const gUnknown_08517BFC[]; -extern const u16 *const gUnknown_08517C0C[]; -extern const u16 *const gUnknown_08518034[]; -extern const u16 *const gUnknown_0851829C[]; -extern const u16 *const gUnknown_085202C4[]; -extern const u16 *const gUnknown_08524864[]; -extern const u16 *const gUnknown_08524870[]; +extern const u16 *const gTilesetAnims_General0[]; +extern const u16 *const gTilesetAnims_General1[]; +extern const u16 *const gTilesetAnims_General2[]; +extern const u16 *const gTilesetAnims_General3[]; +extern const u16 *const gTilesetAnims_General4[]; +extern const u16 *const gTilesetAnims_Lavaridge0[]; +extern const u16 *const gTilesetAnims_Pacifidlog0[]; +extern const u16 *const gTilesetAnims_Underwater0[]; +extern const u16 *const gTilesetAnims_Pacifidlog1[]; +extern u16 *const gTilesetAnims_MauvilleVDests0[]; +extern u16 *const gTilesetAnims_MauvilleVDests1[]; +extern const u16 *const gTilesetAnims_Mauville0a[]; +extern const u16 *const gTilesetAnims_Mauville0b[]; +extern const u16 *const gTilesetAnims_Mauville1a[]; +extern const u16 *const gTilesetAnims_Mauville1b[]; +extern u16 *const gTilesetAnims_RustboroVDests0[]; +extern const u16 *const gTilesetAnims_Rustboro0[]; +extern const u16 *const gTilesetAnims_Rustboro1[]; +extern const u16 *const gTilesetAnims_Lavaridge1_Cave0[]; +extern u16 *const gTilesetAnims_EverGrandeVDests0[]; +extern const u16 *const gTilesetAnims_EverGrande0[]; +extern const u16 *const gTilesetAnims_Dewford0[]; +extern const u16 *const gTilesetAnims_BattleFrontierOutsideWest0[]; +extern const u16 *const gTilesetAnims_BattleFrontierOutsideEast0[]; +extern const u16 *const gTilesetAnims_Slateport0[]; +extern const u16 *const gTilesetAnims_InsideBuilding0[]; +extern const u16 *const gTilesetAnims_SootopolisGym0[]; +extern const u16 *const gTilesetAnims_SootopolisGym1[]; +extern const u16 *const gTilesetAnims_EliteFour1[]; +extern const u16 *const gTilesetAnims_EliteFour0[]; +extern const u16 *const gTilesetAnims_MauvilleGym0[]; +extern const u16 *const gTilesetAnims_BikeShop0[]; +extern const u16 *const gTilesetAnims_Sootopolis0[]; +extern const u16 *const gTilesetAnims_BattlePyramid0[]; +extern const u16 *const gTilesetAnims_BattlePyramid1[]; extern const u16 gUnknown_08D85640[]; extern const u16 gUnknown_08D85660[]; extern const u16 gUnknown_08D85680[]; extern const u16 gUnknown_08D856A0[]; -static const u16 *const gUnknown_0852487C[] = { +static const u16 *const gTilesetAnims_BattleDomePals0[] = { gUnknown_08D85640, gUnknown_08D85660, gUnknown_08D85680, @@ -81,24 +81,24 @@ static const u16 *const gUnknown_0852487C[] = { // .text -static void sub_80A0954(void) +static void ResetTilesetAnimBuffer(void) { sTilesetDMA3TransferBufferSize = 0; CpuFill32(0, sTilesetDMA3TransferBuffer, sizeof sTilesetDMA3TransferBuffer); } -static void sub_80A0980(const u16 *a0, u16 *a1, u16 a2) +static void AppendTilesetAnimToBuffer(const u16 *src, u16 *dest, u16 size) { if (sTilesetDMA3TransferBufferSize < 20) { - sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].src = a0; - sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].dest = a1; - sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].size = a2; + sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].src = src; + sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].dest = dest; + sTilesetDMA3TransferBuffer[sTilesetDMA3TransferBufferSize].size = size; sTilesetDMA3TransferBufferSize ++; } } -void sub_80A09D0(void) +void TransferTilesetAnimsBuffer(void) { int i; @@ -111,7 +111,7 @@ void sub_80A09D0(void) void cur_mapheader_run_tileset_funcs_after_some_cpuset(void) { - sub_80A0954(); + ResetTilesetAnimBuffer(); cur_mapheader_run_tileset1_func(); cur_mapheader_run_tileset2_func(); } @@ -123,7 +123,7 @@ void sub_80A0A2C(void) void sub_80A0A38(void) { - sub_80A0954(); + ResetTilesetAnimBuffer(); if (++sPrimaryTilesetCBCounter >= sPrimaryTilesetCBBufferSize) sPrimaryTilesetCBCounter = 0; if (++sSecondaryTilesetCBCounter >= sSecondaryTilesetCBBufferSize) @@ -203,7 +203,7 @@ static void sub_80A0BCC(u16 timer) u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08510764[idx], (u16 *)(BG_VRAM + 0x3F80), 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_General0[idx], (u16 *)(BG_VRAM + 0x3F80), 0x80); } static void sub_80A0BF4(u16 timer) @@ -211,7 +211,7 @@ static void sub_80A0BF4(u16 timer) u8 idx; idx = timer % 8; - sub_80A0980(gUnknown_08512574[idx], (u16 *)(BG_VRAM + 0x3600), 0x3C0); + AppendTilesetAnimToBuffer(gTilesetAnims_General1[idx], (u16 *)(BG_VRAM + 0x3600), 0x3C0); } static void sub_80A0C1C(u16 timer) @@ -219,7 +219,7 @@ static void sub_80A0C1C(u16 timer) u16 idx; idx = timer % 8; - sub_80A0980(gUnknown_08512E54[idx], (u16 *)(BG_VRAM + 0x3a00), 0x140); + AppendTilesetAnimToBuffer(gTilesetAnims_General2[idx], (u16 *)(BG_VRAM + 0x3a00), 0x140); } static void sub_80A0C44(u16 timer) @@ -227,7 +227,7 @@ static void sub_80A0C44(u16 timer) u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08513174[idx], (u16 *)(BG_VRAM + 0x3e00), 0xc0); + AppendTilesetAnimToBuffer(gTilesetAnims_General3[idx], (u16 *)(BG_VRAM + 0x3e00), 0xc0); } void TilesetCb_Petalburg(void) @@ -580,7 +580,7 @@ static void sub_80A12AC(u16 timer) u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08513684[idx], (u16 *)(BG_VRAM + 0x3c00), 0x140); + AppendTilesetAnimToBuffer(gTilesetAnims_General4[idx], (u16 *)(BG_VRAM + 0x3c00), 0x140); } static void sub_80A12D4(u8 timer) @@ -588,10 +588,10 @@ static void sub_80A12D4(u8 timer) u8 idx; idx = timer % 4; - sub_80A0980(gUnknown_08513894[idx], (u16 *)(BG_VRAM + 0x6400), 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Lavaridge0[idx], (u16 *)(BG_VRAM + 0x6400), 0x80); idx = (timer + 2) % 4; - sub_80A0980(gUnknown_08513894[idx], (u16 *)(BG_VRAM + 0x6480), 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Lavaridge0[idx], (u16 *)(BG_VRAM + 0x6480), 0x80); } static void sub_80A131C(u8 timer) @@ -599,7 +599,7 @@ static void sub_80A131C(u8 timer) u8 idx; idx = timer % 4; - sub_80A0980(gUnknown_085143E4[idx], (u16 *)(BG_VRAM + 0x7a00), 0x3C0); + AppendTilesetAnimToBuffer(gTilesetAnims_Pacifidlog0[idx], (u16 *)(BG_VRAM + 0x7a00), 0x3C0); } static void sub_80A1344(u8 timer) @@ -607,7 +607,7 @@ static void sub_80A1344(u8 timer) u8 idx; idx = timer % 4; - sub_80A0980(gUnknown_085145F4[idx], (u16 *)(BG_VRAM + 0x7e00), 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Underwater0[idx], (u16 *)(BG_VRAM + 0x7e00), 0x80); } static void sub_80A136C(u8 timer) @@ -615,7 +615,7 @@ static void sub_80A136C(u8 timer) u8 idx; idx = timer % 8; - sub_80A0980(gUnknown_08514E04[idx], (u16 *)(BG_VRAM + 0x7e00), 0x100); + AppendTilesetAnimToBuffer(gTilesetAnims_Pacifidlog1[idx], (u16 *)(BG_VRAM + 0x7e00), 0x100); } static void sub_80A1394(u16 timer_div, u8 timer_mod) @@ -624,14 +624,14 @@ static void sub_80A1394(u16 timer_div, u8 timer_mod) if (timer_div < 12) // almost certainly a typo { timer_div %= 12; - sub_80A0980(gUnknown_08515384[timer_div], gUnknown_08515344[timer_mod], 0x80); - sub_80A0980(gUnknown_085153B4[timer_div], gUnknown_08515364[timer_mod], 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Mauville0a[timer_div], gTilesetAnims_MauvilleVDests0[timer_mod], 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Mauville0b[timer_div], gTilesetAnims_MauvilleVDests1[timer_mod], 0x80); } else { timer_div %= 4; - sub_80A0980(gUnknown_085153E4[timer_div], gUnknown_08515344[timer_mod], 0x80); - sub_80A0980(gUnknown_085153F4[timer_div], gUnknown_08515364[timer_mod], 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Mauville1a[timer_div], gTilesetAnims_MauvilleVDests0[timer_mod], 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Mauville1b[timer_div], gTilesetAnims_MauvilleVDests1[timer_mod], 0x80); } } @@ -639,8 +639,8 @@ static void sub_80A1434(u16 timer_div, u8 timer_mod) { timer_div -= timer_mod; timer_div %= 8; - if (gUnknown_08515824[timer_div]) - sub_80A0980(gUnknown_08515824[timer_div], gUnknown_08515804[timer_mod], 0x80); + if (gTilesetAnims_Rustboro0[timer_div]) + AppendTilesetAnimToBuffer(gTilesetAnims_Rustboro0[timer_div], gTilesetAnims_RustboroVDests0[timer_mod], 0x80); } static void sub_80A1470(u16 timer) @@ -648,7 +648,7 @@ static void sub_80A1470(u16 timer) u16 idx; idx = timer % 2; - sub_80A0980(gUnknown_08515964[idx], (u16 *)(BG_VRAM + 0x7800), 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Rustboro1[idx], (u16 *)(BG_VRAM + 0x7800), 0x80); } static void sub_80A1498(u16 timer) @@ -656,7 +656,7 @@ static void sub_80A1498(u16 timer) u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(BG_VRAM + 0x5400), 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Lavaridge1_Cave0[idx], (u16 *)(BG_VRAM + 0x5400), 0x80); } static void sub_80A14C0(u16 timer_div, u8 timer_mod) @@ -664,7 +664,7 @@ static void sub_80A14C0(u16 timer_div, u8 timer_mod) timer_div -= timer_mod; timer_div %= 8; - sub_80A0980(gUnknown_085161DC[timer_div], gUnknown_085161BC[timer_mod], 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_EverGrande0[timer_div], gTilesetAnims_EverGrandeVDests0[timer_mod], 0x80); } static void sub_80A14F8(u16 timer) @@ -672,7 +672,7 @@ static void sub_80A14F8(u16 timer) u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08515D8C[idx], (u16 *)(BG_VRAM + 0x7400), 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Lavaridge1_Cave0[idx], (u16 *)(BG_VRAM + 0x7400), 0x80); } static void sub_80A1520(u16 timer) @@ -680,7 +680,7 @@ static void sub_80A1520(u16 timer) u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_085164FC[idx], (u16 *)(BG_VRAM + 0x5540), 0xC0); + AppendTilesetAnimToBuffer(gTilesetAnims_Dewford0[idx], (u16 *)(BG_VRAM + 0x5540), 0xC0); } static void sub_80A1548(u16 timer) @@ -688,7 +688,7 @@ static void sub_80A1548(u16 timer) u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_0851680C[idx], (u16 *)(BG_VRAM + 0x5b40), 0xC0); + AppendTilesetAnimToBuffer(gTilesetAnims_BattleFrontierOutsideWest0[idx], (u16 *)(BG_VRAM + 0x5b40), 0xC0); } static void sub_80A1570(u16 timer) @@ -696,7 +696,7 @@ static void sub_80A1570(u16 timer) u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08516B1C[idx], (u16 *)(BG_VRAM + 0x5b40), 0xC0); + AppendTilesetAnimToBuffer(gTilesetAnims_BattleFrontierOutsideEast0[idx], (u16 *)(BG_VRAM + 0x5b40), 0xC0); } static void sub_80A1598(u16 timer) @@ -704,7 +704,7 @@ static void sub_80A1598(u16 timer) u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08516D2C[idx], (u16 *)(BG_VRAM + 0x5c00), 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_Slateport0[idx], (u16 *)(BG_VRAM + 0x5c00), 0x80); } static void sub_80A15C0(u16 timer) @@ -774,7 +774,7 @@ static void sub_80A1688(u16 timer) u16 idx; idx = timer % 2; - sub_80A0980(gUnknown_08516E3C[idx], (u16 *)(BG_VRAM + 0x3e00), 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_InsideBuilding0[idx], (u16 *)(BG_VRAM + 0x3e00), 0x80); } static void sub_80A16B0(u16 timer) @@ -782,8 +782,8 @@ static void sub_80A16B0(u16 timer) u16 idx; idx = timer % 3; - sub_80A0980(gUnknown_08517A44[idx], (u16 *)(BG_VRAM + 0x7e00), 0x180); - sub_80A0980(gUnknown_08517A50[idx], (u16 *)(BG_VRAM + 0x7a00), 0x280); + AppendTilesetAnimToBuffer(gTilesetAnims_SootopolisGym0[idx], (u16 *)(BG_VRAM + 0x7e00), 0x180); + AppendTilesetAnimToBuffer(gTilesetAnims_SootopolisGym1[idx], (u16 *)(BG_VRAM + 0x7a00), 0x280); } static void sub_80A16F8(u16 timer) @@ -791,7 +791,7 @@ static void sub_80A16F8(u16 timer) u16 idx; idx = timer % 4; - sub_80A0980(gUnknown_08517BFC[idx], (u16 *)(BG_VRAM + 0x7f00), 0x20); + AppendTilesetAnimToBuffer(gTilesetAnims_EliteFour1[idx], (u16 *)(BG_VRAM + 0x7f00), 0x20); } static void sub_80A1720(u16 timer) @@ -799,7 +799,7 @@ static void sub_80A1720(u16 timer) u16 idx; idx = timer % 2; - sub_80A0980(gUnknown_08517C0C[idx], (u16 *)(BG_VRAM + 0x7c00), 0x80); + AppendTilesetAnimToBuffer(gTilesetAnims_EliteFour0[idx], (u16 *)(BG_VRAM + 0x7c00), 0x80); } static void sub_80A1748(u16 timer) @@ -807,7 +807,7 @@ static void sub_80A1748(u16 timer) u16 idx; idx = timer % 2; - sub_80A0980(gUnknown_08518034[idx], (u16 *)(BG_VRAM + 0x5200), 0x200); + AppendTilesetAnimToBuffer(gTilesetAnims_MauvilleGym0[idx], (u16 *)(BG_VRAM + 0x5200), 0x200); } static void sub_80A1770(u16 timer) @@ -815,7 +815,7 @@ static void sub_80A1770(u16 timer) u16 idx; idx = timer % 2; - sub_80A0980(gUnknown_0851829C[idx], (u16 *)(BG_VRAM + 0x7e00), 0x120); + AppendTilesetAnimToBuffer(gTilesetAnims_BikeShop0[idx], (u16 *)(BG_VRAM + 0x7e00), 0x120); } static void sub_80A1798(u16 timer) @@ -823,7 +823,7 @@ static void sub_80A1798(u16 timer) u16 idx; idx = timer % 8; - sub_80A0980(gUnknown_085202C4[idx], (u16 *)(BG_VRAM + 0x5e00), 0xc00); + AppendTilesetAnimToBuffer(gTilesetAnims_Sootopolis0[idx], (u16 *)(BG_VRAM + 0x5e00), 0xc00); } static void sub_80A17C0(u16 timer) @@ -831,7 +831,7 @@ static void sub_80A17C0(u16 timer) u16 idx; idx = timer % 3; - sub_80A0980(gUnknown_08524864[idx], (u16 *)(BG_VRAM + 0x52e0), 0x100); + AppendTilesetAnimToBuffer(gTilesetAnims_BattlePyramid0[idx], (u16 *)(BG_VRAM + 0x52e0), 0x100); } static void sub_80A17EC(u16 timer) @@ -839,12 +839,12 @@ static void sub_80A17EC(u16 timer) u16 idx; idx = timer % 3; - sub_80A0980(gUnknown_08524870[idx], (u16 *)(BG_VRAM + 0x50e0), 0x100); + AppendTilesetAnimToBuffer(gTilesetAnims_BattlePyramid1[idx], (u16 *)(BG_VRAM + 0x50e0), 0x100); } static void sub_80A1818(u16 a1) { - CpuCopy16(gUnknown_0852487C[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); + CpuCopy16(gTilesetAnims_BattleDomePals0[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); if ((u8)FindTaskIdByFunc(sub_8149DFC) != 0xFF ) { @@ -855,7 +855,7 @@ static void sub_80A1818(u16 a1) static void sub_80A1884(u16 a1) { - CpuCopy16(gUnknown_0852487C[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); + CpuCopy16(gTilesetAnims_BattleDomePals0[a1 & 0x3], gPlttBufferUnfaded + 0x80, 32); if ((u8)FindTaskIdByFunc(sub_8149DFC) == 0xFF ) { BlendPalette(0x80, 0x10, gPaletteFade.y, gPaletteFade.blendColor & 0x7FFF); -- cgit v1.2.3 From df0b715207ad6d025995dd5612190d8d51fc049f Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 2 Oct 2017 21:08:54 -0400 Subject: Decompile data/tileset.s --- src/tileset_anims.c | 616 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 581 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/tileset_anims.c b/src/tileset_anims.c index b7f18d869..e53461e02 100644 --- a/src/tileset_anims.c +++ b/src/tileset_anims.c @@ -31,41 +31,587 @@ static void cur_mapheader_run_tileset2_func(void); // .rodata -extern const u16 *const gTilesetAnims_General0[]; -extern const u16 *const gTilesetAnims_General1[]; -extern const u16 *const gTilesetAnims_General2[]; -extern const u16 *const gTilesetAnims_General3[]; -extern const u16 *const gTilesetAnims_General4[]; -extern const u16 *const gTilesetAnims_Lavaridge0[]; -extern const u16 *const gTilesetAnims_Pacifidlog0[]; -extern const u16 *const gTilesetAnims_Underwater0[]; -extern const u16 *const gTilesetAnims_Pacifidlog1[]; -extern u16 *const gTilesetAnims_MauvilleVDests0[]; -extern u16 *const gTilesetAnims_MauvilleVDests1[]; -extern const u16 *const gTilesetAnims_Mauville0a[]; -extern const u16 *const gTilesetAnims_Mauville0b[]; -extern const u16 *const gTilesetAnims_Mauville1a[]; -extern const u16 *const gTilesetAnims_Mauville1b[]; -extern u16 *const gTilesetAnims_RustboroVDests0[]; -extern const u16 *const gTilesetAnims_Rustboro0[]; -extern const u16 *const gTilesetAnims_Rustboro1[]; -extern const u16 *const gTilesetAnims_Lavaridge1_Cave0[]; -extern u16 *const gTilesetAnims_EverGrandeVDests0[]; -extern const u16 *const gTilesetAnims_EverGrande0[]; -extern const u16 *const gTilesetAnims_Dewford0[]; -extern const u16 *const gTilesetAnims_BattleFrontierOutsideWest0[]; -extern const u16 *const gTilesetAnims_BattleFrontierOutsideEast0[]; -extern const u16 *const gTilesetAnims_Slateport0[]; -extern const u16 *const gTilesetAnims_InsideBuilding0[]; -extern const u16 *const gTilesetAnims_SootopolisGym0[]; -extern const u16 *const gTilesetAnims_SootopolisGym1[]; -extern const u16 *const gTilesetAnims_EliteFour1[]; -extern const u16 *const gTilesetAnims_EliteFour0[]; -extern const u16 *const gTilesetAnims_MauvilleGym0[]; -extern const u16 *const gTilesetAnims_BikeShop0[]; -extern const u16 *const gTilesetAnims_Sootopolis0[]; -extern const u16 *const gTilesetAnims_BattlePyramid0[]; -extern const u16 *const gTilesetAnims_BattlePyramid1[]; + +const u16 gUnknown_085105C4[] = INCBIN_U16("data/tilesets/primary/general/anim/0/1.4bpp"); + +const u16 gUnknown_08510644[] = INCBIN_U16("data/tilesets/primary/general/anim/0/0.4bpp"); + +const u16 gUnknown_085106C4[] = INCBIN_U16("data/tilesets/primary/general/anim/0/2.4bpp"); + +const u16 tileset_anims_space_0[16] = {}; + +const u16 *const gTilesetAnims_General0[] = { + gUnknown_08510644, + gUnknown_085105C4, + gUnknown_08510644, + gUnknown_085106C4 +}; + +const u16 gUnknown_08510774[] = INCBIN_U16("data/tilesets/primary/general/anim/1/0.4bpp"); + +const u16 gUnknown_08510B34[] = INCBIN_U16("data/tilesets/primary/general/anim/1/1.4bpp"); + +const u16 gUnknown_08510EF4[] = INCBIN_U16("data/tilesets/primary/general/anim/1/2.4bpp"); + +const u16 gUnknown_085112B4[] = INCBIN_U16("data/tilesets/primary/general/anim/1/3.4bpp"); + +const u16 gUnknown_08511674[] = INCBIN_U16("data/tilesets/primary/general/anim/1/4.4bpp"); + +const u16 gUnknown_08511A34[] = INCBIN_U16("data/tilesets/primary/general/anim/1/5.4bpp"); + +const u16 gUnknown_08511DF4[] = INCBIN_U16("data/tilesets/primary/general/anim/1/6.4bpp"); + +const u16 gUnknown_085121B4[] = INCBIN_U16("data/tilesets/primary/general/anim/1/7.4bpp"); + +const u16 *const gTilesetAnims_General1[] = { + gUnknown_08510774, + gUnknown_08510B34, + gUnknown_08510EF4, + gUnknown_085112B4, + gUnknown_08511674, + gUnknown_08511A34, + gUnknown_08511DF4, + gUnknown_085121B4 +}; + +const u16 gUnknown_08512594[] = INCBIN_U16("data/tilesets/primary/general/anim/2/0.4bpp"); + +const u16 gUnknown_085126D4[] = INCBIN_U16("data/tilesets/primary/general/anim/2/1.4bpp"); + +const u16 gUnknown_08512814[] = INCBIN_U16("data/tilesets/primary/general/anim/2/2.4bpp"); + +const u16 gUnknown_08512954[] = INCBIN_U16("data/tilesets/primary/general/anim/2/3.4bpp"); + +const u16 gUnknown_08512A94[] = INCBIN_U16("data/tilesets/primary/general/anim/2/4.4bpp"); + +const u16 gUnknown_08512BD4[] = INCBIN_U16("data/tilesets/primary/general/anim/2/5.4bpp"); + +const u16 gUnknown_08512D14[] = INCBIN_U16("data/tilesets/primary/general/anim/2/6.4bpp"); + +const u16 *const gTilesetAnims_General2[] = { + gUnknown_08512594, + gUnknown_085126D4, + gUnknown_08512814, + gUnknown_08512954, + gUnknown_08512A94, + gUnknown_08512BD4, + gUnknown_08512D14, + gUnknown_08512594 +}; + +const u16 gUnknown_08512E74[] = INCBIN_U16("data/tilesets/primary/general/anim/3/0.4bpp"); + +const u16 gUnknown_08512F34[] = INCBIN_U16("data/tilesets/primary/general/anim/3/1.4bpp"); + +const u16 gUnknown_08512FF4[] = INCBIN_U16("data/tilesets/primary/general/anim/3/2.4bpp"); + +const u16 gUnknown_085130B4[] = INCBIN_U16("data/tilesets/primary/general/anim/3/3.4bpp"); + +const u16 *const gTilesetAnims_General3[] = { + gUnknown_08512E74, + gUnknown_08512F34, + gUnknown_08512FF4, + gUnknown_085130B4 +}; + +const u16 gUnknown_08513184[] = INCBIN_U16("data/tilesets/primary/general/anim/4/0.4bpp"); + +const u16 gUnknown_085132C4[] = INCBIN_U16("data/tilesets/primary/general/anim/4/1.4bpp"); + +const u16 gUnknown_08513404[] = INCBIN_U16("data/tilesets/primary/general/anim/4/2.4bpp"); + +const u16 gUnknown_08513544[] = INCBIN_U16("data/tilesets/primary/general/anim/4/3.4bpp"); + +const u16 *const gTilesetAnims_General4[] = { + gUnknown_08513184, + gUnknown_085132C4, + gUnknown_08513404, + gUnknown_08513544 +}; + +const u16 gUnknown_08513694[] = INCBIN_U16("data/tilesets/secondary/lavaridge/anim/0.4bpp"); + +const u16 gUnknown_08513714[] = INCBIN_U16("data/tilesets/secondary/lavaridge/anim/1.4bpp"); + +const u16 gUnknown_08513794[] = INCBIN_U16("data/tilesets/secondary/lavaridge/anim/2.4bpp"); + +const u16 gUnknown_08513814[] = INCBIN_U16("data/tilesets/secondary/lavaridge/anim/3.4bpp"); + +const u16 *const gTilesetAnims_Lavaridge0[] = { + gUnknown_08513694, + gUnknown_08513714, + gUnknown_08513794, + gUnknown_08513814 +}; + +const u16 gUnknown_085138A4[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/0/0.4bpp"); + +const u16 gUnknown_08513C64[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/0/1.4bpp"); + +const u16 gUnknown_08514024[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/0/2.4bpp"); + +const u16 *const gTilesetAnims_Pacifidlog0[] = { + gUnknown_085138A4, + gUnknown_08513C64, + gUnknown_08514024, + gUnknown_08513C64 +}; + +const u16 gUnknown_085143F4[] = INCBIN_U16("data/tilesets/secondary/underwater/anim/0.4bpp"); + +const u16 gUnknown_08514474[] = INCBIN_U16("data/tilesets/secondary/underwater/anim/1.4bpp"); + +const u16 gUnknown_085144F4[] = INCBIN_U16("data/tilesets/secondary/underwater/anim/2.4bpp"); + +const u16 gUnknown_08514574[] = INCBIN_U16("data/tilesets/secondary/underwater/anim/3.4bpp"); + +const u16 *const gTilesetAnims_Underwater0[] = { + gUnknown_085143F4, + gUnknown_08514474, + gUnknown_085144F4, + gUnknown_08514574 +}; + +const u16 gUnknown_08514604[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/1/0.4bpp"); + +const u16 gUnknown_08514704[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/1/1.4bpp"); + +const u16 gUnknown_08514804[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/1/2.4bpp"); + +const u16 gUnknown_08514904[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/1/3.4bpp"); + +const u16 gUnknown_08514A04[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/1/4.4bpp"); + +const u16 gUnknown_08514B04[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/1/5.4bpp"); + +const u16 gUnknown_08514C04[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/1/6.4bpp"); + +const u16 gUnknown_08514D04[] = INCBIN_U16("data/tilesets/secondary/pacifidlog/anim/1/7.4bpp"); + +const u16 *const gTilesetAnims_Pacifidlog1[] = { + gUnknown_08514604, + gUnknown_08514704, + gUnknown_08514804, + gUnknown_08514904, + gUnknown_08514A04, + gUnknown_08514B04, + gUnknown_08514C04, + gUnknown_08514D04 +}; + +const u16 gUnknown_08514E24[] = INCBIN_U16("data/tilesets/secondary/mauville/anim/0/a/0.4bpp"); + +const u16 gUnknown_08514EA4[] = INCBIN_U16("data/tilesets/secondary/mauville/anim/0/a/1.4bpp"); + +const u16 gUnknown_08514F24[] = INCBIN_U16("data/tilesets/secondary/mauville/anim/0/a/2.4bpp"); + +const u16 gUnknown_08514FA4[] = INCBIN_U16("data/tilesets/secondary/mauville/anim/0/a/3.4bpp"); + +const u16 gUnknown_08515024[] = INCBIN_U16("data/tilesets/secondary/mauville/anim/1/a/1.4bpp"); + +const u16 gUnknown_085150A4[] = INCBIN_U16("data/tilesets/secondary/mauville/anim/0/b/0.4bpp"); + +const u16 gUnknown_08515124[] = INCBIN_U16("data/tilesets/secondary/mauville/anim/0/b/1.4bpp"); + +const u16 gUnknown_085151A4[] = INCBIN_U16("data/tilesets/secondary/mauville/anim/0/b/2.4bpp"); + +const u16 gUnknown_08515224[] = INCBIN_U16("data/tilesets/secondary/mauville/anim/0/b/3.4bpp"); + +const u16 gUnknown_085152A4[] = INCBIN_U16("data/tilesets/secondary/mauville/anim/1/b/1.4bpp"); + +const u16 tileset_anims_space_1[16] = {}; + +u16 *const gTilesetAnims_MauvilleVDests0[] = { + (u16 *)(BG_VRAM + 0x4c00), + (u16 *)(BG_VRAM + 0x4c80), + (u16 *)(BG_VRAM + 0x4d00), + (u16 *)(BG_VRAM + 0x4d80), + (u16 *)(BG_VRAM + 0x4e00), + (u16 *)(BG_VRAM + 0x4e80), + (u16 *)(BG_VRAM + 0x4f00), + (u16 *)(BG_VRAM + 0x4f80) +}; + +u16 *const gTilesetAnims_MauvilleVDests1[] = { + (u16 *)(BG_VRAM + 0x5000), + (u16 *)(BG_VRAM + 0x5080), + (u16 *)(BG_VRAM + 0x5100), + (u16 *)(BG_VRAM + 0x5180), + (u16 *)(BG_VRAM + 0x5200), + (u16 *)(BG_VRAM + 0x5280), + (u16 *)(BG_VRAM + 0x5300), + (u16 *)(BG_VRAM + 0x5380) +}; + +const u16 *const gTilesetAnims_Mauville0a[] = { + gUnknown_08514E24, + gUnknown_08514E24, + gUnknown_08514EA4, + gUnknown_08514F24, + gUnknown_08514FA4, + gUnknown_08514FA4, + gUnknown_08514FA4, + gUnknown_08514FA4, + gUnknown_08514FA4, + gUnknown_08514FA4, + gUnknown_08514F24, + gUnknown_08514EA4 +}; + +const u16 *const gTilesetAnims_Mauville0b[] = { + gUnknown_085150A4, + gUnknown_085150A4, + gUnknown_08515124, + gUnknown_085151A4, + gUnknown_08515224, + gUnknown_08515224, + gUnknown_08515224, + gUnknown_08515224, + gUnknown_08515224, + gUnknown_08515224, + gUnknown_085151A4, + gUnknown_08515124 +}; + +const u16 *const gTilesetAnims_Mauville1a[] = { + gUnknown_08514E24, + gUnknown_08514E24, + gUnknown_08515024, + gUnknown_08515024 +}; + +const u16 *const gTilesetAnims_Mauville1b[] = { + gUnknown_085150A4, + gUnknown_085150A4, + gUnknown_085152A4, + gUnknown_085152A4 +}; + +const u16 gUnknown_08515404[] = INCBIN_U16("data/tilesets/secondary/rustboro/anim/0/0.4bpp"); + +const u16 gUnknown_08515484[] = INCBIN_U16("data/tilesets/secondary/rustboro/anim/0/1.4bpp"); + +const u16 gUnknown_08515504[] = INCBIN_U16("data/tilesets/secondary/rustboro/anim/0/2.4bpp"); + +const u16 gUnknown_08515584[] = INCBIN_U16("data/tilesets/secondary/rustboro/anim/0/3.4bpp"); + +const u16 gUnknown_08515604[] = INCBIN_U16("data/tilesets/secondary/rustboro/anim/0/4.4bpp"); + +const u16 gUnknown_08515684[] = INCBIN_U16("data/tilesets/secondary/rustboro/anim/0/5.4bpp"); + +const u16 gUnknown_08515704[] = INCBIN_U16("data/tilesets/secondary/rustboro/anim/0/6.4bpp"); + +const u16 gUnknown_08515784[] = INCBIN_U16("data/tilesets/secondary/rustboro/anim/0/7.4bpp"); + +u16 *const gTilesetAnims_RustboroVDests0[] = { + (u16 *)(BG_VRAM + 0x5000), + (u16 *)(BG_VRAM + 0x5080), + (u16 *)(BG_VRAM + 0x5100), + (u16 *)(BG_VRAM + 0x5180), + (u16 *)(BG_VRAM + 0x5200), + (u16 *)(BG_VRAM + 0x5280), + (u16 *)(BG_VRAM + 0x5300), + (u16 *)(BG_VRAM + 0x5380) +}; + +const u16 *const gTilesetAnims_Rustboro0[] = { + gUnknown_08515404, + gUnknown_08515484, + gUnknown_08515504, + gUnknown_08515584, + gUnknown_08515604, + gUnknown_08515684, + gUnknown_08515704, + gUnknown_08515784 +}; + +const u16 gUnknown_08515844[] = INCBIN_U16("data/tilesets/secondary/rustboro/anim/1/0.4bpp"); + +const u16 gUnknown_085158C4[] = INCBIN_U16("data/tilesets/secondary/rustboro/anim/1/1.4bpp"); + +const u16 tileset_anims_space_2[16] = {}; + +const u16 *const gTilesetAnims_Rustboro1[] = { + gUnknown_08515844, + gUnknown_085158C4 +}; + +const u16 gUnknown_0851596C[] = INCBIN_U16("data/tilesets/secondary/cave/anim/0.4bpp"); + +const u16 gUnknown_085159EC[] = INCBIN_U16("data/tilesets/secondary/cave/anim/1.4bpp"); + +const u16 gUnknown_08515A6C[] = INCBIN_U16("data/tilesets/secondary/cave/anim/2.4bpp"); + +const u16 gUnknown_08515AEC[] = INCBIN_U16("data/tilesets/secondary/cave/anim/3.4bpp"); + +const u16 gUnknown_08515B6C[] = INCBIN_U16("data/tilesets/secondary/cave/anim/unused/0.4bpp"); + +const u16 gUnknown_08515BEC[] = INCBIN_U16("data/tilesets/secondary/cave/anim/unused/1.4bpp"); + +const u16 gUnknown_08515C6C[] = INCBIN_U16("data/tilesets/secondary/cave/anim/unused/2.4bpp"); + +const u16 gUnknown_08515CEC[] = INCBIN_U16("data/tilesets/secondary/cave/anim/unused/3.4bpp"); + +const u16 tileset_anims_space_3[16] = {}; + +const u16 *const gTilesetAnims_Lavaridge1_Cave0[] = { + gUnknown_0851596C, + gUnknown_085159EC, + gUnknown_08515A6C, + gUnknown_08515AEC +}; + +const u16 gUnknown_08515D9C[] = INCBIN_U16("data/tilesets/secondary/ever_grande/anim/0.4bpp"); + +const u16 gUnknown_08515E1C[] = INCBIN_U16("data/tilesets/secondary/ever_grande/anim/1.4bpp"); + +const u16 gUnknown_08515E9C[] = INCBIN_U16("data/tilesets/secondary/ever_grande/anim/2.4bpp"); + +const u16 gUnknown_08515F1C[] = INCBIN_U16("data/tilesets/secondary/ever_grande/anim/3.4bpp"); + +const u16 gUnknown_08515F9C[] = INCBIN_U16("data/tilesets/secondary/ever_grande/anim/4.4bpp"); + +const u16 gUnknown_0851601C[] = INCBIN_U16("data/tilesets/secondary/ever_grande/anim/5.4bpp"); + +const u16 gUnknown_0851609C[] = INCBIN_U16("data/tilesets/secondary/ever_grande/anim/6.4bpp"); + +const u16 gUnknown_0851611C[] = INCBIN_U16("data/tilesets/secondary/ever_grande/anim/7.4bpp"); + +const u16 tileset_anims_space_4[16] = {}; + +u16 *const gTilesetAnims_EverGrandeVDests0[] = { + (u16 *)(BG_VRAM + 0x5c00), + (u16 *)(BG_VRAM + 0x5c80), + (u16 *)(BG_VRAM + 0x5d00), + (u16 *)(BG_VRAM + 0x5d80), + (u16 *)(BG_VRAM + 0x5e00), + (u16 *)(BG_VRAM + 0x5e80), + (u16 *)(BG_VRAM + 0x5f00), + (u16 *)(BG_VRAM + 0x5f80) +}; + +const u16 *const gTilesetAnims_EverGrande0[] = { + gUnknown_08515D9C, + gUnknown_08515E1C, + gUnknown_08515E9C, + gUnknown_08515F1C, + gUnknown_08515F9C, + gUnknown_0851601C, + gUnknown_0851609C, + gUnknown_0851611C +}; + +const u16 gUnknown_085161FC[] = INCBIN_U16("data/tilesets/secondary/dewford/anim/0.4bpp"); + +const u16 gUnknown_085162BC[] = INCBIN_U16("data/tilesets/secondary/dewford/anim/1.4bpp"); + +const u16 gUnknown_0851637C[] = INCBIN_U16("data/tilesets/secondary/dewford/anim/2.4bpp"); + +const u16 gUnknown_0851643C[] = INCBIN_U16("data/tilesets/secondary/dewford/anim/3.4bpp"); + +const u16 *const gTilesetAnims_Dewford0[] = { + gUnknown_085161FC, + gUnknown_085162BC, + gUnknown_0851637C, + gUnknown_0851643C +}; + +const u16 gUnknown_0851650C[] = INCBIN_U16("data/tilesets/secondary/battle_frontier_outside_west/anim/0.4bpp"); + +const u16 gUnknown_085165CC[] = INCBIN_U16("data/tilesets/secondary/battle_frontier_outside_west/anim/1.4bpp"); + +const u16 gUnknown_0851668C[] = INCBIN_U16("data/tilesets/secondary/battle_frontier_outside_west/anim/2.4bpp"); + +const u16 gUnknown_0851674C[] = INCBIN_U16("data/tilesets/secondary/battle_frontier_outside_west/anim/3.4bpp"); + +const u16 *const gTilesetAnims_BattleFrontierOutsideWest0[] = { + gUnknown_0851650C, + gUnknown_085165CC, + gUnknown_0851668C, + gUnknown_0851674C +}; + +const u16 gUnknown_0851681C[] = INCBIN_U16("data/tilesets/secondary/battle_frontier_outside_east/anim/0.4bpp"); + +const u16 gUnknown_085168DC[] = INCBIN_U16("data/tilesets/secondary/battle_frontier_outside_east/anim/1.4bpp"); + +const u16 gUnknown_0851699C[] = INCBIN_U16("data/tilesets/secondary/battle_frontier_outside_east/anim/2.4bpp"); + +const u16 gUnknown_08516A5C[] = INCBIN_U16("data/tilesets/secondary/battle_frontier_outside_east/anim/3.4bpp"); + +const u16 *const gTilesetAnims_BattleFrontierOutsideEast0[] = { + gUnknown_0851681C, + gUnknown_085168DC, + gUnknown_0851699C, + gUnknown_08516A5C +}; + +const u16 gUnknown_08516B2C[] = INCBIN_U16("data/tilesets/secondary/slateport/anim/0.4bpp"); + +const u16 gUnknown_08516BAC[] = INCBIN_U16("data/tilesets/secondary/slateport/anim/1.4bpp"); + +const u16 gUnknown_08516C2C[] = INCBIN_U16("data/tilesets/secondary/slateport/anim/2.4bpp"); + +const u16 gUnknown_08516CAC[] = INCBIN_U16("data/tilesets/secondary/slateport/anim/3.4bpp"); + +const u16 *const gTilesetAnims_Slateport0[] = { + gUnknown_08516B2C, + gUnknown_08516BAC, + gUnknown_08516C2C, + gUnknown_08516CAC +}; + +const u16 gUnknown_08516D3C[] = INCBIN_U16("data/tilesets/primary/building/anim/0.4bpp"); + +const u16 gUnknown_08516DBC[] = INCBIN_U16("data/tilesets/primary/building/anim/1.4bpp"); + +const u16 *const gTilesetAnims_InsideBuilding0[] = { + gUnknown_08516D3C, + gUnknown_08516DBC +}; + +const u16 gUnknown_08516E44[] = INCBIN_U16("data/tilesets/secondary/sootopolis_gym/anim/0/0.4bpp"); + +const u16 gUnknown_08516FC4[] = INCBIN_U16("data/tilesets/secondary/sootopolis_gym/anim/0/1.4bpp"); + +const u16 gUnknown_08517144[] = INCBIN_U16("data/tilesets/secondary/sootopolis_gym/anim/0/2.4bpp"); + +const u16 gUnknown_085172C4[] = INCBIN_U16("data/tilesets/secondary/sootopolis_gym/anim/1/0.4bpp"); + +const u16 gUnknown_08517544[] = INCBIN_U16("data/tilesets/secondary/sootopolis_gym/anim/1/1.4bpp"); + +const u16 gUnknown_085177C4[] = INCBIN_U16("data/tilesets/secondary/sootopolis_gym/anim/1/2.4bpp"); + +const u16 *const gTilesetAnims_SootopolisGym0[] = { + gUnknown_08516E44, + gUnknown_08516FC4, + gUnknown_08517144 +}; + +const u16 *const gTilesetAnims_SootopolisGym1[] = { + gUnknown_085172C4, + gUnknown_08517544, + gUnknown_085177C4 +}; + +const u16 gUnknown_08517A5C[] = INCBIN_U16("data/tilesets/secondary/elite_four/anim/1/0.4bpp"); + +const u16 gUnknown_08517ADC[] = INCBIN_U16("data/tilesets/secondary/elite_four/anim/1/1.4bpp"); + +const u16 gUnknown_08517B5C[] = INCBIN_U16("data/tilesets/secondary/elite_four/anim/0/0.4bpp"); + +const u16 gUnknown_08517B7C[] = INCBIN_U16("data/tilesets/secondary/elite_four/anim/0/1.4bpp"); + +const u16 gUnknown_08517B9C[] = INCBIN_U16("data/tilesets/secondary/elite_four/anim/0/2.4bpp"); + +const u16 gUnknown_08517BBC[] = INCBIN_U16("data/tilesets/secondary/elite_four/anim/0/3.4bpp"); + +const u16 tileset_anims_space_5[16] = {}; + +const u16 *const gTilesetAnims_EliteFour1[] = { + gUnknown_08517B5C, + gUnknown_08517B7C, + gUnknown_08517B9C, + gUnknown_08517BBC +}; + +const u16 *const gTilesetAnims_EliteFour0[] = { + gUnknown_08517A5C, + gUnknown_08517ADC +}; + +const u16 gUnknown_08517C14[] = INCBIN_U16("data/tilesets/secondary/mauville_gym/anim/0.4bpp"); + +const u16 gUnknown_08517E14[] = INCBIN_U16("data/tilesets/secondary/mauville_gym/anim/1.4bpp"); + +const u16 tileset_anims_space_6[16] = {}; + +const u16 *const gTilesetAnims_MauvilleGym0[] = { + gUnknown_08517C14, + gUnknown_08517E14 +}; + +const u16 gUnknown_0851803C[] = INCBIN_U16("data/tilesets/secondary/bike_shop/anim/0.4bpp"); + +const u16 gUnknown_0851815C[] = INCBIN_U16("data/tilesets/secondary/bike_shop/anim/1.4bpp"); + +const u16 tileset_anims_space_7[16] = {}; + +const u16 *const gTilesetAnims_BikeShop0[] = { + gUnknown_0851803C, + gUnknown_0851815C +}; + +const u16 gUnknown_085182A4[] = INCBIN_U16("data/tilesets/secondary/sootopolis/anim/0.4bpp"); + +const u16 gUnknown_08518EA4[] = INCBIN_U16("data/tilesets/secondary/sootopolis/anim/1.4bpp"); + +const u16 gUnknown_08519AA4[] = INCBIN_U16("data/tilesets/secondary/sootopolis/anim/2.4bpp"); + +const u16 gUnknown_0851A6A4[] = INCBIN_U16("data/tilesets/secondary/sootopolis/anim/3.4bpp"); + +const u16 gUnknown_0851B2A4[] = INCBIN_U16("data/tilesets/secondary/sootopolis/anim/4.4bpp"); + +const u16 gUnknown_0851BEA4[] = INCBIN_U16("data/tilesets/secondary/sootopolis/anim/5.4bpp"); + +const u16 gUnknown_0851CAA4[] = INCBIN_U16("data/tilesets/secondary/sootopolis/anim/6.4bpp"); + +const u16 gUnknown_0851D6A4[] = INCBIN_U16("data/tilesets/secondary/sootopolis/anim/7.4bpp"); + +const u16 tileset_anims_space_8[16] = {}; + +const u16 gUnknown_0851E2C4[] = INCBIN_U16("data/tilesets/secondary/unused_1/0.4bpp"); + +const u16 gUnknown_0851EAC4[] = INCBIN_U16("data/tilesets/secondary/unused_1/1.4bpp"); + +const u16 gUnknown_0851F2C4[] = INCBIN_U16("data/tilesets/secondary/unused_1/2.4bpp"); + +const u16 gUnknown_0851FAC4[] = INCBIN_U16("data/tilesets/secondary/unused_1/3.4bpp"); + +const u16 *const gTilesetAnims_Sootopolis0[] = { + gUnknown_085182A4, + gUnknown_08518EA4, + gUnknown_08519AA4, + gUnknown_0851A6A4, + gUnknown_0851B2A4, + gUnknown_0851BEA4, + gUnknown_0851CAA4, + gUnknown_0851D6A4 +}; + +const u16 gUnknown_085202E4[] = INCBIN_U16("data/tilesets/secondary/battle_pyramid/anim/0/0.4bpp"); + +const u16 gUnknown_085203E4[] = INCBIN_U16("data/tilesets/secondary/battle_pyramid/anim/0/1.4bpp"); + +const u16 gUnknown_085204E4[] = INCBIN_U16("data/tilesets/secondary/battle_pyramid/anim/0/2.4bpp"); + +const u16 tileset_anims_space_9[16] = {}; + +const u16 gUnknown_08520604[] = INCBIN_U16("data/tilesets/secondary/battle_pyramid/anim/1/0.4bpp"); + +const u16 gUnknown_08520704[] = INCBIN_U16("data/tilesets/secondary/battle_pyramid/anim/1/1.4bpp"); + +const u16 gUnknown_08520804[] = INCBIN_U16("data/tilesets/secondary/battle_pyramid/anim/1/2.4bpp"); + +const u16 tileset_anims_space_10[7808] = {}; + +const u16 gUnknown_08524604[] = INCBIN_U16("data/tilesets/secondary/unused_2/0.4bpp"); + +const u16 tileset_anims_space_11[224] = {}; + +const u16 gUnknown_08524804[] = INCBIN_U16("data/tilesets/secondary/unused_2/1.4bpp"); + +const u16 *const gTilesetAnims_BattlePyramid0[] = { + gUnknown_085202E4, + gUnknown_085203E4, + gUnknown_085204E4 +}; + +const u16 *const gTilesetAnims_BattlePyramid1[] = { + gUnknown_08520604, + gUnknown_08520704, + gUnknown_08520804 +}; extern const u16 gUnknown_08D85640[]; extern const u16 gUnknown_08D85660[]; -- cgit v1.2.3 From 572648ba2d82dbdc8a05ba3d38908e1a1c326e0e Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 2 Oct 2017 21:51:22 -0400 Subject: BSS: field_screen, field_effect, pokemon_storage_system, fldeff_cut, script_menu --- src/field_effect.c | 15 +++++++++++++++ src/field_screen.c | 15 +++++++++++++++ src/fldeff_cut.c | 19 +++++++++++++++++++ src/pokemon_storage_system.c | 15 +++++++++++++++ src/script_menu.c | 16 ++++++++++++++++ 5 files changed, 80 insertions(+) create mode 100644 src/field_effect.c create mode 100644 src/field_screen.c create mode 100644 src/fldeff_cut.c create mode 100644 src/pokemon_storage_system.c create mode 100644 src/script_menu.c (limited to 'src') diff --git a/src/field_effect.c b/src/field_effect.c new file mode 100644 index 000000000..628dc776a --- /dev/null +++ b/src/field_effect.c @@ -0,0 +1,15 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations + +IWRAM_DATA u8 gUnknown_03000F58[32]; + +// Static ROM declarations + +// .rodata + +// .text diff --git a/src/field_screen.c b/src/field_screen.c new file mode 100644 index 000000000..2d33d237f --- /dev/null +++ b/src/field_screen.c @@ -0,0 +1,15 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations +IWRAM_DATA u8 *gUnknown_03000F50; +IWRAM_DATA u32 filler_03000f54; + +// Static ROM declarations + +// .rodata + +// .text diff --git a/src/fldeff_cut.c b/src/fldeff_cut.c new file mode 100644 index 000000000..9929dd6f9 --- /dev/null +++ b/src/fldeff_cut.c @@ -0,0 +1,19 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations + +IWRAM_DATA u8 gUnknown_03001100; +IWRAM_DATA u8 gUnknown_03001101; +IWRAM_DATA u8 gUnknown_03001102; +IWRAM_DATA u32 fldeff_cut_unused_03001104; +IWRAM_DATA u8 gUnknown_03001108[25]; + +// Static ROM declarations + +// .rodata + +// .text diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c new file mode 100644 index 000000000..3e409244c --- /dev/null +++ b/src/pokemon_storage_system.c @@ -0,0 +1,15 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations + +IWRAM_DATA u8 gUnknown_03000F78[0x188]; + +// Static ROM declarations + +// .rodata + +// .text diff --git a/src/script_menu.c b/src/script_menu.c new file mode 100644 index 000000000..04f1e82b7 --- /dev/null +++ b/src/script_menu.c @@ -0,0 +1,16 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations + +IWRAM_DATA u8 gUnknown_03001124[6]; +IWRAM_DATA u32 filler_0300112c; + +// Static ROM declarations + +// .rodata + +// .text -- cgit v1.2.3 From ce5ac9d782c100a5e9ed58ed7ba611565d7d7a50 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 2 Oct 2017 22:02:22 -0400 Subject: BSS: record_mixing --- src/record_mixing.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/record_mixing.c (limited to 'src') diff --git a/src/record_mixing.c b/src/record_mixing.c new file mode 100644 index 000000000..151835e5e --- /dev/null +++ b/src/record_mixing.c @@ -0,0 +1,28 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations + +IWRAM_DATA bool8 gUnknown_03001130; +IWRAM_DATA struct SecretBaseRecord *gUnknown_03001134; +IWRAM_DATA TVShow *gUnknown_03001138; +IWRAM_DATA struct UnknownSaveStruct2ABC *gUnknown_0300113C; +IWRAM_DATA OldMan *gUnknown_03001140; +IWRAM_DATA struct EasyChatPair *gUnknown_03001144; +IWRAM_DATA struct DaycareData *gUnknown_03001148; +IWRAM_DATA void *gUnknown_0300114C; // gSaveBlock2Ptr->field_64C +IWRAM_DATA LilycoveLady *gUnknown_03001150; +IWRAM_DATA void *gUnknown_03001154; // gSaveBlock2Ptr->field_0DC; +IWRAM_DATA void *gUnknown_03001158; // gSaveBlock2Ptr->field_64C +IWRAM_DATA u32 gUnknown_0300115C; +IWRAM_DATA u8 gUnknown_03001160[8]; +IWRAM_DATA u32 gUnknown_03001168[3]; + +// Static ROM declarations + +// .rodata + +// .text -- cgit v1.2.3