mirror of
https://github.com/pret/pmd-red.git
synced 2026-08-24 01:35:07 -05:00
Merge pull request #142 from Kermalis/kermalis-dungeon_capabilities
Complete dungeon_capabilities
This commit is contained in:
@@ -1,91 +0,0 @@
|
||||
#include "asm/constants/gba_constants.inc"
|
||||
#include "asm/macros.inc"
|
||||
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
thumb_func_start sub_8070BC0
|
||||
sub_8070BC0:
|
||||
push {r4-r6,lr}
|
||||
adds r4, r0, 0
|
||||
ldr r5, [r4, 0x70]
|
||||
movs r1, 0
|
||||
bl IsCharging
|
||||
lsls r0, 24
|
||||
cmp r0, 0
|
||||
bne _08070C56
|
||||
adds r6, r5, 0
|
||||
adds r6, 0xA8
|
||||
ldrb r0, [r6]
|
||||
cmp r0, 0x4
|
||||
beq _08070C56
|
||||
cmp r0, 0x3
|
||||
beq _08070C56
|
||||
adds r0, r4, 0
|
||||
bl ShouldMonsterRunAway
|
||||
lsls r0, 24
|
||||
cmp r0, 0
|
||||
bne _08070C56
|
||||
adds r0, r5, 0
|
||||
adds r0, 0xEC
|
||||
ldrb r0, [r0]
|
||||
cmp r0, 0x1
|
||||
beq _08070C56
|
||||
adds r0, r5, 0
|
||||
adds r0, 0xB0
|
||||
ldrb r1, [r0]
|
||||
cmp r1, 0x6
|
||||
beq _08070C56
|
||||
cmp r1, 0x1
|
||||
beq _08070C56
|
||||
adds r0, r5, 0
|
||||
adds r0, 0xBC
|
||||
ldrb r3, [r0]
|
||||
adds r4, r0, 0
|
||||
cmp r3, 0x2
|
||||
beq _08070C56
|
||||
ldrb r2, [r6]
|
||||
cmp r2, 0x1
|
||||
beq _08070C56
|
||||
adds r0, r5, 0
|
||||
adds r0, 0xE4
|
||||
ldrb r0, [r0]
|
||||
cmp r0, 0x1
|
||||
beq _08070C56
|
||||
cmp r2, 0x5
|
||||
beq _08070C56
|
||||
cmp r3, 0x1
|
||||
beq _08070C56
|
||||
cmp r1, 0x3
|
||||
beq _08070C56
|
||||
cmp r1, 0x4
|
||||
beq _08070C56
|
||||
adds r0, r5, 0
|
||||
adds r0, 0xE8
|
||||
ldrb r1, [r0]
|
||||
cmp r1, 0x2
|
||||
beq _08070C56
|
||||
adds r0, r5, 0
|
||||
adds r0, 0xC8
|
||||
ldrb r0, [r0]
|
||||
cmp r0, 0x2
|
||||
beq _08070C56
|
||||
cmp r1, 0x1
|
||||
beq _08070C56
|
||||
ldrb r0, [r4]
|
||||
cmp r0, 0x7
|
||||
beq _08070C56
|
||||
cmp r0, 0x3
|
||||
beq _08070C56
|
||||
movs r0, 0x1
|
||||
b _08070C58
|
||||
_08070C56:
|
||||
movs r0, 0
|
||||
_08070C58:
|
||||
pop {r4-r6}
|
||||
pop {r1}
|
||||
bx r1
|
||||
thumb_func_end sub_8070BC0
|
||||
|
||||
.align 2, 0
|
||||
@@ -4,5 +4,10 @@
|
||||
#include "dungeon_entity.h"
|
||||
|
||||
bool8 CannotMove(struct Entity *pokemon, bool8 checkBlinker);
|
||||
bool8 sub_8070BC0(struct Entity* entity);
|
||||
bool8 CannotUseItems(struct Entity *pokemon);
|
||||
bool8 HasStatusThatPreventsActing(struct Entity *pokemon);
|
||||
bool8 CannotAttack(struct Entity *pokemon, bool8 skipSleep);
|
||||
bool8 CanMoveInDirection(struct Entity *pokemon, u32 direction);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef GUARD_DUNGEON_CAPABILITIES_1_H
|
||||
#define GUARD_DUNGEON_CAPABILITIES_1_H
|
||||
|
||||
#include "dungeon_entity.h"
|
||||
|
||||
bool8 CannotUseItems(struct Entity *pokemon);
|
||||
bool8 HasStatusThatPreventsActing(struct Entity *pokemon);
|
||||
bool8 CannotAttack(struct Entity *pokemon, bool8 skipSleep);
|
||||
bool8 CanMoveInDirection(struct Entity *pokemon, u32 direction);
|
||||
|
||||
#endif
|
||||
@@ -221,8 +221,6 @@ SECTIONS {
|
||||
src/dungeon_movement.o(.text);
|
||||
src/status_checks_1.o(.text);
|
||||
src/dungeon_capabilities.o(.text);
|
||||
asm/code_8070BC0.o(.text);
|
||||
src/dungeon_capabilities_1.o(.text);
|
||||
src/dungeon_ai_targeting.o(.text);
|
||||
src/dungeon_pokemon_attributes.o(.text);
|
||||
asm/code_80718D8.o(.text);
|
||||
@@ -462,7 +460,7 @@ SECTIONS {
|
||||
data/data_8106A4C.o(.rodata);
|
||||
src/type_effectiveness.o(.data);
|
||||
data/data_8106F7C.o(.rodata);
|
||||
src/dungeon_capabilities_1.o(.rodata);
|
||||
src/dungeon_capabilities.o(.rodata);
|
||||
src/dungeon_ai_targeting.o(.rodata);
|
||||
data/data_8107010.o(.rodata);
|
||||
src/friend_area.o(.rodata);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "dungeon_ai_items.h"
|
||||
#include "dungeon_ai_movement.h"
|
||||
#include "dungeon_ai_targeting.h"
|
||||
#include "dungeon_capabilities_1.h"
|
||||
#include "dungeon_capabilities.h"
|
||||
#include "dungeon_global_data.h"
|
||||
#include "dungeon_items.h"
|
||||
#include "dungeon_leader.h"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "dungeon_action.h"
|
||||
#include "dungeon_ai_targeting.h"
|
||||
#include "dungeon_ai_targeting.h"
|
||||
#include "dungeon_capabilities_1.h"
|
||||
#include "dungeon_capabilities.h"
|
||||
#include "dungeon_global_data.h"
|
||||
#include "dungeon_map_access.h"
|
||||
#include "dungeon_pokemon_attributes.h"
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "dungeon_ai_items.h"
|
||||
#include "dungeon_ai_targeting.h"
|
||||
#include "dungeon_capabilities.h"
|
||||
#include "dungeon_capabilities_1.h"
|
||||
#include "dungeon_entity.h"
|
||||
#include "dungeon_global_data.h"
|
||||
#include "dungeon_map_access.h"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "dungeon_action.h"
|
||||
#include "dungeon_ai_leader.h"
|
||||
#include "dungeon_ai_targeting.h"
|
||||
#include "dungeon_capabilities_1.h"
|
||||
#include "dungeon_capabilities.h"
|
||||
#include "dungeon_global_data.h"
|
||||
#include "dungeon_map_access.h"
|
||||
#include "dungeon_movement.h"
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
#include "global.h"
|
||||
#include "dungeon_capabilities.h"
|
||||
|
||||
#include "constants/dungeon.h"
|
||||
#include "constants/iq_skill.h"
|
||||
#include "constants/status.h"
|
||||
#include "charge_move.h"
|
||||
#include "dungeon_ai_targeting.h"
|
||||
#include "dungeon_capabilities.h"
|
||||
#include "dungeon_engine.h"
|
||||
#include "dungeon_items.h"
|
||||
#include "dungeon_map_access.h"
|
||||
#include "dungeon_movement.h"
|
||||
#include "dungeon_pokemon_attributes.h"
|
||||
#include "dungeon_util.h"
|
||||
#include "map.h"
|
||||
|
||||
const u8 gDirectionBitMasks_1[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
|
||||
|
||||
bool8 CannotMove(struct Entity *pokemon, bool8 checkBlinker)
|
||||
{
|
||||
struct EntityInfo *pokemonInfo = pokemon->info;
|
||||
|
||||
if ((checkBlinker && pokemonInfo->eyesightStatus == STATUS_BLINKER)
|
||||
|| pokemonInfo->sleep == STATUS_SLEEP
|
||||
|| pokemonInfo->sleep == STATUS_NAPPING
|
||||
@@ -13,13 +28,143 @@ bool8 CannotMove(struct Entity *pokemon, bool8 checkBlinker)
|
||||
|| pokemonInfo->volatileStatus == STATUS_PAUSED
|
||||
|| pokemonInfo->volatileStatus == STATUS_INFATUATED
|
||||
|| pokemonInfo->immobilizeStatus == STATUS_PETRIFIED)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (pokemonInfo->terrifiedTurns != 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 sub_8070BC0(struct Entity* entity)
|
||||
{
|
||||
struct EntityInfo *entityInfo = entity->info;
|
||||
|
||||
if (IsCharging(entity, FALSE)
|
||||
|| entityInfo->sleep == STATUS_YAWNING
|
||||
|| entityInfo->sleep == STATUS_NIGHTMARE
|
||||
|| ShouldMonsterRunAway(entity)
|
||||
|| entityInfo->muzzled == TRUE
|
||||
|| entityInfo->immobilizeStatus == STATUS_PETRIFIED
|
||||
|| entityInfo->immobilizeStatus == STATUS_FROZEN)
|
||||
return FALSE;
|
||||
|
||||
if (entityInfo->volatileStatus == STATUS_CONFUSED)
|
||||
return FALSE;
|
||||
if (entityInfo->sleep == STATUS_SLEEP)
|
||||
return FALSE;
|
||||
if (entityInfo->transformStatus == STATUS_INVISIBLE
|
||||
|| entityInfo->sleep == STATUS_NAPPING)
|
||||
return FALSE;
|
||||
if (entityInfo->volatileStatus == STATUS_CRINGE)
|
||||
return FALSE;
|
||||
if (entityInfo->immobilizeStatus == STATUS_WRAP)
|
||||
return FALSE;
|
||||
if (entityInfo->immobilizeStatus == STATUS_WRAPPED
|
||||
|| entityInfo->eyesightStatus == STATUS_CROSS_EYED)
|
||||
return FALSE;
|
||||
if (entityInfo->waitingStatus == STATUS_DECOY)
|
||||
return FALSE;
|
||||
if (entityInfo->eyesightStatus == STATUS_BLINKER)
|
||||
return FALSE;
|
||||
if (entityInfo->volatileStatus != STATUS_INFATUATED
|
||||
&& entityInfo->volatileStatus != STATUS_PAUSED)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline bool8 JoinLocationCannotUseItems(struct EntityInfo *pokemonInfo)
|
||||
{
|
||||
if (pokemonInfo->joinedAt == DUNGEON_JOIN_LOCATION_CLIENT_POKEMON)
|
||||
return TRUE;
|
||||
if (pokemonInfo->joinedAt == DUNGEON_RESCUE_TEAM_BASE)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 CannotUseItems(struct Entity *pokemon)
|
||||
{
|
||||
struct EntityInfo *pokemonInfo = pokemon->info;
|
||||
|
||||
if (pokemonInfo->clientType == CLIENT_TYPE_CLIENT
|
||||
|| JoinLocationCannotUseItems(pokemonInfo)
|
||||
|| (!pokemonInfo->isTeamLeader && ShouldMonsterRunAway(pokemon))
|
||||
|| CannotMove(pokemon, FALSE)
|
||||
|| HasStatusThatPreventsActing(pokemon))
|
||||
return TRUE;
|
||||
|
||||
if (IsCharging(pokemon, FALSE))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 HasStatusThatPreventsActing(struct Entity *pokemon)
|
||||
{
|
||||
struct EntityInfo *pokemonInfo = pokemon->info;
|
||||
|
||||
if ((pokemonInfo->sleep != STATUS_SLEEPLESS
|
||||
&& pokemonInfo->sleep != STATUS_NONE)
|
||||
|| pokemonInfo->immobilizeStatus == STATUS_FROZEN
|
||||
|| pokemonInfo->immobilizeStatus == STATUS_PETRIFIED)
|
||||
return TRUE;
|
||||
|
||||
if (pokemonInfo->chargingStatus == STATUS_BIDE)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 CannotAttack(struct Entity *pokemon, bool8 skipSleep)
|
||||
{
|
||||
struct EntityInfo *pokemonInfo = pokemon->info;
|
||||
|
||||
if ((skipSleep ||
|
||||
pokemonInfo->sleep == STATUS_SLEEPLESS ||
|
||||
pokemonInfo->sleep == STATUS_YAWNING ||
|
||||
pokemonInfo->sleep == STATUS_NONE) &&
|
||||
pokemonInfo->immobilizeStatus != STATUS_FROZEN &&
|
||||
pokemonInfo->immobilizeStatus != STATUS_WRAP &&
|
||||
pokemonInfo->immobilizeStatus != STATUS_WRAPPED &&
|
||||
pokemonInfo->immobilizeStatus != STATUS_PETRIFIED &&
|
||||
pokemonInfo->volatileStatus != STATUS_CRINGE &&
|
||||
pokemonInfo->volatileStatus != STATUS_PAUSED &&
|
||||
pokemonInfo->volatileStatus != STATUS_INFATUATED &&
|
||||
pokemonInfo->nonVolatileStatus != STATUS_PARALYSIS &&
|
||||
!ShouldMonsterRunAway(pokemon))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool8 CanMoveInDirection(struct Entity *pokemon, u32 direction)
|
||||
{
|
||||
u8 crossableTerrain = GetCrossableTerrain(pokemon->info->id);
|
||||
struct Tile *currentMapTile = GetTile(pokemon->pos.x + gAdjacentTileOffsets[direction].x,
|
||||
pokemon->pos.y + gAdjacentTileOffsets[direction].y);
|
||||
|
||||
if (currentMapTile->terrainType & TERRAIN_TYPE_IMPASSABLE_WALL || currentMapTile->monster != NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!IsCurrentFixedRoomBossFight())
|
||||
{
|
||||
if (pokemon->info->transformStatus == STATUS_MOBILE || HasHeldItem(pokemon, ITEM_MOBILE_SCARF))
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
if (direction & 1)
|
||||
// Super Mobile can't break walls diagonally.
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
else
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
}
|
||||
|
||||
currentMapTile = GetTile(pokemon->pos.x, pokemon->pos.y);
|
||||
if (!(currentMapTile->walkableNeighborFlags[crossableTerrain] & gDirectionBitMasks_1[direction & DIRECTION_MASK]))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
#include "global.h"
|
||||
#include "dungeon_capabilities_1.h"
|
||||
|
||||
#include "constants/dungeon.h"
|
||||
#include "constants/iq_skill.h"
|
||||
#include "constants/status.h"
|
||||
#include "charge_move.h"
|
||||
#include "dungeon_ai_targeting.h"
|
||||
#include "dungeon_capabilities.h"
|
||||
#include "dungeon_engine.h"
|
||||
#include "dungeon_items.h"
|
||||
#include "dungeon_map_access.h"
|
||||
#include "dungeon_movement.h"
|
||||
#include "dungeon_pokemon_attributes.h"
|
||||
#include "dungeon_util.h"
|
||||
#include "map.h"
|
||||
|
||||
const u8 gDirectionBitMasks_1[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
|
||||
|
||||
static inline bool8 JoinLocationCannotUseItems(struct EntityInfo *pokemonInfo)
|
||||
{
|
||||
if (pokemonInfo->joinedAt == DUNGEON_JOIN_LOCATION_CLIENT_POKEMON)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (pokemonInfo->joinedAt == DUNGEON_RESCUE_TEAM_BASE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 CannotUseItems(struct Entity *pokemon)
|
||||
{
|
||||
struct EntityInfo *pokemonInfo = pokemon->info;
|
||||
if (pokemonInfo->clientType == CLIENT_TYPE_CLIENT
|
||||
|| JoinLocationCannotUseItems(pokemonInfo)
|
||||
|| (!pokemonInfo->isTeamLeader && ShouldMonsterRunAway(pokemon))
|
||||
|| CannotMove(pokemon, FALSE)
|
||||
|| HasStatusThatPreventsActing(pokemon))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (IsCharging(pokemon, FALSE))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 HasStatusThatPreventsActing(struct Entity *pokemon)
|
||||
{
|
||||
struct EntityInfo *pokemonInfo = pokemon->info;
|
||||
if ((pokemonInfo->sleep != STATUS_SLEEPLESS
|
||||
&& pokemonInfo->sleep != STATUS_NONE)
|
||||
|| pokemonInfo->immobilizeStatus == STATUS_FROZEN
|
||||
|| pokemonInfo->immobilizeStatus == STATUS_PETRIFIED)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (pokemonInfo->chargingStatus == STATUS_BIDE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 CannotAttack(struct Entity *pokemon, bool8 skipSleep)
|
||||
{
|
||||
struct EntityInfo *pokemonInfo = pokemon->info;
|
||||
if ((skipSleep ||
|
||||
pokemonInfo->sleep == STATUS_SLEEPLESS ||
|
||||
pokemonInfo->sleep == STATUS_YAWNING ||
|
||||
pokemonInfo->sleep == STATUS_NONE) &&
|
||||
pokemonInfo->immobilizeStatus != STATUS_FROZEN &&
|
||||
pokemonInfo->immobilizeStatus != STATUS_WRAP &&
|
||||
pokemonInfo->immobilizeStatus != STATUS_WRAPPED &&
|
||||
pokemonInfo->immobilizeStatus != STATUS_PETRIFIED &&
|
||||
pokemonInfo->volatileStatus != STATUS_CRINGE &&
|
||||
pokemonInfo->volatileStatus != STATUS_PAUSED &&
|
||||
pokemonInfo->volatileStatus != STATUS_INFATUATED &&
|
||||
pokemonInfo->nonVolatileStatus != STATUS_PARALYSIS &&
|
||||
!ShouldMonsterRunAway(pokemon)) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool8 CanMoveInDirection(struct Entity *pokemon, u32 direction)
|
||||
{
|
||||
u8 crossableTerrain = GetCrossableTerrain(pokemon->info->id);
|
||||
struct Tile *currentMapTile = GetTile(pokemon->pos.x + gAdjacentTileOffsets[direction].x,
|
||||
pokemon->pos.y + gAdjacentTileOffsets[direction].y);
|
||||
if (currentMapTile->terrainType & TERRAIN_TYPE_IMPASSABLE_WALL || currentMapTile->monster != NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!IsCurrentFixedRoomBossFight())
|
||||
{
|
||||
if (pokemon->info->transformStatus == STATUS_MOBILE || HasHeldItem(pokemon, ITEM_MOBILE_SCARF))
|
||||
{
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
{
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
{
|
||||
if (direction & 1)
|
||||
{
|
||||
// Super Mobile can't break walls diagonally.
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
else
|
||||
{
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
currentMapTile = GetTile(pokemon->pos.x, pokemon->pos.y);
|
||||
if (!(currentMapTile->walkableNeighborFlags[crossableTerrain] & gDirectionBitMasks_1[direction & DIRECTION_MASK]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "dungeon_ai_items.h"
|
||||
#include "dungeon_ai_movement.h"
|
||||
#include "dungeon_ai_targeting.h"
|
||||
#include "dungeon_capabilities_1.h"
|
||||
#include "dungeon_capabilities.h"
|
||||
#include "dungeon_global_data.h"
|
||||
#include "dungeon_items.h"
|
||||
#include "dungeon_leader.h"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "charge_move.h"
|
||||
#include "dungeon_action.h"
|
||||
#include "dungeon_ai_attack.h"
|
||||
#include "dungeon_capabilities_1.h"
|
||||
#include "dungeon_capabilities.h"
|
||||
#include "dungeon_random.h"
|
||||
|
||||
const s16 gConfusedAttackChance = 70;
|
||||
|
||||
Reference in New Issue
Block a user