Sync union_room_player_avatar
This commit is contained in:
@@ -1,12 +1,3 @@
|
|||||||
.set LOCALID_UNION_ROOM_PLAYER_4, 2
|
|
||||||
.set LOCALID_UNION_ROOM_PLAYER_8, 3
|
|
||||||
.set LOCALID_UNION_ROOM_PLAYER_7, 4
|
|
||||||
.set LOCALID_UNION_ROOM_PLAYER_6, 5
|
|
||||||
.set LOCALID_UNION_ROOM_PLAYER_5, 6
|
|
||||||
.set LOCALID_UNION_ROOM_PLAYER_3, 7
|
|
||||||
.set LOCALID_UNION_ROOM_PLAYER_2, 8
|
|
||||||
.set LOCALID_UNION_ROOM_PLAYER_1, 9
|
|
||||||
|
|
||||||
UnionRoom_MapScripts::
|
UnionRoom_MapScripts::
|
||||||
map_script MAP_SCRIPT_ON_RESUME, UnionRoom_OnResume
|
map_script MAP_SCRIPT_ON_RESUME, UnionRoom_OnResume
|
||||||
map_script MAP_SCRIPT_ON_TRANSITION, UnionRoom_OnTransition
|
map_script MAP_SCRIPT_ON_TRANSITION, UnionRoom_OnTransition
|
||||||
|
|||||||
@@ -189,10 +189,21 @@
|
|||||||
#define TRACKS_FOOT 1
|
#define TRACKS_FOOT 1
|
||||||
#define TRACKS_BIKE_TIRE 2
|
#define TRACKS_BIKE_TIRE 2
|
||||||
|
|
||||||
#define OBJ_EVENT_ID_PLAYER 0xFF
|
|
||||||
#define OBJ_EVENT_ID_CAMERA 0x7F
|
|
||||||
|
|
||||||
#define OBJ_KIND_NORMAL 0
|
#define OBJ_KIND_NORMAL 0
|
||||||
#define OBJ_KIND_CLONE 255
|
#define OBJ_KIND_CLONE 255
|
||||||
|
|
||||||
|
// Special object event local ids
|
||||||
|
#define OBJ_EVENT_ID_PLAYER 0xFF
|
||||||
|
#define OBJ_EVENT_ID_CAMERA 0x7F
|
||||||
|
|
||||||
|
// Object event local ids referenced in C files
|
||||||
|
#define LOCALID_UNION_ROOM_PLAYER_4 2
|
||||||
|
#define LOCALID_UNION_ROOM_PLAYER_8 3
|
||||||
|
#define LOCALID_UNION_ROOM_PLAYER_7 4
|
||||||
|
#define LOCALID_UNION_ROOM_PLAYER_6 5
|
||||||
|
#define LOCALID_UNION_ROOM_PLAYER_5 6
|
||||||
|
#define LOCALID_UNION_ROOM_PLAYER_3 7
|
||||||
|
#define LOCALID_UNION_ROOM_PLAYER_2 8
|
||||||
|
#define LOCALID_UNION_ROOM_PLAYER_1 9
|
||||||
|
|
||||||
#endif // GUARD_CONSTANTS_EVENT_OBJECTS_H
|
#endif // GUARD_CONSTANTS_EVENT_OBJECTS_H
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
#ifndef GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
|
||||||
#define GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
|
||||||
|
|
||||||
#include "union_room.h"
|
|
||||||
|
|
||||||
u8 ZeroUnionObjWork(struct UnionRoomObject * ptr);
|
|
||||||
void DestroyUnionRoomPlayerObjects(void);
|
|
||||||
void CreateGroupMemberObjectsInvisible(u8 *spriteIds, s32 group);
|
|
||||||
void DestroyGroupMemberObjects(u8 *spriteIds);
|
|
||||||
void MakeGroupAssemblyAreasPassable(void);
|
|
||||||
void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p);
|
|
||||||
void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p);
|
|
||||||
bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds);
|
|
||||||
void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct RfuPlayerList *main0_p);
|
|
||||||
|
|
||||||
#endif //GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
||||||
|
#define GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
||||||
|
|
||||||
|
#include "union_room.h"
|
||||||
|
|
||||||
|
u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players);
|
||||||
|
void DestroyUnionRoomPlayerObjects(void);
|
||||||
|
void CreateUnionRoomPlayerSprites(u8 *spriteIds, s32 leaderId);
|
||||||
|
void DestroyUnionRoomPlayerSprites(u8 *spriteIds);
|
||||||
|
void MakeGroupAssemblyAreasPassable(void);
|
||||||
|
void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom);
|
||||||
|
void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom);
|
||||||
|
bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *list, s16 *memberIdPtr, s16 *leaderIdPtr, u8 *spriteIds);
|
||||||
|
void UpdateUnionRoomMemberFacing(u32 memberId, u32 leaderId, struct RfuPlayerList *list);
|
||||||
|
|
||||||
|
#endif //GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
||||||
+2
-2
@@ -249,7 +249,7 @@ SECTIONS {
|
|||||||
src/trainer_fan_club.o(.text);
|
src/trainer_fan_club.o(.text);
|
||||||
src/quest_log_events.o(.text);
|
src/quest_log_events.o(.text);
|
||||||
src/union_room.o(.text);
|
src/union_room.o(.text);
|
||||||
src/rfu_union_tool.o(.text);
|
src/union_room_player_avatar.o(.text);
|
||||||
src/union_room_battle.o(.text);
|
src/union_room_battle.o(.text);
|
||||||
src/pokemon_special_anim.o(.text);
|
src/pokemon_special_anim.o(.text);
|
||||||
src/pokemon_special_anim_scene.o(.text);
|
src/pokemon_special_anim_scene.o(.text);
|
||||||
@@ -542,7 +542,7 @@ SECTIONS {
|
|||||||
src/trainer_fan_club.o(.rodata);
|
src/trainer_fan_club.o(.rodata);
|
||||||
src/quest_log_events.o(.rodata);
|
src/quest_log_events.o(.rodata);
|
||||||
src/union_room.o(.rodata);
|
src/union_room.o(.rodata);
|
||||||
src/rfu_union_tool.o(.rodata);
|
src/union_room_player_avatar.o(.rodata);
|
||||||
src/union_room_battle.o(.rodata);
|
src/union_room_battle.o(.rodata);
|
||||||
src/union_room_message.o(.rodata);
|
src/union_room_message.o(.rodata);
|
||||||
src/pokemon_special_anim.o(.rodata);
|
src/pokemon_special_anim.o(.rodata);
|
||||||
|
|||||||
+10
-7
@@ -34,6 +34,7 @@
|
|||||||
#include "constants/trainers.h"
|
#include "constants/trainers.h"
|
||||||
#include "constants/hold_effects.h"
|
#include "constants/hold_effects.h"
|
||||||
#include "constants/battle_move_effects.h"
|
#include "constants/battle_move_effects.h"
|
||||||
|
#include "constants/union_room.h"
|
||||||
|
|
||||||
#define SPECIES_TO_HOENN(name) [SPECIES_##name - 1] = HOENN_DEX_##name
|
#define SPECIES_TO_HOENN(name) [SPECIES_##name - 1] = HOENN_DEX_##name
|
||||||
#define SPECIES_TO_NATIONAL(name) [SPECIES_##name - 1] = NATIONAL_DEX_##name
|
#define SPECIES_TO_NATIONAL(name) [SPECIES_##name - 1] = NATIONAL_DEX_##name
|
||||||
@@ -1643,7 +1644,9 @@ static const u16 sDeoxysBaseStats[] =
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const u16 gLinkPlayerFacilityClasses[] =
|
// The classes used by other players in the Union Room.
|
||||||
|
// These should correspond with the overworld graphics in sUnionRoomObjGfxIds
|
||||||
|
const u16 gUnionRoomFacilityClasses[NUM_UNION_ROOM_CLASSES * GENDER_COUNT] =
|
||||||
{
|
{
|
||||||
// Male
|
// Male
|
||||||
FACILITY_CLASS_COOLTRAINER_M,
|
FACILITY_CLASS_COOLTRAINER_M,
|
||||||
@@ -6031,19 +6034,19 @@ void SetDeoxysStats(void)
|
|||||||
u16 GetUnionRoomTrainerPic(void)
|
u16 GetUnionRoomTrainerPic(void)
|
||||||
{
|
{
|
||||||
u8 linkId = GetMultiplayerId() ^ 1;
|
u8 linkId = GetMultiplayerId() ^ 1;
|
||||||
u32 arrId = gLinkPlayers[linkId].trainerId & 7;
|
|
||||||
|
|
||||||
arrId |= gLinkPlayers[linkId].gender << 3;
|
u32 arrId = gLinkPlayers[linkId].trainerId % NUM_UNION_ROOM_CLASSES;
|
||||||
return FacilityClassToPicIndex(gLinkPlayerFacilityClasses[arrId]);
|
arrId |= gLinkPlayers[linkId].gender * NUM_UNION_ROOM_CLASSES;
|
||||||
|
return FacilityClassToPicIndex(gUnionRoomFacilityClasses[arrId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 GetUnionRoomTrainerClass(void)
|
u16 GetUnionRoomTrainerClass(void)
|
||||||
{
|
{
|
||||||
u8 linkId = GetMultiplayerId() ^ 1;
|
u8 linkId = GetMultiplayerId() ^ 1;
|
||||||
u32 arrId = gLinkPlayers[linkId].trainerId & 7;
|
|
||||||
|
|
||||||
arrId |= gLinkPlayers[linkId].gender << 3;
|
u32 arrId = gLinkPlayers[linkId].trainerId % NUM_UNION_ROOM_CLASSES;
|
||||||
return gFacilityClassToTrainerClass[gLinkPlayerFacilityClasses[arrId]];
|
arrId |= gLinkPlayers[linkId].gender * NUM_UNION_ROOM_CLASSES;
|
||||||
|
return gFacilityClassToTrainerClass[gUnionRoomFacilityClasses[arrId]];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateEventLegalEnemyMon(void)
|
void CreateEventLegalEnemyMon(void)
|
||||||
|
|||||||
@@ -1,663 +0,0 @@
|
|||||||
#include "global.h"
|
|
||||||
#include "event_data.h"
|
|
||||||
#include "event_object_movement.h"
|
|
||||||
#include "field_player_avatar.h"
|
|
||||||
#include "fieldmap.h"
|
|
||||||
#include "rfu_union_tool.h"
|
|
||||||
#include "script.h"
|
|
||||||
#include "task.h"
|
|
||||||
#include "constants/event_object_movement.h"
|
|
||||||
#include "constants/union_room.h"
|
|
||||||
#include "constants/event_objects.h"
|
|
||||||
|
|
||||||
static EWRAM_DATA struct UnionRoomObject * UnionObjWork = NULL;
|
|
||||||
static EWRAM_DATA u32 sUnionObjRefreshTimer = 0;
|
|
||||||
|
|
||||||
static u8 StartUnionObjAnimTask(void);
|
|
||||||
static u32 RfuUnionGroupMemberIsInvisible(u32 group, u32 member);
|
|
||||||
static void UnionPartnerObjectSetFacing(s32 member, s32 group, u8 direction);
|
|
||||||
|
|
||||||
static const u8 sUnionObjectEventGfxIds[][10] = {
|
|
||||||
[MALE] = {
|
|
||||||
OBJ_EVENT_GFX_COOLTRAINER_M,
|
|
||||||
OBJ_EVENT_GFX_BLACKBELT,
|
|
||||||
OBJ_EVENT_GFX_CAMPER,
|
|
||||||
OBJ_EVENT_GFX_YOUNGSTER,
|
|
||||||
OBJ_EVENT_GFX_BOY,
|
|
||||||
OBJ_EVENT_GFX_BUG_CATCHER,
|
|
||||||
OBJ_EVENT_GFX_MAN,
|
|
||||||
OBJ_EVENT_GFX_ROCKER
|
|
||||||
},
|
|
||||||
[FEMALE] = {
|
|
||||||
OBJ_EVENT_GFX_COOLTRAINER_F,
|
|
||||||
OBJ_EVENT_GFX_CHANNELER,
|
|
||||||
OBJ_EVENT_GFX_PICNICKER,
|
|
||||||
OBJ_EVENT_GFX_LASS,
|
|
||||||
OBJ_EVENT_GFX_WOMAN_1,
|
|
||||||
OBJ_EVENT_GFX_BATTLE_GIRL,
|
|
||||||
OBJ_EVENT_GFX_WOMAN_2,
|
|
||||||
OBJ_EVENT_GFX_BEAUTY
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const s16 sUnionPartnerCoords[][2] = {
|
|
||||||
{ 4, 6},
|
|
||||||
{13, 8},
|
|
||||||
{10, 6},
|
|
||||||
{ 1, 8},
|
|
||||||
{13, 4},
|
|
||||||
{ 7, 4},
|
|
||||||
{ 1, 4},
|
|
||||||
{ 7, 8}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const s8 sFacingDirectionOffsets[][2] = {
|
|
||||||
[DIR_NONE] = { 0, 0},
|
|
||||||
[DIR_SOUTH] = { 1, 0},
|
|
||||||
[DIR_NORTH] = { 0, -1},
|
|
||||||
[DIR_WEST] = {-1, 0},
|
|
||||||
[DIR_EAST] = { 0, 1}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u8 sOppositeFacingDirection[] = {
|
|
||||||
[DIR_NONE] = DIR_NONE,
|
|
||||||
[DIR_SOUTH] = DIR_NORTH,
|
|
||||||
[DIR_NORTH] = DIR_SOUTH,
|
|
||||||
[DIR_WEST] = DIR_EAST,
|
|
||||||
[DIR_EAST] = DIR_WEST
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u8 sUnionGroupMemberFacings[] = {
|
|
||||||
DIR_SOUTH,
|
|
||||||
DIR_WEST,
|
|
||||||
DIR_SOUTH,
|
|
||||||
DIR_EAST,
|
|
||||||
DIR_NORTH
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u8 sUnionRoomLocalIds[] = {
|
|
||||||
9,
|
|
||||||
8,
|
|
||||||
7,
|
|
||||||
2,
|
|
||||||
6,
|
|
||||||
5,
|
|
||||||
4,
|
|
||||||
3
|
|
||||||
};
|
|
||||||
|
|
||||||
// Unused
|
|
||||||
static const u16 sHidePlayerFlags[] = {
|
|
||||||
FLAG_HIDE_UNION_ROOM_PLAYER_1,
|
|
||||||
FLAG_HIDE_UNION_ROOM_PLAYER_2,
|
|
||||||
FLAG_HIDE_UNION_ROOM_PLAYER_3,
|
|
||||||
FLAG_HIDE_UNION_ROOM_PLAYER_4,
|
|
||||||
FLAG_HIDE_UNION_ROOM_PLAYER_5,
|
|
||||||
FLAG_HIDE_UNION_ROOM_PLAYER_6,
|
|
||||||
FLAG_HIDE_UNION_ROOM_PLAYER_7,
|
|
||||||
FLAG_HIDE_UNION_ROOM_PLAYER_8
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool32 is_walking_or_running(void)
|
|
||||||
{
|
|
||||||
if (gPlayerAvatar.tileTransitionState == 2 || gPlayerAvatar.tileTransitionState == 0)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static u8 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id)
|
|
||||||
{
|
|
||||||
return sUnionObjectEventGfxIds[gender][id % 8];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void GetUnionRoomPlayerFacingCoords(u32 group, u32 member, s32 * xp, s32 * yp)
|
|
||||||
{
|
|
||||||
*xp = sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[member][0] + 7;
|
|
||||||
*yp = sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[member][1] + 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32 IsUnionRoomPlayerFacingTileAt(u32 group, u32 member, s32 x, s32 y)
|
|
||||||
{
|
|
||||||
if (sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[member][0] + 7 != x)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else if (sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[member][1] + 7 != y)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32 IsUnionRoomPlayerHidden(u32 player_idx)
|
|
||||||
{
|
|
||||||
return FlagGet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void HideUnionRoomPlayer(u32 player_idx)
|
|
||||||
{
|
|
||||||
FlagSet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ShowUnionRoomPlayer(u32 player_idx)
|
|
||||||
{
|
|
||||||
FlagClear(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetUnionRoomPlayerGfx(u32 playerIdx, u32 gfxId)
|
|
||||||
{
|
|
||||||
VarSet(VAR_OBJ_GFX_ID_0 + playerIdx, gfxId);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CreateUnionRoomPlayerObjectEvent(u32 playerIdx)
|
|
||||||
{
|
|
||||||
TrySpawnObjectEvent(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RemoveUnionRoomPlayerObjectEvent(u32 playerIdx)
|
|
||||||
{
|
|
||||||
RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32 SetUnionRoomPlayerEnterExitMovement(u32 playerIdx, const u8 * movement)
|
|
||||||
{
|
|
||||||
u8 objectId;
|
|
||||||
struct ObjectEvent * object;
|
|
||||||
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
object = &gObjectEvents[objectId];
|
|
||||||
if (ObjectEventIsMovementOverridden(object))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (ObjectEventSetHeldMovement(object, *movement))
|
|
||||||
{
|
|
||||||
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 387);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 playerIdx)
|
|
||||||
{
|
|
||||||
u8 objectId;
|
|
||||||
struct ObjectEvent * object;
|
|
||||||
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
object = &gObjectEvents[objectId];
|
|
||||||
if (!ObjectEventClearHeldMovementIfFinished(object))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (!ArePlayerFieldControlsLocked())
|
|
||||||
{
|
|
||||||
UnfreezeObjectEvent(object);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FreezeObjectEvent(object);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 ZeroUnionObjWork(struct UnionRoomObject * ptr)
|
|
||||||
{
|
|
||||||
s32 i;
|
|
||||||
|
|
||||||
sUnionObjRefreshTimer = 0;
|
|
||||||
UnionObjWork = ptr;
|
|
||||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 442)
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
ptr[i].state = 0;
|
|
||||||
ptr[i].gfxId = 0;
|
|
||||||
ptr[i].animState = 0;
|
|
||||||
ptr[i].schedAnim = 0;
|
|
||||||
}
|
|
||||||
return StartUnionObjAnimTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const u8 sMovement_UnionPlayerExit[2] = {
|
|
||||||
MOVEMENT_ACTION_FLY_UP,
|
|
||||||
MOVEMENT_ACTION_STEP_END
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool32 AnimateUnionRoomPlayerDespawn(s8 * a0, u32 playerIdx, struct UnionRoomObject * ptr)
|
|
||||||
{
|
|
||||||
switch (*a0)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerExit) == TRUE)
|
|
||||||
{
|
|
||||||
HideUnionRoomPlayer(playerIdx);
|
|
||||||
(*a0)++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx))
|
|
||||||
{
|
|
||||||
RemoveUnionRoomPlayerObjectEvent(playerIdx);
|
|
||||||
HideUnionRoomPlayer(playerIdx);
|
|
||||||
*a0 = 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const u8 sMovement_UnionPlayerEnter[2] = {
|
|
||||||
MOVEMENT_ACTION_FLY_DOWN,
|
|
||||||
MOVEMENT_ACTION_STEP_END
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool32 AnimateUnionRoomPlayerSpawn(s8 * state_p, u32 playerIdx, struct UnionRoomObject * ptr)
|
|
||||||
{
|
|
||||||
s16 x, y;
|
|
||||||
|
|
||||||
switch (*state_p)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
if (!is_walking_or_running())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
PlayerGetDestCoords(&x, &y);
|
|
||||||
if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
player_get_pos_including_state_based_drift(&x, &y);
|
|
||||||
if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SetUnionRoomPlayerGfx(playerIdx, ptr->gfxId);
|
|
||||||
CreateUnionRoomPlayerObjectEvent(playerIdx);
|
|
||||||
ShowUnionRoomPlayer(playerIdx);
|
|
||||||
(*state_p)++;
|
|
||||||
// fallthrough
|
|
||||||
case 3: // incorrect?
|
|
||||||
if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerEnter) == 1)
|
|
||||||
{
|
|
||||||
(*state_p)++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx))
|
|
||||||
{
|
|
||||||
*state_p = 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32 SpawnGroupLeader(u32 playerIdx, u32 gender, u32 idMod256)
|
|
||||||
{
|
|
||||||
struct UnionRoomObject * ptr = &UnionObjWork[playerIdx];
|
|
||||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 561)
|
|
||||||
ptr->schedAnim = UNION_ROOM_SPAWN_IN;
|
|
||||||
ptr->gfxId = GetUnionRoomPlayerGraphicsId(gender, idMod256);
|
|
||||||
if (ptr->state == 0)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32 DespawnGroupLeader(u32 playerIdx)
|
|
||||||
{
|
|
||||||
struct UnionRoomObject * ptr = &UnionObjWork[playerIdx];
|
|
||||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 577)
|
|
||||||
ptr->schedAnim = UNION_ROOM_SPAWN_OUT;
|
|
||||||
if (ptr->state == 1)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AnimateUnionObj(u32 playerIdx, struct UnionRoomObject * ptr)
|
|
||||||
{
|
|
||||||
switch (ptr->state)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
if (ptr->schedAnim == UNION_ROOM_SPAWN_IN)
|
|
||||||
{
|
|
||||||
ptr->state = 2;
|
|
||||||
ptr->animState = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// fallthrough
|
|
||||||
case 2:
|
|
||||||
if (!RfuUnionGroupMemberIsInvisible(playerIdx, 0) && ptr->schedAnim == 2)
|
|
||||||
{
|
|
||||||
ptr->state = 0;
|
|
||||||
ptr->animState = 0;
|
|
||||||
RemoveUnionRoomPlayerObjectEvent(playerIdx);
|
|
||||||
HideUnionRoomPlayer(playerIdx);
|
|
||||||
}
|
|
||||||
else if (AnimateUnionRoomPlayerSpawn(&ptr->animState, playerIdx, ptr) == TRUE)
|
|
||||||
{
|
|
||||||
ptr->state = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (ptr->schedAnim == UNION_ROOM_SPAWN_OUT)
|
|
||||||
{
|
|
||||||
ptr->state = 3;
|
|
||||||
ptr->animState = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// fallthrough
|
|
||||||
case 3:
|
|
||||||
if (AnimateUnionRoomPlayerDespawn(&ptr->animState, playerIdx, ptr) == TRUE)
|
|
||||||
{
|
|
||||||
ptr->state = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ptr->schedAnim = UNION_ROOM_SPAWN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Task_AnimateUnionObjs(u8 taskId)
|
|
||||||
{
|
|
||||||
s32 i;
|
|
||||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 643)
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
AnimateUnionObj(i, &UnionObjWork[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static u8 StartUnionObjAnimTask(void)
|
|
||||||
{
|
|
||||||
if (FuncIsActiveTask(Task_AnimateUnionObjs) == TRUE)
|
|
||||||
{
|
|
||||||
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 655)
|
|
||||||
return NUM_TASKS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return CreateTask(Task_AnimateUnionObjs, 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DestroyAnimateUnionObjsTask(void)
|
|
||||||
{
|
|
||||||
u8 taskId = FindTaskIdByFunc(Task_AnimateUnionObjs);
|
|
||||||
if (taskId < NUM_TASKS)
|
|
||||||
{
|
|
||||||
DestroyTask(taskId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DestroyUnionRoomPlayerObjects(void)
|
|
||||||
{
|
|
||||||
s32 i;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
if (!IsUnionRoomPlayerHidden(i))
|
|
||||||
{
|
|
||||||
RemoveUnionRoomPlayerObjectEvent(i);
|
|
||||||
HideUnionRoomPlayer(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UnionObjWork = NULL;
|
|
||||||
DestroyAnimateUnionObjsTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateGroupMemberObjectsInvisible(u8 * sprite_ids, s32 group)
|
|
||||||
{
|
|
||||||
s32 i;
|
|
||||||
|
|
||||||
for (i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
s32 obj_id = 5 * group + i;
|
|
||||||
sprite_ids[obj_id] = CreateVirtualObject(OBJ_EVENT_GFX_MAN, obj_id - 0x38, sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[i][0], sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[i][1], 3, 1);
|
|
||||||
SetVirtualObjectInvisibility(obj_id - 0x38, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DestroyGroupMemberObjects(u8 *spriteIds)
|
|
||||||
{
|
|
||||||
s32 i;
|
|
||||||
for (i = 0; i < 40; i++)
|
|
||||||
{
|
|
||||||
DestroySprite(&gSprites[spriteIds[i]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MakeGroupAssemblyAreasPassable(void)
|
|
||||||
{
|
|
||||||
s32 i, j, x, y;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < 5; j++)
|
|
||||||
{
|
|
||||||
GetUnionRoomPlayerFacingCoords(i, j, &x, &y);
|
|
||||||
MapGridSetMetatileImpassabilityAt(x, y, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static u8 UnionPartnerObjectGetFacing(u32 member, u32 group, struct RfuGameData * gname)
|
|
||||||
{
|
|
||||||
if (member != 0)
|
|
||||||
{
|
|
||||||
return sUnionGroupMemberFacings[member];
|
|
||||||
}
|
|
||||||
else if (gname->activity == 0x45)
|
|
||||||
{
|
|
||||||
return DIR_SOUTH;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return DIR_EAST;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 RfuUnionGroupMemberIsInvisible(u32 group, u32 member)
|
|
||||||
{
|
|
||||||
return IsVirtualObjectInvisible(5 * group + member - 0x38);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SpawnGroupMember(u32 groupNo, u32 memberNo, u8 direction, struct RfuGameData * gname)
|
|
||||||
{
|
|
||||||
s32 x, y;
|
|
||||||
s32 objId = 5 * groupNo + memberNo;
|
|
||||||
if (RfuUnionGroupMemberIsInvisible(groupNo, memberNo) == TRUE)
|
|
||||||
{
|
|
||||||
SetVirtualObjectInvisibility(objId - 0x38, FALSE);
|
|
||||||
SetVirtualObjectSpriteAnim(objId - 0x38, UNION_ROOM_SPAWN_IN);
|
|
||||||
}
|
|
||||||
SetVirtualObjectGraphics(objId - 0x38, direction);
|
|
||||||
UnionPartnerObjectSetFacing(memberNo, groupNo, UnionPartnerObjectGetFacing(memberNo, groupNo, gname));
|
|
||||||
GetUnionRoomPlayerFacingCoords(groupNo, memberNo, &x, &y);
|
|
||||||
MapGridSetMetatileImpassabilityAt(x, y, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DespawnGroupMember(u32 group, u32 member)
|
|
||||||
{
|
|
||||||
s32 x, y;
|
|
||||||
SetVirtualObjectSpriteAnim(5 * group + member - 0x38, UNION_ROOM_SPAWN_OUT);
|
|
||||||
GetUnionRoomPlayerFacingCoords(group, member, &x, &y);
|
|
||||||
MapGridSetMetatileImpassabilityAt(x, y, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AssembleGroup(u32 group, struct RfuGameData * gname)
|
|
||||||
{
|
|
||||||
s16 x, y, x2, y2;
|
|
||||||
s32 i;
|
|
||||||
|
|
||||||
PlayerGetDestCoords(&x, &y);
|
|
||||||
player_get_pos_including_state_based_drift(&x2, &y2);
|
|
||||||
if (IsVirtualObjectInvisible(5 * group - 0x38) == TRUE)
|
|
||||||
{
|
|
||||||
if (IsUnionRoomPlayerFacingTileAt(group, 0, x, y) == TRUE || IsUnionRoomPlayerFacingTileAt(group, 0, x2, y2) == TRUE)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SpawnGroupMember(group, 0, GetUnionRoomPlayerGraphicsId(gname->playerGender, gname->compatibility.playerTrainerId[0]), gname);
|
|
||||||
}
|
|
||||||
for (i = 1; i < 5; i++)
|
|
||||||
{
|
|
||||||
if (gname->partnerInfo[i - 1] == 0)
|
|
||||||
{
|
|
||||||
DespawnGroupMember(group, i);
|
|
||||||
}
|
|
||||||
else if (IsUnionRoomPlayerFacingTileAt(group, i, x, y) == FALSE && IsUnionRoomPlayerFacingTileAt(group, i, x2, y2) == FALSE)
|
|
||||||
{
|
|
||||||
SpawnGroupMember(group, i, GetUnionRoomPlayerGraphicsId((gname->partnerInfo[i - 1] >> 3) & 1, gname->partnerInfo[i - 1] & 7), gname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SpawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname)
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
switch (gname->activity)
|
|
||||||
{
|
|
||||||
case 0x40:
|
|
||||||
case 0x54:
|
|
||||||
SpawnGroupLeader(group, gname->playerGender, gname->compatibility.playerTrainerId[0]);
|
|
||||||
for (i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
DespawnGroupMember(group, i);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x41:
|
|
||||||
case 0x44:
|
|
||||||
case 0x45:
|
|
||||||
case 0x48:
|
|
||||||
case 0x51:
|
|
||||||
case 0x52:
|
|
||||||
case 0x53:
|
|
||||||
DespawnGroupLeader(group);
|
|
||||||
AssembleGroup(group, gname);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 979)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DespawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname)
|
|
||||||
{
|
|
||||||
s32 i;
|
|
||||||
DespawnGroupLeader(group);
|
|
||||||
for (i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
DespawnGroupMember(group, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom * groups)
|
|
||||||
{
|
|
||||||
s32 i;
|
|
||||||
struct RfuPlayer * x20_p;
|
|
||||||
sUnionObjRefreshTimer = 0;
|
|
||||||
for (i = 0, x20_p = groups->playerList->players; i < 8; i++)
|
|
||||||
{
|
|
||||||
if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN)
|
|
||||||
{
|
|
||||||
SpawnGroupLeaderAndMembers(i, &x20_p[i].rfu.data);
|
|
||||||
}
|
|
||||||
else if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT)
|
|
||||||
{
|
|
||||||
DespawnGroupLeaderAndMembers(i, &x20_p[i].rfu.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p)
|
|
||||||
{
|
|
||||||
sUnionObjRefreshTimer = 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p)
|
|
||||||
{
|
|
||||||
if (++sUnionObjRefreshTimer > 300)
|
|
||||||
{
|
|
||||||
UpdateUnionRoomPlayerSprites(uroom_p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds)
|
|
||||||
{
|
|
||||||
s16 x, y;
|
|
||||||
s32 i, j;
|
|
||||||
struct RfuPlayer * x20_p;
|
|
||||||
if (!is_walking_or_running())
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
|
|
||||||
for (i = 0, x20_p = main0_p->players; i < 8; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < 5; j++)
|
|
||||||
{
|
|
||||||
s32 objId = 5 * i + j;
|
|
||||||
if (x != sUnionPartnerCoords[i][0] + sFacingDirectionOffsets[j][0] + 7)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (y != sUnionPartnerCoords[i][1] + sFacingDirectionOffsets[j][1] + 7)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (IsVirtualObjectInvisible(objId - 0x38) != FALSE)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (IsVirtualObjectAnimating(objId - 0x38) != FALSE)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (x20_p[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
UnionPartnerObjectSetFacing(j, i, sOppositeFacingDirection[GetPlayerFacingDirection()]);
|
|
||||||
*member_p = j;
|
|
||||||
*group_p = i;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UnionPartnerObjectSetFacing(s32 member, s32 group, u8 direction)
|
|
||||||
{
|
|
||||||
TurnVirtualObject(5 * group - 0x38 + member, direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct RfuPlayerList *main0_p)
|
|
||||||
{
|
|
||||||
return UnionPartnerObjectSetFacing(member, group, UnionPartnerObjectGetFacing(member, group, &main0_p->players[group].rfu.data));
|
|
||||||
}
|
|
||||||
+7
-7
@@ -40,7 +40,7 @@
|
|||||||
#include "union_room.h"
|
#include "union_room.h"
|
||||||
#include "union_room_battle.h"
|
#include "union_room_battle.h"
|
||||||
#include "union_room_chat.h"
|
#include "union_room_chat.h"
|
||||||
#include "rfu_union_tool.h"
|
#include "union_room_player_avatar.h"
|
||||||
#include "union_room_message.h"
|
#include "union_room_message.h"
|
||||||
#include "constants/songs.h"
|
#include "constants/songs.h"
|
||||||
#include "constants/maps.h"
|
#include "constants/maps.h"
|
||||||
@@ -2317,13 +2317,13 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||||||
ClearRfuPlayerList(uroom->playerList->players, MAX_UNION_ROOM_LEADERS);
|
ClearRfuPlayerList(uroom->playerList->players, MAX_UNION_ROOM_LEADERS);
|
||||||
sPlayerCurrActivity = IN_UNION_ROOM;
|
sPlayerCurrActivity = IN_UNION_ROOM;
|
||||||
uroom->searchTaskId = CreateTask_SearchForChildOrParent(uroom->incomingParentList, uroom->incomingChildList, LINK_GROUP_UNION_ROOM_RESUME);
|
uroom->searchTaskId = CreateTask_SearchForChildOrParent(uroom->incomingParentList, uroom->incomingChildList, LINK_GROUP_UNION_ROOM_RESUME);
|
||||||
ZeroUnionObjWork(uroom->objects);
|
InitUnionRoomPlayerObjects(uroom->objects);
|
||||||
MakeGroupAssemblyAreasPassable();
|
MakeGroupAssemblyAreasPassable();
|
||||||
uroom->state = UR_STATE_INIT_OBJECTS;
|
uroom->state = UR_STATE_INIT_OBJECTS;
|
||||||
break;
|
break;
|
||||||
case UR_STATE_INIT_OBJECTS:
|
case UR_STATE_INIT_OBJECTS:
|
||||||
CreateGroupMemberObjectsInvisible(uroom->spriteIds, taskData[0]);
|
CreateUnionRoomPlayerSprites(uroom->spriteIds, taskData[0]);
|
||||||
if (++taskData[0] == 8)
|
if (++taskData[0] == MAX_UNION_ROOM_LEADERS)
|
||||||
uroom->state = UR_STATE_INIT_LINK;
|
uroom->state = UR_STATE_INIT_LINK;
|
||||||
break;
|
break;
|
||||||
case UR_STATE_INIT_LINK:
|
case UR_STATE_INIT_LINK:
|
||||||
@@ -2515,7 +2515,7 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||||||
if (!gReceivedRemoteLinkPlayers)
|
if (!gReceivedRemoteLinkPlayers)
|
||||||
{
|
{
|
||||||
HandleCancelActivity(FALSE);
|
HandleCancelActivity(FALSE);
|
||||||
UpdateUnionGroupMemberFacing(taskData[0], taskData[1], uroom->playerList);
|
UpdateUnionRoomMemberFacing(taskData[0], taskData[1], uroom->playerList);
|
||||||
uroom->state = UR_STATE_INIT_LINK;
|
uroom->state = UR_STATE_INIT_LINK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2840,7 +2840,7 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||||||
Free(uroom->incomingParentList);
|
Free(uroom->incomingParentList);
|
||||||
Free(uroom->incomingChildList);
|
Free(uroom->incomingChildList);
|
||||||
DestroyTask(uroom->searchTaskId);
|
DestroyTask(uroom->searchTaskId);
|
||||||
DestroyGroupMemberObjects(uroom->spriteIds);
|
DestroyUnionRoomPlayerSprites(uroom->spriteIds);
|
||||||
uroom->state = UR_STATE_START_ACTIVITY_FADE;
|
uroom->state = UR_STATE_START_ACTIVITY_FADE;
|
||||||
break;
|
break;
|
||||||
case UR_STATE_START_ACTIVITY_FADE:
|
case UR_STATE_START_ACTIVITY_FADE:
|
||||||
@@ -3051,7 +3051,7 @@ static void Task_RunUnionRoom(u8 taskId)
|
|||||||
if (PrintOnTextbox(&uroom->textState, gStringVar4))
|
if (PrintOnTextbox(&uroom->textState, gStringVar4))
|
||||||
{
|
{
|
||||||
HandleCancelActivity(TRUE);
|
HandleCancelActivity(TRUE);
|
||||||
UpdateUnionGroupMemberFacing(taskData[0], taskData[1], uroom->playerList);
|
UpdateUnionRoomMemberFacing(taskData[0], taskData[1], uroom->playerList);
|
||||||
uroom->state = UR_STATE_MAIN;
|
uroom->state = UR_STATE_MAIN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -0,0 +1,615 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "event_data.h"
|
||||||
|
#include "event_object_movement.h"
|
||||||
|
#include "field_player_avatar.h"
|
||||||
|
#include "fieldmap.h"
|
||||||
|
#include "union_room_player_avatar.h"
|
||||||
|
#include "script.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "constants/event_object_movement.h"
|
||||||
|
#include "constants/union_room.h"
|
||||||
|
#include "constants/event_objects.h"
|
||||||
|
|
||||||
|
#define UR_SPRITE_START_ID (MAX_SPRITES - MAX_UNION_ROOM_LEADERS)
|
||||||
|
|
||||||
|
// Each parent player can lead a group of up to MAX_RFU_PLAYERS (including themselves).
|
||||||
|
// Multiply the leader's id by MAX_RFU_PLAYERS and add the member's id (0 if the leader) to
|
||||||
|
// get the sprite index of that player.
|
||||||
|
#define UR_PLAYER_SPRITE_ID(leaderId, memberId)(MAX_RFU_PLAYERS * leaderId + memberId)
|
||||||
|
|
||||||
|
// Original symbol name from ASSERT statements
|
||||||
|
#define UnionObjWork sUnionObjWork
|
||||||
|
|
||||||
|
static EWRAM_DATA struct UnionRoomObject * sUnionObjWork = NULL;
|
||||||
|
static EWRAM_DATA u32 sUnionObjRefreshTimer = 0;
|
||||||
|
|
||||||
|
static u8 CreateTask_AnimateUnionRoomPlayers(void);
|
||||||
|
static u32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 member);
|
||||||
|
static void SetUnionRoomObjectFacingDirection(s32 member, s32 leaderId, u8 direction);
|
||||||
|
|
||||||
|
// + 2 is just to match, those elements are empty and never read
|
||||||
|
// Graphics ids should correspond with the classes in gUnionRoomFacilityClasses
|
||||||
|
static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][NUM_UNION_ROOM_CLASSES + 2] = {
|
||||||
|
[MALE] = {
|
||||||
|
OBJ_EVENT_GFX_COOLTRAINER_M,
|
||||||
|
OBJ_EVENT_GFX_BLACKBELT,
|
||||||
|
OBJ_EVENT_GFX_CAMPER,
|
||||||
|
OBJ_EVENT_GFX_YOUNGSTER,
|
||||||
|
OBJ_EVENT_GFX_BOY,
|
||||||
|
OBJ_EVENT_GFX_BUG_CATCHER,
|
||||||
|
OBJ_EVENT_GFX_MAN,
|
||||||
|
OBJ_EVENT_GFX_ROCKER
|
||||||
|
},
|
||||||
|
[FEMALE] = {
|
||||||
|
OBJ_EVENT_GFX_COOLTRAINER_F,
|
||||||
|
OBJ_EVENT_GFX_CHANNELER,
|
||||||
|
OBJ_EVENT_GFX_PICNICKER,
|
||||||
|
OBJ_EVENT_GFX_LASS,
|
||||||
|
OBJ_EVENT_GFX_WOMAN_1,
|
||||||
|
OBJ_EVENT_GFX_BATTLE_GIRL,
|
||||||
|
OBJ_EVENT_GFX_WOMAN_2,
|
||||||
|
OBJ_EVENT_GFX_BEAUTY
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const s16 sUnionRoomPlayerCoords[MAX_UNION_ROOM_LEADERS][2] = {
|
||||||
|
{ 4, 6},
|
||||||
|
{13, 8},
|
||||||
|
{10, 6},
|
||||||
|
{ 1, 8},
|
||||||
|
{13, 4},
|
||||||
|
{ 7, 4},
|
||||||
|
{ 1, 4},
|
||||||
|
{ 7, 8}
|
||||||
|
};
|
||||||
|
|
||||||
|
// If there's a group of players interacting in the Union Room, the group
|
||||||
|
// leader will be at one of the positions above and each member in the group
|
||||||
|
// will be at one of the offsets from that position below. The leader will
|
||||||
|
// be at the first offset (0,0), as they're at the center.
|
||||||
|
static const s8 sUnionRoomGroupOffsets[][2] = {
|
||||||
|
{ 0, 0}, // Center
|
||||||
|
{ 1, 0}, // Left
|
||||||
|
{ 0, -1}, // Top
|
||||||
|
{-1, 0}, // Right
|
||||||
|
{ 0, 1} // Bottom
|
||||||
|
};
|
||||||
|
|
||||||
|
static const u8 sOppositeFacingDirection[] = {
|
||||||
|
[DIR_NONE] = DIR_NONE,
|
||||||
|
[DIR_SOUTH] = DIR_NORTH,
|
||||||
|
[DIR_NORTH] = DIR_SOUTH,
|
||||||
|
[DIR_WEST] = DIR_EAST,
|
||||||
|
[DIR_EAST] = DIR_WEST
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compare to sUnionRoomGroupOffsets, the direction each group member
|
||||||
|
// needs to be facing in order to face the group leader in the center.
|
||||||
|
static const u8 sMemberFacingDirections[] = {
|
||||||
|
DIR_SOUTH, // Leader, but never read
|
||||||
|
DIR_WEST,
|
||||||
|
DIR_SOUTH,
|
||||||
|
DIR_EAST,
|
||||||
|
DIR_NORTH
|
||||||
|
};
|
||||||
|
|
||||||
|
static const u8 sUnionRoomLocalIds[] = {
|
||||||
|
LOCALID_UNION_ROOM_PLAYER_1,
|
||||||
|
LOCALID_UNION_ROOM_PLAYER_2,
|
||||||
|
LOCALID_UNION_ROOM_PLAYER_3,
|
||||||
|
LOCALID_UNION_ROOM_PLAYER_4,
|
||||||
|
LOCALID_UNION_ROOM_PLAYER_5,
|
||||||
|
LOCALID_UNION_ROOM_PLAYER_6,
|
||||||
|
LOCALID_UNION_ROOM_PLAYER_7,
|
||||||
|
LOCALID_UNION_ROOM_PLAYER_8
|
||||||
|
};
|
||||||
|
|
||||||
|
// Unused
|
||||||
|
static const u16 sHidePlayerFlags[] = {
|
||||||
|
FLAG_HIDE_UNION_ROOM_PLAYER_1,
|
||||||
|
FLAG_HIDE_UNION_ROOM_PLAYER_2,
|
||||||
|
FLAG_HIDE_UNION_ROOM_PLAYER_3,
|
||||||
|
FLAG_HIDE_UNION_ROOM_PLAYER_4,
|
||||||
|
FLAG_HIDE_UNION_ROOM_PLAYER_5,
|
||||||
|
FLAG_HIDE_UNION_ROOM_PLAYER_6,
|
||||||
|
FLAG_HIDE_UNION_ROOM_PLAYER_7,
|
||||||
|
FLAG_HIDE_UNION_ROOM_PLAYER_8
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool32 IsPlayerStandingStill(void)
|
||||||
|
{
|
||||||
|
if (gPlayerAvatar.tileTransitionState == T_TILE_CENTER || gPlayerAvatar.tileTransitionState == T_NOT_MOVING)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gender and trainer id are used to determine which sprite a player appears as
|
||||||
|
static u8 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id)
|
||||||
|
{
|
||||||
|
return sUnionRoomObjGfxIds[gender][id % NUM_UNION_ROOM_CLASSES];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetUnionRoomPlayerCoords(u32 leaderId, u32 memberId, s32 * x, s32 * y)
|
||||||
|
{
|
||||||
|
*x = sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + 7;
|
||||||
|
*y = sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 IsUnionRoomPlayerAt(u32 leaderId, u32 memberId, s32 x, s32 y)
|
||||||
|
{
|
||||||
|
if ((sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + MAP_OFFSET == x)
|
||||||
|
&& (sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + MAP_OFFSET == y))
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 IsUnionRoomPlayerHidden(u32 leaderId)
|
||||||
|
{
|
||||||
|
return FlagGet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HideUnionRoomPlayer(u32 leaderId)
|
||||||
|
{
|
||||||
|
FlagSet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ShowUnionRoomPlayer(u32 leaderId)
|
||||||
|
{
|
||||||
|
FlagClear(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetUnionRoomPlayerGfx(u32 leaderId, u32 gfxId)
|
||||||
|
{
|
||||||
|
VarSet(VAR_OBJ_GFX_ID_0 + leaderId, gfxId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateUnionRoomPlayerObjectEvent(u32 leaderId)
|
||||||
|
{
|
||||||
|
TrySpawnObjectEvent(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RemoveUnionRoomPlayerObjectEvent(u32 leaderId)
|
||||||
|
{
|
||||||
|
RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 SetUnionRoomPlayerEnterExitMovement(u32 leaderId, const u8 * movement)
|
||||||
|
{
|
||||||
|
u8 objectId;
|
||||||
|
struct ObjectEvent * object;
|
||||||
|
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
|
||||||
|
return FALSE;
|
||||||
|
object = &gObjectEvents[objectId];
|
||||||
|
if (ObjectEventIsMovementOverridden(object))
|
||||||
|
return FALSE;
|
||||||
|
if (ObjectEventSetHeldMovement(object, *movement))
|
||||||
|
{
|
||||||
|
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 387);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 leaderId)
|
||||||
|
{
|
||||||
|
u8 objectId;
|
||||||
|
struct ObjectEvent * object;
|
||||||
|
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
object = &gObjectEvents[objectId];
|
||||||
|
if (!ObjectEventClearHeldMovementIfFinished(object))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!ArePlayerFieldControlsLocked())
|
||||||
|
UnfreezeObjectEvent(object);
|
||||||
|
else
|
||||||
|
FreezeObjectEvent(object);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
sUnionObjRefreshTimer = 0;
|
||||||
|
sUnionObjWork = players;
|
||||||
|
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 442)
|
||||||
|
for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++)
|
||||||
|
{
|
||||||
|
players[i].state = 0;
|
||||||
|
players[i].gfxId = 0;
|
||||||
|
players[i].animState = 0;
|
||||||
|
players[i].schedAnim = UNION_ROOM_SPAWN_NONE;
|
||||||
|
}
|
||||||
|
return CreateTask_AnimateUnionRoomPlayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const u8 sMovement_UnionPlayerExit[2] = {
|
||||||
|
MOVEMENT_ACTION_FLY_UP,
|
||||||
|
MOVEMENT_ACTION_STEP_END
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool32 AnimateUnionRoomPlayerDespawn(s8 * state, u32 leaderId, struct UnionRoomObject * object)
|
||||||
|
{
|
||||||
|
switch (*state)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerExit) == TRUE)
|
||||||
|
{
|
||||||
|
HideUnionRoomPlayer(leaderId);
|
||||||
|
(*state)++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (TryReleaseUnionRoomPlayerObjectEvent(leaderId))
|
||||||
|
{
|
||||||
|
RemoveUnionRoomPlayerObjectEvent(leaderId);
|
||||||
|
HideUnionRoomPlayer(leaderId);
|
||||||
|
*state = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const u8 sMovement_UnionPlayerEnter[2] = {
|
||||||
|
MOVEMENT_ACTION_FLY_DOWN,
|
||||||
|
MOVEMENT_ACTION_STEP_END
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 leaderId, struct UnionRoomObject * object)
|
||||||
|
{
|
||||||
|
s16 x, y;
|
||||||
|
|
||||||
|
switch (*state)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (!IsPlayerStandingStill())
|
||||||
|
break;
|
||||||
|
PlayerGetDestCoords(&x, &y);
|
||||||
|
if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE)
|
||||||
|
break;
|
||||||
|
player_get_pos_including_state_based_drift(&x, &y);
|
||||||
|
if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE)
|
||||||
|
break;
|
||||||
|
SetUnionRoomPlayerGfx(leaderId, object->gfxId);
|
||||||
|
CreateUnionRoomPlayerObjectEvent(leaderId);
|
||||||
|
ShowUnionRoomPlayer(leaderId);
|
||||||
|
(*state)++;
|
||||||
|
// fallthrough
|
||||||
|
case 3: // incorrect?
|
||||||
|
if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerEnter) == 1)
|
||||||
|
(*state)++;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (TryReleaseUnionRoomPlayerObjectEvent(leaderId))
|
||||||
|
{
|
||||||
|
*state = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 SpawnGroupLeader(u32 leaderId, u32 gender, u32 id)
|
||||||
|
{
|
||||||
|
struct UnionRoomObject * object = &sUnionObjWork[leaderId];
|
||||||
|
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 561)
|
||||||
|
object->schedAnim = UNION_ROOM_SPAWN_IN;
|
||||||
|
object->gfxId = GetUnionRoomPlayerGraphicsId(gender, id);
|
||||||
|
|
||||||
|
if (object->state == 0)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 DespawnGroupLeader(u32 leaderId)
|
||||||
|
{
|
||||||
|
struct UnionRoomObject * object = &sUnionObjWork[leaderId];
|
||||||
|
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 577)
|
||||||
|
object->schedAnim = UNION_ROOM_SPAWN_OUT;
|
||||||
|
|
||||||
|
if (object->state == 1)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AnimateUnionRoomPlayer(u32 leaderId, struct UnionRoomObject * object)
|
||||||
|
{
|
||||||
|
switch (object->state)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (object->schedAnim == UNION_ROOM_SPAWN_IN)
|
||||||
|
{
|
||||||
|
object->state = 2;
|
||||||
|
object->animState = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// fallthrough
|
||||||
|
case 2:
|
||||||
|
if (!IsUnionRoomPlayerInvisible(leaderId, 0) && object->schedAnim == UNION_ROOM_SPAWN_OUT)
|
||||||
|
{
|
||||||
|
object->state = 0;
|
||||||
|
object->animState = 0;
|
||||||
|
RemoveUnionRoomPlayerObjectEvent(leaderId);
|
||||||
|
HideUnionRoomPlayer(leaderId);
|
||||||
|
}
|
||||||
|
else if (AnimateUnionRoomPlayerSpawn(&object->animState, leaderId, object) == TRUE)
|
||||||
|
{
|
||||||
|
object->state = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (object->schedAnim != UNION_ROOM_SPAWN_OUT)
|
||||||
|
break;
|
||||||
|
object->state = 3;
|
||||||
|
object->animState = 0;
|
||||||
|
// fallthrough
|
||||||
|
case 3:
|
||||||
|
if (AnimateUnionRoomPlayerDespawn(&object->animState, leaderId, object) == TRUE)
|
||||||
|
object->state = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
object->schedAnim = UNION_ROOM_SPAWN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Task_AnimateUnionRoomPlayers(u8 taskId)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 643)
|
||||||
|
for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++)
|
||||||
|
AnimateUnionRoomPlayer(i, &sUnionObjWork[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 CreateTask_AnimateUnionRoomPlayers(void)
|
||||||
|
{
|
||||||
|
if (FuncIsActiveTask(Task_AnimateUnionRoomPlayers) == TRUE)
|
||||||
|
{
|
||||||
|
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 655)
|
||||||
|
return NUM_TASKS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return CreateTask(Task_AnimateUnionRoomPlayers, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DestroyTask_AnimateUnionRoomPlayers(void)
|
||||||
|
{
|
||||||
|
u8 taskId = FindTaskIdByFunc(Task_AnimateUnionRoomPlayers);
|
||||||
|
if (taskId < NUM_TASKS)
|
||||||
|
DestroyTask(taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyUnionRoomPlayerObjects(void)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++)
|
||||||
|
{
|
||||||
|
if (!IsUnionRoomPlayerHidden(i))
|
||||||
|
{
|
||||||
|
RemoveUnionRoomPlayerObjectEvent(i);
|
||||||
|
HideUnionRoomPlayer(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sUnionObjWork = NULL;
|
||||||
|
DestroyTask_AnimateUnionRoomPlayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateUnionRoomPlayerSprites(u8 * spriteIds, s32 leaderId)
|
||||||
|
{
|
||||||
|
s32 memberId;
|
||||||
|
|
||||||
|
for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++)
|
||||||
|
{
|
||||||
|
s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId);
|
||||||
|
spriteIds[id] = CreateVirtualObject(OBJ_EVENT_GFX_MAN,
|
||||||
|
id - UR_SPRITE_START_ID,
|
||||||
|
sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0],
|
||||||
|
sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1],
|
||||||
|
3, 1);
|
||||||
|
SetVirtualObjectInvisibility(id - UR_SPRITE_START_ID, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyUnionRoomPlayerSprites(u8 *spriteIds)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
for (i = 0; i < NUM_UNION_ROOM_SPRITES; i++)
|
||||||
|
DestroySprite(&gSprites[spriteIds[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the impassable metatiles around the group leaders that get set
|
||||||
|
// to prevent the player from walking through the group member sprites.
|
||||||
|
void MakeGroupAssemblyAreasPassable(void)
|
||||||
|
{
|
||||||
|
s32 leaderId, memberId, x, y;
|
||||||
|
for (leaderId = 0; leaderId < MAX_UNION_ROOM_LEADERS; leaderId++)
|
||||||
|
{
|
||||||
|
for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++)
|
||||||
|
{
|
||||||
|
GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y);
|
||||||
|
MapGridSetMetatileImpassabilityAt(x, y, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 GetNewFacingDirectionForUnionRoomPlayer(u32 memberId, u32 leaderId, struct RfuGameData * gameData)
|
||||||
|
{
|
||||||
|
if (memberId != 0) // If not leader
|
||||||
|
return sMemberFacingDirections[memberId];
|
||||||
|
else if (gameData->activity == (ACTIVITY_CHAT | IN_UNION_ROOM))
|
||||||
|
return DIR_SOUTH;
|
||||||
|
else
|
||||||
|
return DIR_EAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 memberId)
|
||||||
|
{
|
||||||
|
return IsVirtualObjectInvisible(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SpawnGroupMember(u32 leaderId, u32 memberId, u8 graphicsId, struct RfuGameData * gameData)
|
||||||
|
{
|
||||||
|
s32 x, y;
|
||||||
|
s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId);
|
||||||
|
if (IsUnionRoomPlayerInvisible(leaderId, memberId) == TRUE)
|
||||||
|
{
|
||||||
|
SetVirtualObjectInvisibility(id - UR_SPRITE_START_ID, FALSE);
|
||||||
|
SetVirtualObjectSpriteAnim(id - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_IN);
|
||||||
|
}
|
||||||
|
SetVirtualObjectGraphics(id - UR_SPRITE_START_ID, graphicsId);
|
||||||
|
SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, gameData));
|
||||||
|
GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y);
|
||||||
|
MapGridSetMetatileImpassabilityAt(x, y, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DespawnGroupMember(u32 leaderId, u32 memberId)
|
||||||
|
{
|
||||||
|
s32 x, y;
|
||||||
|
SetVirtualObjectSpriteAnim(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_OUT);
|
||||||
|
GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y);
|
||||||
|
MapGridSetMetatileImpassabilityAt(x, y, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AssembleGroup(u32 leaderId, struct RfuGameData * gameData)
|
||||||
|
{
|
||||||
|
s16 x, y, x2, y2;
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
PlayerGetDestCoords(&x, &y);
|
||||||
|
player_get_pos_including_state_based_drift(&x2, &y2);
|
||||||
|
if (IsVirtualObjectInvisible(UR_PLAYER_SPRITE_ID(leaderId, 0) - UR_SPRITE_START_ID) == TRUE)
|
||||||
|
{
|
||||||
|
if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE || IsUnionRoomPlayerAt(leaderId, 0, x2, y2) == TRUE)
|
||||||
|
return;
|
||||||
|
SpawnGroupMember(leaderId, 0, GetUnionRoomPlayerGraphicsId(gameData->playerGender, gameData->compatibility.playerTrainerId[0]), gameData);
|
||||||
|
}
|
||||||
|
for (i = 1; i < MAX_RFU_PLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (gameData->partnerInfo[i - 1] == 0)
|
||||||
|
DespawnGroupMember(leaderId, i);
|
||||||
|
else if (IsUnionRoomPlayerAt(leaderId, i, x, y) == FALSE && IsUnionRoomPlayerAt(leaderId, i, x2, y2) == FALSE)
|
||||||
|
SpawnGroupMember(leaderId, i, GetUnionRoomPlayerGraphicsId((gameData->partnerInfo[i - 1] >> PINFO_GENDER_SHIFT) & 1,
|
||||||
|
gameData->partnerInfo[i - 1] & PINFO_TID_MASK),
|
||||||
|
gameData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SpawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameData)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
switch (gameData->activity)
|
||||||
|
{
|
||||||
|
case ACTIVITY_NONE | IN_UNION_ROOM:
|
||||||
|
case ACTIVITY_PLYRTALK | IN_UNION_ROOM:
|
||||||
|
SpawnGroupLeader(leaderId, gameData->playerGender, gameData->compatibility.playerTrainerId[0]);
|
||||||
|
for (i = 0; i < MAX_RFU_PLAYERS; i++)
|
||||||
|
DespawnGroupMember(leaderId, i);
|
||||||
|
break;
|
||||||
|
case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM:
|
||||||
|
case ACTIVITY_TRADE | IN_UNION_ROOM:
|
||||||
|
case ACTIVITY_CHAT | IN_UNION_ROOM:
|
||||||
|
case ACTIVITY_CARD | IN_UNION_ROOM:
|
||||||
|
case ACTIVITY_ACCEPT | IN_UNION_ROOM:
|
||||||
|
case ACTIVITY_DECLINE | IN_UNION_ROOM:
|
||||||
|
case ACTIVITY_NPCTALK | IN_UNION_ROOM:
|
||||||
|
DespawnGroupLeader(leaderId);
|
||||||
|
AssembleGroup(leaderId, gameData);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 979)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DespawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameData)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
DespawnGroupLeader(leaderId);
|
||||||
|
for (i = 0; i < MAX_RFU_PLAYERS; i++)
|
||||||
|
DespawnGroupMember(leaderId, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom * uroom)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
struct RfuPlayer * leaders;
|
||||||
|
sUnionObjRefreshTimer = 0;
|
||||||
|
for (i = 0, leaders = uroom->playerList->players; i < MAX_UNION_ROOM_LEADERS; i++)
|
||||||
|
{
|
||||||
|
if (leaders[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN)
|
||||||
|
SpawnGroupLeaderAndMembers(i, &leaders[i].rfu.data);
|
||||||
|
else if (leaders[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT)
|
||||||
|
DespawnGroupLeaderAndMembers(i, &leaders[i].rfu.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom)
|
||||||
|
{
|
||||||
|
sUnionObjRefreshTimer = 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom)
|
||||||
|
{
|
||||||
|
if (++sUnionObjRefreshTimer > 300)
|
||||||
|
UpdateUnionRoomPlayerSprites(uroom);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *list, s16 *memberIdPtr, s16 *leaderIdPtr, u8 *spriteIds)
|
||||||
|
{
|
||||||
|
s16 x, y;
|
||||||
|
s32 leaderId, memberId;
|
||||||
|
struct RfuPlayer * leaders;
|
||||||
|
if (!IsPlayerStandingStill())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
|
||||||
|
for (leaderId = 0, leaders = list->players; leaderId < MAX_UNION_ROOM_LEADERS; leaderId++)
|
||||||
|
{
|
||||||
|
for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++)
|
||||||
|
{
|
||||||
|
s32 objId = UR_PLAYER_SPRITE_ID(leaderId, memberId);
|
||||||
|
|
||||||
|
// Is the player in front of a group member position?
|
||||||
|
if (x != sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + 7)
|
||||||
|
continue;
|
||||||
|
if (y != sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + 7)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Has a group member spawned at this position?
|
||||||
|
if (IsVirtualObjectInvisible(objId - UR_SPRITE_START_ID) != FALSE)
|
||||||
|
continue;
|
||||||
|
if (IsVirtualObjectAnimating(objId - UR_SPRITE_START_ID) != FALSE)
|
||||||
|
continue;
|
||||||
|
if (leaders[leaderId].groupScheduledAnim != UNION_ROOM_SPAWN_IN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Interaction attempt successful, face player
|
||||||
|
SetUnionRoomObjectFacingDirection(memberId, leaderId, sOppositeFacingDirection[GetPlayerFacingDirection()]);
|
||||||
|
*memberIdPtr = memberId;
|
||||||
|
*leaderIdPtr = leaderId;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetUnionRoomObjectFacingDirection(s32 memberId, s32 leaderId, u8 direction)
|
||||||
|
{
|
||||||
|
TurnVirtualObject(MAX_RFU_PLAYERS * leaderId - UR_SPRITE_START_ID + memberId, direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateUnionRoomMemberFacing(u32 memberId, u32 leaderId, struct RfuPlayerList *list)
|
||||||
|
{
|
||||||
|
return SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, &list->players[leaderId].rfu.data));
|
||||||
|
}
|
||||||
+1
-1
@@ -102,7 +102,7 @@
|
|||||||
.include "src/help_message.o"
|
.include "src/help_message.o"
|
||||||
.include "src/quest_log_events.o"
|
.include "src/quest_log_events.o"
|
||||||
.include "src/union_room.o"
|
.include "src/union_room.o"
|
||||||
.include "src/rfu_union_tool.o"
|
.include "src/union_room_player_avatar.o"
|
||||||
.include "src/union_room_battle.o"
|
.include "src/union_room_battle.o"
|
||||||
.include "src/pokemon_special_anim.o"
|
.include "src/pokemon_special_anim.o"
|
||||||
.include "src/party_menu.o"
|
.include "src/party_menu.o"
|
||||||
|
|||||||
Reference in New Issue
Block a user