pmd-red/src/code_8069E0C.c
2024-11-16 12:18:40 -05:00

334 lines
8.8 KiB
C

#include "global.h"
#include "code_803E46C.h"
#include "code_803E668.h"
#include "code_8045A00.h"
#include "constants/ability.h"
#include "constants/move_id.h"
#include "constants/status.h"
#include "constants/type.h"
#include "constants/weather.h"
#include "dungeon_map_access.h"
#include "dungeon_pokemon_attributes.h"
#include "dungeon_random.h"
#include "dungeon_message.h"
#include "dungeon_util.h"
#include "game_options.h"
#include "move_effects_target.h"
#include "moves.h"
#include "pokemon.h"
#include "structs/dungeon_entity.h"
#include "structs/str_dungeon.h"
#include "text_util.h"
#include "weather.h"
struct unkStruct_80F520C
{
u8 unk0; // types0
u8 unk1; // Most likely just padding and should be removed
s16 unk2; // monsterID
};
// Castform Forecast ability data
extern struct unkStruct_80F520C gUnknown_80F520C[WEATHER_RANDOM];
extern u8 gUnknown_80F51E4[];
extern u8 *gUnknown_80FCC7C[];
extern u8 *gUnknown_80FCCAC[];
extern u8 *gUnknown_80FDCC8[];
extern void sub_8042900(Entity *r0);
extern void sub_8042968(Entity *r0);
extern void sub_806ABAC(Entity *, Entity *);
void sub_8041BBC(Entity *r0);
extern bool8 sub_8045888(Entity *);
extern void sub_806A2BC(Entity *, u8);
extern void sub_804178C(u32);
extern void sub_803F508(Entity *);
void sub_8069E0C(Entity *pokemon)
{
s32 index;
EntityInfo *entityInfo;
entityInfo = GetEntInfo(pokemon);
if (HasAbility(pokemon, ABILITY_FORECAST)) {
entityInfo->types[0] = gUnknown_80F520C[GetApparentWeather(pokemon)].unk0;
entityInfo->types[1] = TYPE_NONE;
}
else {
for(index = 0; index < 2; index++)
entityInfo->types[index] = GetPokemonType(entityInfo->id, index);
}
for(index = 0; index < 2; index++)
entityInfo->abilities[index] = GetPokemonAbility(entityInfo->id, index);
gDungeon->unkC = 1;
}
void TriggerWeatherAbilities(void)
{
Entity *entity;
s32 index;
if (gDungeon->unkC != 0) {
gDungeon->unkC = 0;
gDungeon->weather.nullifyWeather = FALSE;
for(index = 0; index < DUNGEON_MAX_POKEMON; index++)
{
entity = gDungeon->activePokemon[index];
if (EntityExists(entity)) {
if (HasAbility(entity, ABILITY_DRIZZLE)) {
gDungeon->weather.naturalWeather[WEATHER_RAIN] = 1;
}
else if (HasAbility(entity, ABILITY_SAND_STREAM)) {
gDungeon->weather.naturalWeather[WEATHER_SANDSTORM] = 1;
}
else if (HasAbility(entity, ABILITY_DROUGHT)) {
gDungeon->weather.naturalWeather[WEATHER_SUNNY] = 1;
}
if ((HasAbility(entity, ABILITY_AIR_LOCK)) || (HasAbility(entity, ABILITY_CLOUD_NINE))) {
gDungeon->weather.nullifyWeather = TRUE;
}
}
}
}
}
s32 GetMonsterApparentID(Entity *pokemon, s16 id)
{
if (id == MONSTER_CASTFORM || id == MONSTER_CASTFORM_SNOWY || id == MONSTER_CASTFORM_SUNNY || id == MONSTER_CASTFORM_RAINY) {
if (HasAbility(pokemon, ABILITY_FORECAST))
return gUnknown_80F520C[GetApparentWeather(pokemon)].unk2;
return MONSTER_CASTFORM;
}
return id;
}
static inline u8 sub_8069F9C_sub(Entity *pokemon)
{
u32 weather;
weather = GetApparentWeather(pokemon);
return gUnknown_80F51E4[weather];
}
void sub_8069F9C(Entity *pokemon,Entity * target,Move *move)
{
u8 type;
u8 ability;
const char *__src;
#ifndef NONMATCHING
register s32 abilityCounter asm("r1"); // r1
#else
s32 abilityCounter;
#endif
int randomIndex;
int abilityIndex;
EntityInfo *iVar6; // r7
EntityInfo *iVar7; // r2
EntityInfo *iVar8;
u8 local_20 [4];
if (!EntityExists(pokemon)) {
return;
}
if (!EntityExists(target)) {
return;
}
if (pokemon == target) {
return;
}
iVar7 = GetEntInfo(pokemon);
iVar8 = iVar7;
iVar6 = GetEntInfo(target);
abilityIndex = -1;
if (iVar6->abilities[0] == ABILITY_TRACE) {
abilityIndex = 0;
}
if (iVar6->abilities[1] == ABILITY_TRACE) {
abilityIndex = 1;
}
if (-1 < abilityIndex) {
abilityCounter = 0;
ability = iVar7->abilities[0];
if (ability != ABILITY_UNKNOWN) {
local_20[0] = ability;
abilityCounter = 1;
}
ability = iVar8->abilities[1];
if (ability != ABILITY_UNKNOWN) {
local_20[abilityCounter] = ability;
abilityCounter++;
}
if (abilityCounter != 0) {
if (abilityCounter == 1) {
randomIndex = 0;
}
else {
randomIndex = DungeonRandInt(abilityCounter);
if (randomIndex < 0) goto _0806A068;
}
iVar6->abilities[abilityIndex] = local_20[randomIndex];
gDungeon->unkC = 1;
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],target,0);
TryDisplayDungeonLoggableMessage3(pokemon,target,*gUnknown_80FCC7C);
sub_8042900(target);
sub_806ABAC(pokemon,target);
}
}
_0806A068:
if (iVar6->unk15A != 0) {
iVar6->unk15A = 0;
if (HasAbility(target, ABILITY_COLOR_CHANGE)) {
type = GetMoveTypeForMonster(pokemon,move);
if (move->id == MOVE_WEATHER_BALL) {
type = sub_8069F9C_sub(pokemon);
}
if ((type != TYPE_NONE) && (!MonsterIsType(target,type))) {
iVar6->types[0] = type;
iVar6->types[1] = TYPE_NONE;
iVar6->isColorChanged = TRUE;
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],target,0);
__src = GetUnformattedTypeString(iVar6->types[0]);
strcpy(gFormatBuffer_Items[0],__src);
TryDisplayDungeonLoggableMessage3(pokemon,target,*gUnknown_80FCCAC);
sub_8042968(target);
}
}
}
}
void sub_806A120(Entity * pokemon, Entity * target, Move* move)
{
u32 uVar2_u32;
u8 moveType;
const char *typeString;
EntityInfo *entityInfo;
if ((((EntityExists(pokemon)) && (EntityExists(target))) && (pokemon != target))
&& (entityInfo = GetEntInfo(target), entityInfo->reflectClassStatus.status == STATUS_CONVERSION2)) {
moveType = GetMoveTypeForMonster(pokemon, move);
uVar2_u32 = sub_8092364(moveType);
if (uVar2_u32 != TYPE_NONE) {
entityInfo->types[0] = uVar2_u32;
entityInfo->types[1] = 0;
sub_8041BBC(target);
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],target,0);
typeString = GetUnformattedTypeString(uVar2_u32);
strcpy(gFormatBuffer_Items[0],typeString);
TryDisplayDungeonLoggableMessage3(pokemon,target,*gUnknown_80FDCC8);
}
}
}
void sub_806A1B0(Entity *pokemon)
{
if ((EntityExists(pokemon)) && (HasAbility(pokemon, ABILITY_TRUANT))) {
PausedStatusTarget(pokemon,pokemon,0,1,0);
}
}
void sub_806A1E8(Entity *pokemon)
{
bool8 bVar3;
EntityInfo *entityInfo;
bVar3 = FALSE;
if (EntityExists(pokemon)) {
if (GetEntityType(pokemon) == ENTITY_MONSTER) {
entityInfo = GetEntInfo(pokemon);
bVar3 = (!entityInfo->isNotTeamMember);
}
if (gGameOptionsRef->FarOffPals == '\0') {
bVar3 = FALSE;
}
if (bVar3 && (!sub_8045888(pokemon))) {
sub_806A2BC(pokemon,1);
}
}
}
void sub_806A240(Entity *pokemon, Entity *target)
{
bool8 isNotTeamMember;
EntityInfo *entityInfo;
isNotTeamMember = FALSE;
if (EntityExists(pokemon)){
if (GetEntityType(pokemon) == ENTITY_MONSTER) {
entityInfo = GetEntInfo(pokemon);
isNotTeamMember = (!entityInfo->isNotTeamMember);
}
if (isNotTeamMember && (!sub_8045888(pokemon))) {
sub_806A2BC(pokemon,1);
return;
}
else if (GetEntityType(target) == ENTITY_MONSTER) {
entityInfo = GetEntInfo(target);
isNotTeamMember = (!entityInfo->isNotTeamMember);
}
if (isNotTeamMember && (!sub_8045888(target))) {
sub_806A2BC(target,1);
}
}
}
void sub_806A2BC(Entity *pokemon, u8 param_2)
{
if ((EntityExists(pokemon)) && (GetEntityType(pokemon) == ENTITY_MONSTER) && (gDungeon->unk181e8.cameraTarget != pokemon)) {
if (param_2 != '\0') {
sub_804178C(1);
while (gDungeon->unk12 < 0x3c) {
sub_803E46C(0x34);
}
}
sub_803E708(4,0x44);
sub_803F508(pokemon);
sub_804AC20(&pokemon->pos);
gDungeon->unk12 = 0;
}
}
void nullsub_95(void)
{}
void sub_806A338(void)
{
Entity *entity;
s32 index;
for(index = 0; index < DUNGEON_MAX_POKEMON; index++)
{
entity = gDungeon->activePokemon[index];
if (EntityExists(entity) && (GetEntInfo(entity)->curseClassStatus.status == STATUS_SNATCH))
{
gDungeon->snatchPokemon = entity;
ASM_MATCH_TRICK(entity);
gDungeon->unk17B3C = GetEntInfo(entity)->unk98;
break;
}
}
}
void sub_806A390(Entity *pokemon)
{
s32 index;
EntityInfo *info;
Move *move;
info = GetEntInfo(pokemon);
for(index = 0; index < MAX_MON_MOVES; index++)
{
move = &info->moves.moves[index];
if(move->moveFlags & MOVE_FLAG_EXISTS)
{
move->moveFlags2 &= 0xF7;
move->moveFlags2 &= 0xEF;
move->moveFlags2 |= MOVE_FLAG2_UNK4;
move->PP = GetMoveBasePP(move);
}
}
}