pmd-red/src/code_8040094_1.c
2025-03-08 19:14:00 +01:00

486 lines
13 KiB
C

#include "global.h"
#include "globaldata.h"
#include "dungeon_message.h"
#include "dungeon_random.h"
#include "structs/dungeon_entity.h"
#include "structs/str_dungeon.h"
#include "dungeon_music.h"
#include "dungeon.h"
#include "code_8009804.h"
#include "code_800E9E4.h"
#include "dungeon_util.h"
#include "code_804267C.h"
#include "weather.h"
#include "tile_types.h"
#include "constants/move_id.h"
#include "constants/weather.h"
#include "constants/type.h"
struct UnkStruct_8040094
{
u16 unk0;
u16 unk2;
DungeonPos unk4;
DungeonPos unk8;
s32 unkC;
s32 unk10;
};
extern u8 sub_800EC94(s32 param_1);
extern s32 sub_800E710(s32 a0, u16 a1);
extern void sub_800569C(DungeonPos *, axdata *, u8);
extern void sub_800EEC8(u16 r0);
extern void sub_800EF64(void);
extern void sub_8042DD4(s32 a0, Entity *a1, s32 a2);
extern void sub_803E46C(u32);
extern u8 sub_800EA44(s32 species, u16 a2);
extern s32 sub_800E790(s32 species, u16 a2);
extern void sub_806CDD4(Entity *entity, u8, u32 direction);
extern s32 sub_800E52C(struct UnkStruct_8040094 *a0);
extern s32 sub_800EA84(struct UnkStruct_8040094 *a0);
extern bool8 sub_800E838(struct UnkStruct_8040094 *a0, s32 a1);
extern bool8 sub_800E9A8(s32 a0);
extern void sub_803EA10(void);
extern void sub_803E708(s32, u32);
extern void sub_800EEF8(u16 a0);
extern bool8 sub_803F428(DungeonPos *pos);
extern void sub_800EEE0(u16 a0);
extern s32 sub_800EBC8(struct UnkStruct_8040094 *a0);
extern bool8 sub_800E7D0(struct UnkStruct_8040094 *a0);
extern s32 sub_800ED20(u16 param_1);
extern u8 sub_800EC84(s32 param_1);
extern bool8 MoveMatchesBideClassStatus(Entity *pokemon, Move *move);
extern bool8 IsSleeping(Entity *pokemon);
extern void sub_80421C0(Entity *pokemon, u16);
extern u8 gUnknown_203B40D;
extern s16 gUnknown_2026E4E;
extern s32 gDungeonBrightness;
extern s32 gUnknown_202F224;
extern const u8 *const gPtrMagnitudeMessage;
extern const s32 gUnknown_8106A8C[];
u16 sub_80412E0(u16 moveId, u8 weather, bool32 a2);
static bool32 sub_804143C(Entity *entity, Move *move);
static bool8 sub_80414C0(Entity *entity, Move *move);
static bool8 sub_804141C(u16 moveId, u8 weather, bool32 a2);
static void sub_8040C4C(Entity *entity, Move *move, bool32 a2);
static void sub_8041038(struct UnkStruct_8040094 *a0, Entity *entity, Move *move, bool32 a2);
static void sub_8041108(struct UnkStruct_8040094 *a0, Entity *entity, Move *move, bool32 a2);
static void sub_8041500(struct UnkStruct_8040094 *a0);
bool8 sub_8040BB0(Entity *entity, Move *move, bool8 a2)
{
bool32 r8 = sub_804143C(entity, move);
bool8 r9 = sub_804141C(move->id, GetApparentWeather(entity), r8);
s32 r4 = sub_800ECB8(sub_80412E0(move->id, GetApparentWeather(entity), r8))->unk0;
if (!sub_8042768(entity))
return r9;
if (sub_80414C0(entity, move))
return r9;
if (!a2)
return r9;
if (r4 != 0) {
sub_8040C4C(entity, move, r8);
}
return r9;
}
static void sub_8040C4C(Entity *entity, Move *move, bool32 a2)
{
u8 savedUnkVar;
s32 r4;
struct UnkStruct_8040094 sp;
u16 r9 = sub_80412E0(move->id, GetApparentWeather(entity), a2);
EntityInfo *entInfo = GetEntInfo(entity);
bool8 r8 = sub_800EC94(move->id);
s32 apparentId = entInfo->apparentID;
s32 r2 = sub_800E710(apparentId, sub_80412E0(move->id, GetApparentWeather(entity), TRUE));
if (r2 != -1) {
sub_800569C(&sp.unk8, &entity->axObj.axdata, r2);
}
else {
sp.unk8 = (DungeonPos) {0};
}
sp.unk0 = r9;
sp.unk2 = entInfo->apparentID;
sp.unk4.x = entity->pixelPos.x / 256;
sp.unk4.y = entity->pixelPos.y / 256;
sp.unkC = entInfo->action.direction;
sp.unk10 = 0;
sub_8041500(&sp);
sub_800EEC8(r9);
sub_800EF64();
sub_803E46C(0x58);
r4 = sub_800EA84(&sp);
sub_8042DD4(r4, entity, 5);
savedUnkVar = gUnknown_203B40D;
while (1) {
if (!sub_800E9A8(r4))
break;
if (!r8)
break;
gUnknown_203B40D = 1;
if (gUnknown_2026E4E != 0x1010) {
gUnknown_2026E4E += 0x101;
}
if (gDungeonBrightness >= 5) {
gDungeonBrightness -= 4;
}
else {
gDungeonBrightness = 0;
r8 = FALSE;
}
sub_803EA10();
sub_803E46C(0x26);
}
gUnknown_203B40D = savedUnkVar;
}
void sub_8040DA0(Entity *entity, Move *move)
{
s32 i;
s32 soundEffectId;
Entity *anotherEntity;
struct UnkStruct_8040094 sp;
bool32 r9 = sub_804143C(entity, move);
bool8 var_28 = FALSE;
EntityInfo *entInfo = GetEntInfo(entity);
u8 var_24 = sub_800EA44(entInfo->apparentID, sub_80412E0(move->id, GetApparentWeather(entity), r9));
sub_8041038(&sp, entity, move, r9);
if (sub_800E838(&sp, 1)) {
anotherEntity = gDungeon->unk181e8.cameraTarget;
}
else if (move->id == MOVE_SILVER_WIND) {
anotherEntity = gDungeon->unk181e8.cameraTarget;
}
else {
anotherEntity = entity;
}
if (!EntityIsValid(anotherEntity)) {
anotherEntity = entity;
}
sp.unk4.x = anotherEntity->pixelPos.x / 256;
sp.unk4.y = anotherEntity->pixelPos.y / 256;
if (!sub_8042768(anotherEntity))
return;
if (sub_80414C0(entity, move))
return;
if (move->id == MOVE_MAGNITUDE) {
gUnknown_202F224 = DungeonRandInt(7);
gDungeon->unk181e8.unk18204 = gDungeon->unk181e8.unk18200 = gUnknown_8106A8C[gUnknown_202F224];
gFormatArgs[0] = gUnknown_202F224 + 4;
LogMessageByIdWithPopupCheckUser(anotherEntity, gPtrMagnitudeMessage);
sub_80421C0(anotherEntity, 0x1A4);
}
else if (move->id == MOVE_EARTHQUAKE) {
gDungeon->unk181e8.unk18204 = gDungeon->unk181e8.unk18200 = 12;
sub_80421C0(anotherEntity, 0x1A4);
}
soundEffectId = sub_800E790(entInfo->apparentID, sub_80412E0(move->id, GetApparentWeather(entity), r9));
if (soundEffectId != 0x3E5) {
PlaySoundEffect((u16) soundEffectId);
}
if (var_24 == 99) {
if (sub_8042768(anotherEntity)) {
s32 direction = entInfo->action.direction;
sub_8041108(&sp, entity, move, r9);
for (i = 0; i < NUM_DIRECTIONS; i++) {
direction--;
direction &= DIRECTION_MASK;
sub_806CDD4(entity, 0, direction);
sub_803E708(2, 0x15);
}
}
}
else if (var_24 == 98) {
if (sub_8042768(anotherEntity)) {
s32 direction = entInfo->action.direction;
sub_8041108(&sp, entity, move, r9);
for (i = 0; i < NUM_DIRECTIONS + 1; i++) {
direction &= DIRECTION_MASK;
sub_806CDD4(entity, 0, direction);
sub_803E708(2, 0x15);
direction++;
}
}
}
else {
sub_806CDD4(entity, var_24, entInfo->action.direction);
entity->unk21 = 0;
for (i = 0; i < 120; i++) {
u32 unk;
sub_803E46C(0x59);
unk = entity->axObj.axdata.sub1.unk10;
if (var_24 == 9) {
unk |= 2;
}
if ((unk & 2) && !var_28) {
sub_8041108(&sp, entity, move, r9);
var_28 = TRUE;
}
if (unk & 1)
break;
if (entity->unk21 != 0)
break;
}
entity->unk21 = 0;
}
}
static void sub_8041038(struct UnkStruct_8040094 *a0, Entity *entity, Move *move, bool32 a2)
{
EntityInfo *entInfo = GetEntInfo(entity);
u16 var_24 = sub_80412E0(move->id, GetApparentWeather(entity), a2);
if (sub_800ECB8(var_24)->unk2 != 0) {
s32 r2 = sub_800E710(entInfo->apparentID, sub_80412E0(move->id, GetApparentWeather(entity), a2));
if (r2 != -1) {
sub_800569C(&a0->unk8, &entity->axObj.axdata, r2);
}
else {
a0->unk8 = (DungeonPos) {0};
}
a0->unk0 = var_24;
a0->unk2 = entInfo->apparentID;
a0->unk4.x = entity->pixelPos.x / 256;
a0->unk4.y = entity->pixelPos.y / 256;
a0->unkC = entInfo->action.direction;
a0->unk10 = 0;
}
else {
a0->unk0 = 0;
}
}
static void sub_8041108(struct UnkStruct_8040094 *a0, Entity *entity, Move *move, bool32 a2)
{
u16 r4 = sub_80412E0(move->id, GetApparentWeather(entity), a2);
s32 var = sub_800ECB8(r4)->unk2;
if (a0->unk0 != 0 && var != 0) {
sub_8041500(a0);
sub_800EEF8(r4);
sub_800EF64();
sub_803E46C(0x5A);
sub_8042DD4(sub_800E52C(a0), entity, 1);
}
}
void sub_8041168(Entity *entity, Entity *entity2, Move *move, DungeonPos *pos)
{
s32 var2;
s32 var3;
struct UnkStruct_8040094 sp;
bool32 r5 = (sub_804143C(entity, move) != 0);
u16 r10 = sub_80412E0(move->id, GetApparentWeather(entity), r5);
s32 var = sub_800ECB8(r10)->unk4;
EntityInfo *ent2Info = NULL;
if (EntityIsValid(entity2)) {
ent2Info = GetEntInfo(entity2);
if (!sub_8042768(entity2))
return;
}
else {
if (!sub_803F428(pos))
return;
}
if (sub_80414C0(entity, move))
return;
if (var == 0)
return;
var2 = sub_800ECA4(var)->unk1c;
if (var2 != -1) {
if (EntityIsValid(entity2)) {
sub_800569C(&sp.unk8, &entity2->axObj.axdata, var2);
}
else {
sp.unk8 = (DungeonPos) {0};
}
}
else {
sp.unk8 = (DungeonPos) {0};
}
sp.unk0 = r10;
if (ent2Info != NULL) {
sp.unk2 = ent2Info->apparentID;
sp.unk4.x = entity2->pixelPos.x / 256;
sp.unk4.y = entity2->pixelPos.y / 256;
sp.unkC = 0;
}
else {
s32 x, y;
sp.unk2 = 1;
x = X_POS_TO_PIXELPOS(pos->x);
sp.unk4.x = x / 256;
y = Y_POS_TO_PIXELPOS(pos->y);
sp.unk4.y = y / 256;
sp.unkC = 0;
}
sp.unk10 = 0;
sub_8041500(&sp);
sub_800EEE0(r10);
sub_800EF64();
var3 = sub_800EBC8(&sp);
sub_803E46C(0x5B);
sub_8042DD4(var3, entity2, 6);
while (1) {
if (!sub_800E9A8(var3))
break;
sub_803E46C(0x28);
}
}
u16 sub_80412E0(u16 moveId, u8 weather, bool32 a2)
{
u16 ret = moveId;
if (moveId == MOVE_WEATHER_BALL) {
switch (weather) {
case WEATHER_CLEAR:
case WEATHER_FOG:
case WEATHER_CLOUDY:
ret = moveId;
break;
case WEATHER_SUNNY:
ret = 0x19E;
break;
case WEATHER_SANDSTORM:
ret = 0x1A1;
break;
case WEATHER_RAIN:
ret = 0x1A0;
break;
case WEATHER_HAIL:
case WEATHER_SNOW:
ret = 0x19F;
break;
}
}
else if (a2) {
switch (moveId) {
case MOVE_DIG:
ret = 0x1A2;
break;
case MOVE_RAZOR_WIND:
ret = 0x1A3;
break;
case MOVE_FOCUS_PUNCH:
ret = 0x1A4;
break;
case MOVE_SKY_ATTACK:
ret = 0x1A5;
break;
case MOVE_SOLARBEAM:
ret = 0x1A6;
break;
case MOVE_FLY:
ret = 0x1A7;
break;
case MOVE_DIVE:
ret = 0x1A8;
break;
case MOVE_BOUNCE:
ret = 0x1A9;
break;
case MOVE_SKULL_BASH:
ret = 0x1AA;
break;
case MOVE_CURSE:
ret = 0x1AB;
break;
case MOVE_SNORE:
ret = 0x1AC;
break;
case MOVE_SLEEP_TALK:
ret = 0x1AD;
break;
default:
ret = moveId;
break;
}
}
return ret;
}
UNUSED static s32 sub_8041400(u16 moveId, u8 weather, bool32 a2)
{
return sub_800ED20(sub_80412E0(moveId, weather, a2));
}
static bool8 sub_804141C(u16 moveId, u8 weather, bool32 a2)
{
return sub_800EC84(sub_80412E0(moveId, weather, a2));
}
static bool32 sub_804143C(Entity *entity, Move *move)
{
if (move->id == MOVE_CURSE) {
if (EntityIsValid(entity) && GetEntityType(entity) == ENTITY_MONSTER) {
if (GetEntInfo(entity)->types[0] == TYPE_GHOST || GetEntInfo(entity)->types[1] == TYPE_GHOST)
return TRUE;
else
return FALSE;
}
}
else if (move->id == MOVE_SNORE || move->id == MOVE_SLEEP_TALK) {
if (!IsSleeping(entity))
return TRUE;
else
return FALSE;
}
else if (move->id == MOVE_SOLARBEAM) {
if (GetApparentWeather(entity) == WEATHER_SUNNY)
return TRUE;
}
return MoveMatchesBideClassStatus(entity, move) != FALSE;
}
static bool8 sub_80414C0(Entity *entity, Move *move)
{
if (move->id == MOVE_DIVE) {
if (IsTileGround(GetTileAtEntitySafe(entity)))
return TRUE;
}
if (move->id == MOVE_DIG) {
if (GetTerrainType(GetTileAtEntitySafe(entity)) != TERRAIN_TYPE_NORMAL)
return TRUE;
}
return FALSE;
}
static void sub_8041500(struct UnkStruct_8040094 *a0)
{
if (sub_800E7D0(a0)) {
sub_803E46C(0x5C);
sub_8052740(0x5D);
}
}