mirror of
https://github.com/pret/pmd-red.git
synced 2026-04-22 23:17:44 -05:00
868 lines
25 KiB
C
868 lines
25 KiB
C
#include "global.h"
|
|
#include "globaldata.h"
|
|
#include "trap.h"
|
|
#include "dungeon_tilemap.h"
|
|
#include "dungeon_8041AD0.h"
|
|
#include "dungeon_message.h"
|
|
#include "dungeon_random.h"
|
|
#include "dungeon_mon_sprite_render.h"
|
|
#include "constants/dungeon_exit.h"
|
|
#include "constants/residual_damage.h"
|
|
#include "constants/trap.h"
|
|
#include "constants/type.h"
|
|
#include "run_dungeon.h"
|
|
#include "dungeon_items.h"
|
|
#include "dungeon_map.h"
|
|
#include "dungeon_map_access.h"
|
|
#include "dungeon_logic.h"
|
|
#include "dungeon_random.h"
|
|
#include "dungeon_util.h"
|
|
#include "dungeon_vram.h"
|
|
#include "dungeon_floor_spawns.h"
|
|
#include "items.h"
|
|
#include "move_orb_effects_1.h"
|
|
#include "moves.h"
|
|
#include "structs/map.h"
|
|
#include "structs/str_dungeon.h"
|
|
#include "dungeon_config.h"
|
|
#include "dungeon_misc.h"
|
|
#include "dungeon_strings.h"
|
|
#include "sprite.h"
|
|
#include "dungeon_pos_data.h"
|
|
#include "dungeon_damage.h"
|
|
#include "dungeon_leveling.h"
|
|
#include "warp_target.h"
|
|
#include "blow_away.h"
|
|
#include "explosion.h"
|
|
#include "dungeon_mon_spawn.h"
|
|
#include "move_orb_actions_1.h"
|
|
#include "move_orb_effects_2.h"
|
|
#include "move_orb_effects_4.h"
|
|
|
|
void sub_807FA18(void)
|
|
{
|
|
s32 x, y;
|
|
|
|
for (y = 0; y < DUNGEON_MAX_SIZE_Y; y++) {
|
|
for (x = 0; x < DUNGEON_MAX_SIZE_X; x++) {
|
|
Tile *tile = GetTileMut(x, y);
|
|
|
|
if (tile->spawnOrVisibilityFlags.spawn & SPAWN_FLAG_TRAP) {
|
|
s32 trapId;
|
|
DungeonPos pos = {x, y};
|
|
|
|
if (tile->spawnOrVisibilityFlags.spawn & SPAWN_FLAG_UNK6) {
|
|
trapId = TRAP_WARP_TRAP;
|
|
}
|
|
else {
|
|
trapId = GetRandomFloorTrap();
|
|
}
|
|
|
|
if (trapId == TRAP_WONDER_TILE) {
|
|
Entity *trap = SpawnTrap(trapId, &pos, 2);
|
|
if (trap != NULL) {
|
|
tile->object = trap;
|
|
trap->isVisible = TRUE;
|
|
}
|
|
}
|
|
else {
|
|
Entity *trap = SpawnTrap(trapId, &pos, 0);
|
|
if (trap != NULL) {
|
|
tile->object = trap;
|
|
trap->isVisible = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_807FA9C(void)
|
|
{
|
|
s32 x, y;
|
|
bool8 showInvisibles = gDungeon->unk181e8.showInvisibleTrapsMonsters;
|
|
|
|
for (y = gDungeon->unk181e8.cameraPos.y - 5; y < gDungeon->unk181e8.cameraPos.y + 5; y++) {
|
|
for (x = gDungeon->unk181e8.cameraPos.x - 6; x < gDungeon->unk181e8.cameraPos.x + 6; x++) {
|
|
bool8 r6 = FALSE;
|
|
const Tile *tile = GetTile(x, y);
|
|
|
|
if (tile->object != NULL && GetEntityType(tile->object) == ENTITY_TRAP && (tile->object->isVisible || showInvisibles)) {
|
|
r6 = TRUE;
|
|
}
|
|
if (tile->terrainFlags & TERRAIN_TYPE_STAIRS) {
|
|
r6 = TRUE;
|
|
}
|
|
|
|
if (r6) {
|
|
s32 spriteX = (x * 24) - gDungeon->unk181e8.cameraPixelPos.x;
|
|
s32 spriteY = (y * 24) - gDungeon->unk181e8.cameraPixelPos.y;
|
|
if (spriteX >= -32 && spriteY >= -32 && spriteX <= 272 && spriteY <= 192) {
|
|
SpriteSetObjMode(&gUnknown_202EDC0, 0);
|
|
SpriteSetY(&gUnknown_202EDC0, spriteY);
|
|
SpriteSetX(&gUnknown_202EDC0, spriteX);
|
|
SpriteSetPriority(&gUnknown_202EDC0, 3);
|
|
SpriteSetPalNum(&gUnknown_202EDC0, 10);
|
|
SpriteSetTileNum(&gUnknown_202EDC0, 0x1FC);
|
|
|
|
AddSprite(&gUnknown_202EDC0, 0, NULL, NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_807FC3C(DungeonPos *pos, u32 trapID, u32 param_3)
|
|
{
|
|
gDungeon->trapPos.x = pos->x;
|
|
gDungeon->trapPos.y = pos->y;
|
|
gDungeon->trapID = trapID;
|
|
gDungeon->unk13579 = param_3;
|
|
gDungeon->unk13570 = 1;
|
|
}
|
|
|
|
bool8 CanLayTrap(DungeonPos *pos)
|
|
{
|
|
Tile *tile = GetTileMut(pos->x, pos->y);
|
|
if (tile->terrainFlags & TERRAIN_TYPE_STAIRS)
|
|
return FALSE;
|
|
|
|
if (tile->room == CORRIDOR_ROOM)
|
|
return FALSE;
|
|
|
|
if (tile->terrainFlags & TERRAIN_TYPE_NATURAL_JUNCTION)
|
|
return FALSE;
|
|
|
|
if (tile->terrainFlags & TERRAIN_TYPE_SHOP)
|
|
return FALSE;
|
|
|
|
if (GetTerrainType(tile) != TERRAIN_TYPE_NORMAL)
|
|
return FALSE;
|
|
|
|
if (tile->object != NULL) {
|
|
if (GetEntityType(tile->object) != ENTITY_TRAP)
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
bool8 LayTrap(DungeonPos *pos, u8 trapID, u8 param_3)
|
|
{
|
|
Tile *tile;
|
|
Entity *entity;
|
|
s32 counter;
|
|
u16 terrainFlags;
|
|
|
|
tile = GetTileMut(pos->x, pos->y);
|
|
if (TRAP_SPIKE_TRAP < trapID) {
|
|
counter = 0;
|
|
while ((counter < 0x1e && (trapID = GetRandomFloorTrap(), trapID == TRAP_WONDER_TILE))) {
|
|
counter++;
|
|
}
|
|
if (counter == 0x1e) {
|
|
trapID = TRAP_CHESTNUT_TRAP;
|
|
}
|
|
}
|
|
terrainFlags = tile->terrainFlags;
|
|
if ((terrainFlags & TERRAIN_TYPE_STAIRS) != 0) goto _0807FD6E;
|
|
if (tile->room == CORRIDOR_ROOM) goto _0807FD6E;
|
|
if ((terrainFlags & TERRAIN_TYPE_NATURAL_JUNCTION) != 0) goto _0807FD6E;
|
|
if ((terrainFlags & TERRAIN_TYPE_SHOP) != 0) goto _0807FD6E;
|
|
if (((terrainFlags & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) != TERRAIN_TYPE_NORMAL)) goto _0807FD6E;
|
|
if (tile->object != NULL) {
|
|
if (GetEntityType(tile->object) != ENTITY_TRAP) goto _0807FD6E;
|
|
GetTrapInfo(tile->object)->id = trapID;
|
|
GetTrapInfo(tile->object)->unk1 = param_3;
|
|
tile->object->isVisible = TRUE;
|
|
}
|
|
else {
|
|
entity = SpawnTrap(trapID,pos,param_3);
|
|
if (entity == NULL)
|
|
_0807FD6E:
|
|
return FALSE;
|
|
else
|
|
{
|
|
tile->object = entity;
|
|
tile->object->isVisible = TRUE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
bool8 sub_807FD84(Entity *entity)
|
|
{
|
|
bool8 flag;
|
|
flag = FALSE;
|
|
|
|
if (gDungeon->unk13570 == 0) {
|
|
return FALSE;
|
|
}
|
|
else {
|
|
gDungeon->unk13570 = 0;
|
|
flag = LayTrap(&gDungeon->trapPos,gDungeon->trapID,gDungeon->unk13579);
|
|
if (flag) {
|
|
LogMessageByIdWithPopupCheckUserUnknown_Async(entity,&gDungeon->trapPos,gUnknown_80FC5F8); // A trap was laid!
|
|
}
|
|
else {
|
|
LogMessageByIdWithPopupCheckUserUnknown_Async(entity,&gDungeon->trapPos,gUnknown_80FC5FC); // A trap can't be laid here.
|
|
}
|
|
UpdateTrapsVisibility();
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
bool8 sub_807FE04(DungeonPos *pos, u8 param_2)
|
|
{
|
|
Tile *tile;
|
|
|
|
tile = GetTileMut(pos->x,pos->y);
|
|
if ((tile->object != NULL) && (GetEntityType(tile->object) == ENTITY_TRAP)) {
|
|
tile->object->type = 0;
|
|
tile->object = NULL;
|
|
if (param_2 != 0) {
|
|
UpdateTrapsVisibility();
|
|
}
|
|
return TRUE;
|
|
}
|
|
else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
bool8 sub_807FE44(DungeonPos *pos, u8 param_2)
|
|
{
|
|
const Tile *tile;
|
|
|
|
tile = GetTile(pos->x,pos->y);
|
|
if ((tile->object != NULL) && (GetEntityType(tile->object) == ENTITY_TRAP)) {
|
|
tile->object->isVisible = TRUE;
|
|
if (param_2 != 0) {
|
|
UpdateTrapsVisibility();
|
|
}
|
|
return TRUE;
|
|
}
|
|
else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
void GetTrapName(u8 *buffer, u8 trapIndex)
|
|
{
|
|
strcpy(buffer, gTrapNames[trapIndex]);
|
|
}
|
|
|
|
void TryTriggerTrap(Entity *pokemon, DungeonPos *pos, s32 param_3, u8 param_4)
|
|
{
|
|
Tile *tile;
|
|
bool8 flag1;
|
|
bool8 flag;
|
|
|
|
Entity *entity;
|
|
s32 rand;
|
|
Trap *trapData;
|
|
Entity *target;
|
|
const u8 *text;
|
|
|
|
tile = GetTileMut(pos->x,pos->y);
|
|
entity = tile->object;
|
|
flag1 = FALSE;
|
|
if (entity == NULL) {
|
|
return;
|
|
}
|
|
if (GetEntityType(entity) != ENTITY_TRAP) {
|
|
return;
|
|
}
|
|
trapData = GetTrapInfo(entity);
|
|
GetTrapName(gFormatBuffer_Monsters[0],trapData->id);
|
|
target = tile->monster;
|
|
if ((target != NULL) && (GetEntityType(target) != ENTITY_MONSTER)) {
|
|
target = NULL;
|
|
}
|
|
flag = entity->isVisible;
|
|
entity->isVisible = TRUE;
|
|
if (((target != NULL) && (sub_806A1E8(target), param_4 != '\0')) && (trapData->id != TRAP_WONDER_TILE)) {
|
|
rand = DungeonRandInt(100);
|
|
text = NULL;
|
|
if (HasHeldItem(target, ITEM_TRAP_SCARF)) {
|
|
text = gUnknown_80FDB5C;
|
|
}
|
|
if ((flag == TRUE) || (gDungeon->unk181e8.showInvisibleTrapsMonsters != 0)) {
|
|
if (rand < 0) text = gUnknown_80FDB7C;
|
|
}
|
|
else if (rand < 0xf) {
|
|
text = gUnknown_80FDB7C;
|
|
}
|
|
if (text != NULL) {
|
|
if (sub_803F428(pos)) {
|
|
UpdateTrapsVisibility();
|
|
}
|
|
TryDisplayDungeonLoggableMessage3_Async(pokemon,target,text);
|
|
if (param_3 == 0) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (sub_803F428(pos)) {
|
|
sub_80421C0(0,0x15c);
|
|
UpdateTrapsVisibility();
|
|
sub_804225C(pokemon,pos,trapData->id);
|
|
if (gDungeon->unk181e8.blinded) {
|
|
LogMessageByIdWithPopupCheckUser_Async(pokemon,gUnknown_80FD7F4);
|
|
}
|
|
else {
|
|
LogMessageByIdWithPopupCheckUser_Async(pokemon,gSteppedOnTrapStrings[trapData->id]);
|
|
}
|
|
}
|
|
if (target != NULL) {
|
|
if (trapData->unk1 == 2) {
|
|
sub_806F480(target,TRUE);
|
|
}
|
|
else if (trapData->unk1 == 1) {
|
|
sub_806F480(target,FALSE);
|
|
}
|
|
}
|
|
switch(trapData->id) {
|
|
case TRAP_TRIP_TRAP:
|
|
HandleTripTrap(pokemon,target);
|
|
break;
|
|
case TRAP_MUD_TRAP:
|
|
HandleMudTrap(pokemon,target);
|
|
break;
|
|
case TRAP_STICKY_TRAP:
|
|
HandleStickyTrap(pokemon,target);
|
|
break;
|
|
case TRAP_GRIMY_TRAP:
|
|
HandleGrimyTrap(pokemon,target);
|
|
break;
|
|
case TRAP_SUMMON_TRAP:
|
|
HandleSummonTrap(pokemon,pos);
|
|
flag1 = TRUE;
|
|
break;
|
|
case TRAP_PITFALL_TRAP:
|
|
case 0x1B: // ???
|
|
HandlePitfallTrap(pokemon,target,tile);
|
|
break;
|
|
case TRAP_WARP_TRAP:
|
|
HandleWarpTrap(pokemon,target);
|
|
break;
|
|
case TRAP_WHIRLWIND_TRAP:
|
|
HandleWhirlwindTrap(entity,target);
|
|
break;
|
|
case TRAP_SPIN_TRAP:
|
|
HandleSpinTrap(pokemon,target);
|
|
break;
|
|
case TRAP_SLUMBER_TRAP:
|
|
HandleSlumberTrap(pokemon,target);
|
|
break;
|
|
case TRAP_SLOW_TRAP:
|
|
HandleSlowTrap(pokemon,target);
|
|
break;
|
|
case TRAP_SEAL_TRAP:
|
|
HandleSealTrap(pokemon,target);
|
|
break;
|
|
case TRAP_POISON_TRAP:
|
|
HandlePoisonTrap(pokemon,target);
|
|
break;
|
|
case TRAP_SELFDESTRUCT_TRAP:
|
|
HandleSelfdestructTrap(pokemon,target);
|
|
break;
|
|
case TRAP_EXPLOSION_TRAP:
|
|
HandleExplosionTrap(pokemon,target);
|
|
break;
|
|
case TRAP_PP_ZERO_TRAP:
|
|
HandlePPZeroTrap(pokemon,target);
|
|
break;
|
|
case TRAP_CHESTNUT_TRAP:
|
|
if (target != NULL) {
|
|
DealDamageToEntity_Async(target,gChestnutTrapDmgValue,RESIDUAL_DAMAGE_CHESTNUT_TRAP,DUNGEON_EXIT_TRIPPED_CHESTNUT_TRAP);
|
|
}
|
|
break;
|
|
case TRAP_WONDER_TILE:
|
|
HandleWonderTile(pokemon,target);
|
|
break;
|
|
case TRAP_POKEMON_TRAP:
|
|
HandlePokemonTrap(pokemon,pos);
|
|
flag1 = TRUE;
|
|
break;
|
|
case TRAP_SPIKE_TRAP:
|
|
if (target != NULL) {
|
|
DealDamageToEntity_Async(target,gSpikeTrapDmgValue,RESIDUAL_DAMAGE_SPIKES,DUNGEON_EXIT_FAINTED_FROM_SPIKES);
|
|
}
|
|
}
|
|
if (EntityIsValid(target)) {
|
|
EnemyEvolution(target);
|
|
}
|
|
if (flag1) {
|
|
sub_807FE04(pos,1);
|
|
}
|
|
}
|
|
|
|
void HandleMudTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
s32 rand, randDef;
|
|
|
|
if (target == NULL)
|
|
return;
|
|
|
|
rand = DungeonRandInt(100);
|
|
randDef = rand;
|
|
if (rand < 25) {
|
|
LowerOffensiveStat(pokemon,target,gStatIndexAtkDef,1,1,1);
|
|
}
|
|
else if (rand < 50) {
|
|
LowerOffensiveStat(pokemon,target,gStatIndexSpecial,1,1,1);
|
|
}
|
|
else if (randDef < 75) {
|
|
LowerDefensiveStat(pokemon,target,gStatIndexAtkDef,1,1,1);
|
|
}
|
|
else {
|
|
LowerDefensiveStat(pokemon,target,gStatIndexSpecial,1,1,1);
|
|
}
|
|
}
|
|
|
|
void HandleStickyTrap(Entity *pokemon,Entity *target)
|
|
{
|
|
EntityInfo *info;
|
|
s32 index;
|
|
s32 itemCount;
|
|
s32 newIndex;
|
|
Item *itemStack[21];
|
|
|
|
info = GetEntInfo(target);
|
|
if (HasHeldItem(target,0xe)) {
|
|
TryDisplayDungeonLoggableMessage3_Async(pokemon,target,gUnknown_80FDC7C);
|
|
}
|
|
else
|
|
{
|
|
itemCount = 0;
|
|
if (info->isTeamLeader) {
|
|
for (index = 0; index < INVENTORY_SIZE; index++) {
|
|
if (ItemExists(&gTeamInventoryRef->teamItems[index]) && IsNotSpecialItem(gTeamInventoryRef->teamItems[index].id)) {
|
|
Item *item = &gTeamInventoryRef->teamItems[index];
|
|
if (!ItemSticky(item)) {
|
|
itemStack[itemCount] = item;
|
|
itemCount++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (ItemExists(&info->heldItem) && IsNotSpecialItem((info->heldItem).id) && !ItemSticky(&info->heldItem)) {
|
|
itemStack[itemCount] = &info->heldItem;
|
|
itemCount++;
|
|
}
|
|
|
|
if (itemCount == 0) {
|
|
TryDisplayDungeonLoggableMessage3_Async(pokemon,target,gUnknown_80FDC40);
|
|
}
|
|
else {
|
|
newIndex = DungeonRandInt(itemCount);
|
|
sub_8045BF8(gFormatBuffer_Items[0], itemStack[newIndex]);
|
|
itemStack[newIndex]->flags |= ITEM_FLAG_STICKY;
|
|
sub_80421C0(target, 0x192);
|
|
TryDisplayDungeonLoggableMessage3_Async(pokemon,target,gUnknown_80FDC18);
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleSpinTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
if(target != NULL)
|
|
ConfuseStatusTarget(pokemon, target, TRUE);
|
|
}
|
|
|
|
void HandleWarpTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
if(target != NULL)
|
|
WarpTarget(pokemon, target, 0, NULL);
|
|
}
|
|
|
|
void HandleSlumberTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
s32 turns;
|
|
|
|
if(target != NULL)
|
|
{
|
|
turns = CalculateStatusTurns(target, gSleepTurnRange, TRUE);
|
|
SleepStatusTarget(pokemon, target, turns, TRUE);
|
|
}
|
|
}
|
|
|
|
void HandleSlowTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
if(target != NULL)
|
|
LowerSpeed(pokemon, target, 1, TRUE);
|
|
}
|
|
|
|
void HandlePoisonTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
if(target != NULL)
|
|
PoisonedStatusTarget(pokemon, target, TRUE);
|
|
}
|
|
|
|
void HandleSelfdestructTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
HandleExplosion(pokemon, target, &target->pos, 1, TYPE_NONE, DUNGEON_EXIT_DISAPPEARED_IN_EXPLOSION);
|
|
}
|
|
|
|
void HandleExplosionTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
HandleExplosion(pokemon, target, &target->pos, 2, TYPE_NONE, DUNGEON_EXIT_DISAPPEARED_IN_EXPLOSION);
|
|
}
|
|
|
|
void HandleGrimyTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
Item *item;
|
|
Item *heldItem;
|
|
s32 counter;
|
|
s32 index;
|
|
EntityInfo *info;
|
|
s32 badFoodCount;
|
|
Item *itemStack [22];
|
|
|
|
badFoodCount = 0;
|
|
if (target != NULL) {
|
|
info = GetEntInfo(target);
|
|
counter = 0;
|
|
if (info->isTeamLeader) {
|
|
for(index = 0; index < INVENTORY_SIZE; index++)
|
|
{
|
|
item = &gTeamInventoryRef->teamItems[index];
|
|
if ((item->flags & ITEM_FLAG_EXISTS)) {
|
|
itemStack[counter] = item;
|
|
counter++;
|
|
}
|
|
}
|
|
}
|
|
heldItem = &info->heldItem;
|
|
if ((heldItem->flags & ITEM_FLAG_EXISTS)) {
|
|
itemStack[counter] = heldItem;
|
|
counter++;
|
|
}
|
|
for (index = 0; index < counter; index++) {
|
|
if (((GetItemCategory(itemStack[index]->id) == CATEGORY_FOOD_GUMMIES) && (itemStack[index]->id != ITEM_GRIMY_FOOD)) &&
|
|
(DungeonRandInt(100) < gGrimyTrapActivateChance)) {
|
|
badFoodCount++;
|
|
CreateItemWithStickyChance(itemStack[index], ITEM_GRIMY_FOOD, 2);
|
|
}
|
|
}
|
|
if (badFoodCount == 1) {
|
|
TryDisplayDungeonLoggableMessage3_Async(pokemon,target,gUnknown_80FD788); // A food item went bad.
|
|
}
|
|
else if (badFoodCount == 0) {
|
|
TryDisplayDungeonLoggableMessage3_Async(pokemon,target,gUnknown_80FD7D4); // Nothing particularly bad happened.
|
|
}
|
|
else
|
|
{
|
|
TryDisplayDungeonLoggableMessage3_Async(pokemon,target,gUnknown_80FD7AC); // Several food items went bad
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandlePitfallTrap(Entity *pokemon, Entity *target, Tile *tile)
|
|
{
|
|
bool8 flag;
|
|
EntityInfo *info;
|
|
|
|
flag = FALSE;
|
|
if (target != NULL) {
|
|
if (IsFloorwideFixedRoom()) {
|
|
LogMessageByIdWithPopupCheckUser_Async(pokemon,gUnknown_80FED0C); // But nothing happened...
|
|
}
|
|
else
|
|
{
|
|
info = GetEntInfo(target);
|
|
if (ShouldDisplayEntity(target)) {
|
|
SetTrap(tile, 0x1B);
|
|
flag = TRUE;
|
|
sub_80421C0(target,0x193);
|
|
DungeonWaitFrames_Async(0x1e,0x48);
|
|
}
|
|
if (info->isTeamLeader) {
|
|
if (GetFloorType() != 2) {
|
|
info->unk15C = 1;
|
|
info->unk15E = 1;
|
|
DungeonWaitFrames_Async(0x28,0x4b);
|
|
DealDamageToEntity_Async(target,gPitfallTrapDmgValue,RESIDUAL_DAMAGE_PITFALL,DUNGEON_EXIT_FELL_INTO_PITFALL);
|
|
gDungeon->unk2 = DUNGEON_UNK2_PITFALL_TRAP;
|
|
return;
|
|
}
|
|
LogMessageByIdWithPopupCheckUser_Async(pokemon,gUnknown_80F9728);
|
|
}
|
|
else
|
|
{
|
|
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],target,0);
|
|
if (info->isNotTeamMember) {
|
|
TryDisplayDungeonLoggableMessage3_Async(pokemon,target,gUnknown_80F970C); // $m0 fell into the pitfall!
|
|
}
|
|
else {
|
|
DisplayDungeonLoggableMessageTrue_Async(pokemon,gUnknown_80F970C); // $m0 fell into the pitfall!
|
|
}
|
|
HandleFaint_Async(target,DUNGEON_EXIT_FELL_INTO_PITFALL,pokemon);
|
|
}
|
|
if (flag) {
|
|
SetTrap(tile, TRAP_PITFALL_TRAP);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleSummonTrap(Entity *pokemon,DungeonPos *pos)
|
|
{
|
|
s32 r4;
|
|
u32 direction;
|
|
s32 pokemonSummonCount;
|
|
s16 species;
|
|
struct MonSpawnInfo stack;
|
|
s32 i;
|
|
|
|
|
|
r4 = DungeonRandInt(3) + 2;
|
|
direction = DungeonRandInt(NUM_DIRECTIONS);
|
|
if (IsFloorwideFixedRoom()) {
|
|
goto _ret;
|
|
}
|
|
else
|
|
{
|
|
pokemonSummonCount = 0;
|
|
if (pokemonSummonCount < r4) {
|
|
for (i = 0; i < r4; i++)
|
|
{
|
|
species = GetRandomFloorMonsterId(0);
|
|
direction &= DIRECTION_MASK;
|
|
stack.species = species;
|
|
if (sub_806AA0C(stack.species,0)) {
|
|
stack.level = 0;
|
|
stack.unk2 = 0;
|
|
stack.pos.x = pos->x + gAdjacentTileOffsets[direction].x;
|
|
stack.pos.y = pos->y + gAdjacentTileOffsets[direction].y;
|
|
stack.unk4 = 0;
|
|
stack.unk10 = 0;
|
|
if (SpawnWildMon(&stack, TRUE) != NULL) {
|
|
pokemonSummonCount++;
|
|
}
|
|
}
|
|
direction++;
|
|
}
|
|
}
|
|
sub_80421EC(pos,0x194);
|
|
if (pokemonSummonCount == 0) {
|
|
_ret:
|
|
LogMessageByIdWithPopupCheckUser_Async(pokemon,gUnknown_80FED04);
|
|
}
|
|
else
|
|
{
|
|
LogMessageByIdWithPopupCheckUser_Async(pokemon,gUnknown_80FED00);
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandlePPZeroTrap(Entity *param_1,Entity *param_2)
|
|
{
|
|
Move *move;
|
|
s32 moveIndex;
|
|
s32 i;
|
|
s32 counter;
|
|
EntityInfo *info;
|
|
Move *moveStack [MAX_MON_MOVES];
|
|
s32 indexStack [MAX_MON_MOVES];
|
|
bool8 flag = FALSE;
|
|
|
|
|
|
if (param_2 != NULL) {
|
|
info = GetEntInfo(param_2);
|
|
counter = 0;
|
|
for(i = 0; i < MAX_MON_MOVES; move++, i++)
|
|
{
|
|
move = &info->moves.moves[i];
|
|
if (((move->moveFlags & MOVE_FLAG_EXISTS) != 0) && (move->PP != 0)) {
|
|
moveStack[counter] = move;
|
|
indexStack[counter] = i;
|
|
counter++;
|
|
}
|
|
}
|
|
if (counter != 0) {
|
|
moveIndex = DungeonRandInt(counter);
|
|
moveStack[moveIndex]->PP = 0;
|
|
BufferMoveName(gFormatBuffer_Items[0],moveStack[moveIndex],0);
|
|
sub_806A9B4(param_2, indexStack[moveIndex]);
|
|
flag = TRUE;
|
|
}
|
|
if(flag)
|
|
TryDisplayDungeonLoggableMessage3_Async(param_1,param_2,gUnknown_80FDA80);
|
|
else
|
|
TryDisplayDungeonLoggableMessage3_Async(param_1,param_2,gUnknown_80FDAA0);
|
|
}
|
|
}
|
|
|
|
void HandleWonderTile(Entity *pokemon, Entity *target)
|
|
{
|
|
sub_8079E34(pokemon, target, FALSE);
|
|
}
|
|
|
|
void HandleSealTrap(Entity *param_1,Entity *param_2)
|
|
{
|
|
Move *move;
|
|
s32 moveIndex;
|
|
s32 i;
|
|
s32 counter;
|
|
EntityInfo *info;
|
|
Move *moveStack [MAX_MON_MOVES];
|
|
bool8 flag = FALSE;
|
|
|
|
|
|
if (param_2 != NULL && !SafeguardIsActive(param_1, param_2, TRUE)) {
|
|
info = GetEntInfo(param_2);
|
|
counter = 0;
|
|
for(i = 0; i < MAX_MON_MOVES;i++)
|
|
{
|
|
move = &info->moves.moves[i];
|
|
if ((move->moveFlags & MOVE_FLAG_EXISTS) && !(move->moveFlags2 & MOVE_FLAG_SEALED)) {
|
|
moveStack[counter] = move;
|
|
counter++;
|
|
}
|
|
}
|
|
if (counter != 0) {
|
|
moveIndex = DungeonRandInt(counter);
|
|
moveStack[moveIndex]->moveFlags2 |= MOVE_FLAG_SEALED;
|
|
BufferMoveName(gFormatBuffer_Items[0],moveStack[moveIndex], NULL);
|
|
flag = TRUE;
|
|
}
|
|
if(flag)
|
|
TryDisplayDungeonLoggableMessage3_Async(param_1,param_2,gUnknown_80FDB04);
|
|
else
|
|
TryDisplayDungeonLoggableMessage3_Async(param_1,param_2,gUnknown_80FDB2C);
|
|
}
|
|
}
|
|
|
|
void HandleWhirlwindTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
if(target)
|
|
{
|
|
BlowAwayTarget(pokemon, target, DungeonRandInt(NUM_DIRECTIONS));
|
|
}
|
|
}
|
|
|
|
void HandlePokemonTrap(Entity *param_1,DungeonPos *pos)
|
|
{
|
|
s32 x, y, roomId;
|
|
s32 maxX;
|
|
struct MonSpawnInfo local_50;
|
|
s32 bottomX;
|
|
s32 maxY;
|
|
s32 bottomY;
|
|
s32 counter = 0;
|
|
s32 range = gDungeon->unk181e8.visibilityRange;
|
|
|
|
if (IsFloorwideFixedRoom()) {
|
|
LogMessageByIdWithPopupCheckUser_Async(param_1,gUnknown_80FED08);
|
|
return;
|
|
}
|
|
|
|
if (range == 0) {
|
|
range = 2;
|
|
}
|
|
|
|
roomId = GetTile(pos->x,pos->y)->room;
|
|
if (roomId == CORRIDOR_ROOM) {
|
|
bottomX = pos->x - range;
|
|
bottomY = pos->y - range;
|
|
maxX = pos->x + range;
|
|
maxY = pos->y + range;
|
|
}
|
|
else {
|
|
RoomData *room = &gDungeon->roomData[roomId];
|
|
bottomX = room->bottomRightCornerX + -1;
|
|
bottomY = room->bottomRightCornerY + -1;
|
|
maxX = room->topLeftCornerX + 1;
|
|
maxY = room->topLeftCornerY + 1;
|
|
}
|
|
|
|
for (y = bottomY; y <= maxY; y++) {
|
|
for (x = bottomX; x <= maxX; x++) {
|
|
const Tile *tile = GetTile(x,y);
|
|
if (tile->object != NULL && GetEntityType(tile->object) == ENTITY_ITEM && !(GetItemInfo(tile->object)->flags & ITEM_FLAG_IN_SHOP)) {
|
|
s32 i, species;
|
|
|
|
local_50.species = MONSTER_KECLEON;
|
|
for (i = 0; i < 100; i++) {
|
|
if (gDungeon->unk644.stoleFromKecleon != 0) {
|
|
species = MONSTER_KECLEON;
|
|
}
|
|
else {
|
|
species = (s16) GetRandomFloorMonsterId(0);
|
|
ASM_MATCH_TRICK(species);
|
|
}
|
|
|
|
local_50.species = species;
|
|
if (sub_806AA0C(local_50.species, 0) != 0)
|
|
break;
|
|
}
|
|
|
|
if (sub_806AA0C(local_50.species, 0)) {
|
|
local_50.level = 0;
|
|
local_50.unk2 = 0;
|
|
local_50.pos.x = x;
|
|
local_50.pos.y = y;
|
|
local_50.unk4 = 0;
|
|
local_50.unk10 = 0;
|
|
if (SpawnWildMon(&local_50, TRUE) != 0) {
|
|
RemoveGroundItem(&local_50.pos,0);
|
|
counter++;
|
|
}
|
|
}
|
|
DrawMinimapTile(x,y);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (counter != 0) {
|
|
LogMessageByIdWithPopupCheckUser_Async(param_1,gUnknown_80FDACC);
|
|
}
|
|
else {
|
|
LogMessageByIdWithPopupCheckUser_Async(param_1,gUnknown_80FDAE4);
|
|
}
|
|
}
|
|
|
|
void HandleTripTrap(Entity *pokemon, Entity *target)
|
|
{
|
|
u32 direction;
|
|
EntityInfo *info;
|
|
DungeonPos pos;
|
|
Item item;
|
|
|
|
if (target != NULL) {
|
|
sub_806CDD4(target, 6, NUM_DIRECTIONS);
|
|
DungeonWaitFrames_Async(0x10, 0x55);
|
|
sub_806CE68(target, NUM_DIRECTIONS);
|
|
info = GetEntInfo(target);
|
|
if ((info->heldItem).flags & ITEM_FLAG_EXISTS) {
|
|
item = (info->heldItem);
|
|
(info->heldItem).flags = 0;
|
|
FillInventoryGaps();
|
|
sub_80421C0(target, 400);
|
|
direction = (info->action).direction & DIRECTION_MASK;
|
|
pos.x = (target->pos).x + gAdjacentTileOffsets[direction].x;
|
|
pos.y = (target->pos).y + gAdjacentTileOffsets[direction].y;
|
|
sub_804687C(pokemon, &target->pos, &pos, &item, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SetTrap(Tile *tile, u8 id)
|
|
{
|
|
Trap *trapData;
|
|
Entity *entity;
|
|
|
|
entity = tile->object;
|
|
if (EntityIsValid(entity)) {
|
|
if (GetEntityType(entity) == ENTITY_TRAP) {
|
|
trapData = GetTrapInfo(entity);
|
|
trapData->id = id;
|
|
}
|
|
UpdateTrapsVisibility();
|
|
}
|
|
}
|