Merge remote-tracking branch 'merrp_origin/followers-expanded-id' into _RHH/pr/upcoming/merrpFollowers

# Conflicts:
#	README.md
#	data/field_effect_scripts.s
#	data/maps/AncientTomb/scripts.inc
#	data/maps/DesertRuins/scripts.inc
#	data/maps/IslandCave/scripts.inc
#	data/scripts/follower.inc
#	graphics/object_events/pics/pokemon/wailord.png
#	graphics/object_events/pics/pokemon_old/substitute.png
#	include/constants/event_objects.h
#	include/global.h
#	remote_build.sh
#	spritesheet_rules.mk
#	src/bike.c
#	src/data/object_events/object_event_anims.h
#	src/data/object_events/object_event_graphics.h
#	src/data/object_events/object_event_graphics_info_followers.h
#	src/data/object_events/object_event_pic_tables.h
#	src/event_object_movement.c
#	src/field_effect_helpers.c
#	src/field_screen_effect.c
#	src/overworld.c
#	src/palette.c
#	src/pokemon_summary_screen.c
#	src/scrcmd.c
#	src/trainer_see.c
This commit is contained in:
Eduardo Quezada 2024-02-17 23:40:08 -03:00
commit 124c17d315
63 changed files with 1058 additions and 510 deletions

View file

@ -650,3 +650,4 @@ BattleFrontier_BattlePalaceLobby_Text_ExplainRulesWhenInDanger:
.string "nature when it is in trouble.\p"
.string "If a POKéMON begins behaving oddly\n"
.string "in a pinch, watch it carefully.$"

View file

@ -434,3 +434,4 @@ BattleFrontier_BattlePikeLobby_Text_ExplainMonOrderRules:
.string "changed.\p"
.string "The sequence must be set before\n"
.string "starting your challenge.$"

View file

@ -904,3 +904,4 @@ BattleFrontier_BattlePyramidLobby_Text_ExplainBagRules:
.string "of ten kinds of items.\p"
.string "The contents of the BATTLE BAG are\n"
.string "lost if you fail in your quest.$"

View file

@ -530,3 +530,4 @@ RusturfTunnel_Text_MikePostBattle:
.string "They halted development here to\n"
.string "protect POKéMON, right?\l"
.string "There's a feel-good story!$"

View file

@ -30,17 +30,6 @@ EventScript_Follower::
bufferlivemonnickname 0
playfirstmoncry
callfunc ScrFunc_getfolloweraction
checkpartymove MOVE_FLY
compare VAR_RESULT 6
goto_if_eq EventScript_FollowerEnd
bufferlivemonnickname 0
msgbox gText_WantsToFly, MSGBOX_YESNO
switch VAR_RESULT
case NO, EventScript_FollowerEnd
case YES, EventScript_FollowerFly
case MULTI_B_PRESSED, EventScript_FollowerEnd
EventScript_FollowerFly::
callfunc ScrFunc_followerfly
EventScript_FollowerEnd::
waitfieldeffect FLDEFF_EMOTE
release

View file

@ -52,7 +52,6 @@ static void SortSprites(u32 *spritePriorities, s32 n);
static u8 CreateSpriteAt(u8 index, const struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority);
static void ResetOamMatrices(void);
static void ResetSprite(struct Sprite *sprite);
static s16 AllocSpriteTiles(u16 tileCount);
static void RequestSpriteFrameImageCopy(u16 index, u16 tileNum, const struct SpriteFrameImage *images);
static void ResetAllSprites(void);
static void BeginAnim(struct Sprite *sprite);

View file

@ -304,6 +304,7 @@ void SetOamMatrixRotationScaling(u8 matrixNum, s16 xScale, s16 yScale, u16 rotat
u16 LoadSpriteSheet(const struct SpriteSheet *sheet);
u16 LoadSpriteSheetByTemplate(const struct SpriteTemplate *template, u32 frame, s32 offset);
void LoadSpriteSheets(const struct SpriteSheet *sheets);
s16 AllocSpriteTiles(u16 tileCount);
u16 AllocTilesForSpriteSheet(struct SpriteSheet *sheet);
void AllocTilesForSpriteSheets(struct SpriteSheet *sheets);
void LoadTilesForSpriteSheet(const struct SpriteSheet *sheet);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -278,6 +278,11 @@
#define ANIM_RUN_WEST (ANIM_STD_COUNT + 2)
#define ANIM_RUN_EAST (ANIM_STD_COUNT + 3)
#define ANIM_EXIT_POKEBALL_FAST_SOUTH (ANIM_STD_COUNT + 0)
#define ANIM_EXIT_POKEBALL_FAST_NORTH (ANIM_STD_COUNT + 1)
#define ANIM_EXIT_POKEBALL_FAST_WEST (ANIM_STD_COUNT + 2)
#define ANIM_EXIT_POKEBALL_FAST_EAST (ANIM_STD_COUNT + 3)
#define ANIM_BUNNY_HOP_BACK_WHEEL_SOUTH (ANIM_STD_COUNT + 0)
#define ANIM_BUNNY_HOP_BACK_WHEEL_NORTH (ANIM_STD_COUNT + 1)
#define ANIM_BUNNY_HOP_BACK_WHEEL_WEST (ANIM_STD_COUNT + 2)

View file

@ -300,6 +300,10 @@
// (You should not use 48x48 sprites/tables for compressed gfx)
// 16x32, 32x32, 64x64 etc are fine
// Followers will emerge from the pokeball they are stored in,
// instead of a normal pokeball
#define OW_MON_POKEBALLS TRUE
#define SHADOW_SIZE_S 0
#define SHADOW_SIZE_M 1
#define SHADOW_SIZE_L 2
@ -392,6 +396,44 @@
#define OBJ_EVENT_PAL_TAG_RS_BRENDAN 0x1122
#define OBJ_EVENT_PAL_TAG_RS_MAY 0x1123
#define OBJ_EVENT_PAL_TAG_DYNAMIC 0x1124
#if OW_MON_POKEBALLS
// Vanilla
#define OBJ_EVENT_PAL_TAG_BALL_MASTER 0x1150
#define OBJ_EVENT_PAL_TAG_BALL_ULTRA 0x1151
#define OBJ_EVENT_PAL_TAG_BALL_GREAT 0x1152
#define OBJ_EVENT_PAL_TAG_BALL_SAFARI 0x1153
#define OBJ_EVENT_PAL_TAG_BALL_NET 0x1154
#define OBJ_EVENT_PAL_TAG_BALL_DIVE 0x1155
#define OBJ_EVENT_PAL_TAG_BALL_NEST 0x1156
#define OBJ_EVENT_PAL_TAG_BALL_REPEAT 0x1157
#define OBJ_EVENT_PAL_TAG_BALL_TIMER 0x1158
#define OBJ_EVENT_PAL_TAG_BALL_LUXURY 0x1159
#define OBJ_EVENT_PAL_TAG_BALL_PREMIER 0x115A
// Gen IV/Sinnoh
#define OBJ_EVENT_PAL_TAG_BALL_DUSK 0x115B
#define OBJ_EVENT_PAL_TAG_BALL_HEAL 0x115C
#define OBJ_EVENT_PAL_TAG_BALL_QUICK 0x115D
#define OBJ_EVENT_PAL_TAG_BALL_CHERISH 0x115E
#define OBJ_EVENT_PAL_TAG_BALL_PARK 0x115F
// Gen II/Johto Apricorns
#define OBJ_EVENT_PAL_TAG_BALL_FAST 0x1160
#define OBJ_EVENT_PAL_TAG_BALL_LEVEL 0x1161
#define OBJ_EVENT_PAL_TAG_BALL_LURE 0x1162
#define OBJ_EVENT_PAL_TAG_BALL_HEAVY 0x1163
#define OBJ_EVENT_PAL_TAG_BALL_LOVE 0x1164
#define OBJ_EVENT_PAL_TAG_BALL_FRIEND 0x1165
#define OBJ_EVENT_PAL_TAG_BALL_MOON 0x1166
#define OBJ_EVENT_PAL_TAG_BALL_SPORT 0x1167
// Gen V
#define OBJ_EVENT_PAL_TAG_BALL_DREAM 0x1168
// Gen VII
#define OBJ_EVENT_PAL_TAG_BALL_BEAST 0x1169
// Gen VIII
#define OBJ_EVENT_PAL_TAG_BALL_STRANGE 0x116A
#endif
// Used as a placeholder follower graphic
#define OBJ_EVENT_PAL_TAG_SUBSTITUTE 0x7611
#define OBJ_EVENT_PAL_TAG_EMOTES 0x8002
// Not a real OW palette tag; used for the white flash applied to followers
#define OBJ_EVENT_PAL_TAG_WHITE (OBJ_EVENT_PAL_TAG_NONE - 1)

View file

@ -113,7 +113,6 @@
#define FLDEFFOBJ_BUBBLES 34
#define FLDEFFOBJ_SMALL_SPARKLE 35
#define FLDEFFOBJ_RAYQUAZA 36
#define FLDEFFOBJ_TRACKS_SLITHER 37
#define FLDEFFOBJ_TRACKS_SPOT 38
#define FLDEFFOBJ_TRACKS_BUG 39
@ -131,11 +130,10 @@
#define FLDEFF_PAL_TAG_HOF_MONITOR 0x1010
#define FLDEFF_PAL_TAG_UNKNOWN 0x1011
// Duplicates of event_object_movement tags
#define FLDEFF_PAL_TAG_MAY 0x1110 // OBJ_EVENT_PAL_TAG_MAY
#define FLDEFF_PAL_TAG_BRENDAN 0x1100 // OBJ_EVENT_PAL_TAG_BRENDAN
#define FLDEFF_PAL_TAG_NPC_1 0x1103 // OBJ_EVENT_PAL_TAG_NPC_1
#define FLDEFF_PAL_TAG_NPC_2 0x1104 // OBJ_EVENT_PAL_TAG_NPC_2
#define FLDEFF_PAL_TAG_MAY 0x1110 // OBJ_EVENT_PAL_TAG_MAY
#define FLDEFF_PAL_TAG_BRENDAN 0x1100 // OBJ_EVENT_PAL_TAG_BRENDAN
#define FLDEFF_PAL_TAG_NPC_1 0x1103 // OBJ_EVENT_PAL_TAG_NPC_1
#define FLDEFF_PAL_TAG_NPC_2 0x1104 // OBJ_EVENT_PAL_TAG_NPC_2
#endif // GUARD_FIELD_EFFECT_CONSTANTS_H

View file

@ -8,6 +8,8 @@ extern u8 ALIGNED(4) gDecompressionBuffer[0x4000];
void LZDecompressWram(const u32 *src, void *dest);
void LZDecompressVram(const u32 *src, void *dest);
bool32 IsLZ77Data(const void *ptr, u32 minSize, u32 maxSize);
u16 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src);
u16 LoadCompressedSpriteSheetByTemplate(const struct SpriteTemplate *template, s32 offset);
void LoadCompressedSpriteSheetOverrideBuffer(const struct CompressedSpriteSheet *src, void *buffer);

View file

@ -293,6 +293,7 @@ void MovementType_FollowPlayer(struct Sprite *);
u8 GetSlideMovementAction(u32);
u8 GetJumpMovementAction(u32);
u8 GetJump2MovementAction(u32);
u8 CopySprite(struct Sprite *sprite, s16 x, s16 y, u8 subpriority);
u8 CreateCopySpriteAt(struct Sprite *sprite, s16 x, s16 y, u8 subpriority);
u8 MovementType_WanderAround_Step0(struct ObjectEvent *, struct Sprite *);

View file

@ -16,81 +16,67 @@ enum {
FOLLOWER_EMOTION_LENGTH,
};
// This struct is optimized for size
// Each "section" can be used to combine multiple conditions,
// i.e, species and map
// Just set the flags accordingly and use the right union member
struct __attribute__((packed)) FollowerMsgInfoExtended {
// Can be either 3 bytes, a u16 and a byte, or a 24-bit value
union __attribute__((packed)) MsgConditionData {
u8 bytes[3];
struct __attribute__((packed)) {
u16 hw;
u8 b;
} split;
u32 raw:24;
}; // size = 0x3
struct __attribute__((packed)) MsgCondition {
u32 type:8;
union MsgConditionData data;
}; // size = 0x4
struct FollowerMsgInfoExtended {
const u8 *text;
const u8 *script;
union __attribute__((packed)) {
u16 species:10;
struct __attribute__((packed)) {
u16 type1:5;
u16 type2:5; // if >= NUMBER_OF_MON_TYPES, inverts checking for type1
} types;
u16 status:10;
} st;
u16 stFlags:2; // 0 = no matching, 1 = species matching, 2 = type matching, 3 = status
u16 emotion:4; // emotion for this message
union __attribute__((packed)) {
struct __attribute__((packed)) {
u16 mapSec:8;
} mapSec;
struct __attribute__((packed)) {
u16 mapNum:8;
u16 mapGroup:6;
} map;
struct __attribute__((packed)) {
u16 behavior1:8;
u16 behavior2:6; // not full; only goes up to 0x3F
} mb;
} mm;
u16 mmFlags:2; // 1 = map sec, 2 = map, 3 = metatile behavior
union __attribute__((packed)) {
struct __attribute__((packed)) {
u16 weather1:5;
u16 weather2:5;
} weather;
u16 song:10;
u16 timeOfDay:10;
} wt;
u16 wtFlags:2; // 1 = weather matching, 2 = song, 3 = time
u16 weight:3;
u32 emotion:4;
u32 weight:3;
// if set, `text` is treated as an array of up to 4 texts instead
u16 textSpread:1;
// which one is displayed is chosen at random
u32 textSpread:1;
u32 orFlag:1; // if set, *any* condition can match, rather than all
union __attribute__((packed)) {
struct __attribute__((packed)) {
u16 behavior:8;
u16 distance:6;
} mb;
} near;
u16 nearFlags:2; // 1 = mb within '+'-shaped distance away
};
struct MsgCondition conditions[5];
}; // size = 8 + 4 + 5*4 = 32, 0x20
enum {
ST_FLAGS_SPECIES = 1,
ST_FLAGS_TYPE,
ST_FLAGS_STATUS,
};
// Follower message conditions
#define MSG_COND_NONE 0
#define MSG_COND_SPECIES 1
#define MSG_COND_TYPE 2
#define MSG_COND_STATUS 3
#define MSG_COND_MAPSEC 4
#define MSG_COND_MAP 5
#define MSG_COND_ON_MB 6
#define MSG_COND_WEATHER 7
#define MSG_COND_MUSIC 8
#define MSG_COND_TIME_OF_DAY 9
#define MSG_COND_NEAR_MB 10
enum {
MM_FLAGS_MAPSEC = 1,
MM_FLAGS_MAP,
MM_FLAGS_MB, // (m)etatile (b)ehavior
};
#define MATCH_U24(type, value) {type, {.raw = value}}
#define MATCH_U16(type, value1, value2) {type, {.split = {.hw = value1, .b = value2}}}
#define MATCH_U8(type, v1, v2, v3) {type, {.bytes = {v1, v2, v3}}}
enum {
WT_FLAGS_WEATHER = 1,
WT_FLAGS_MUSIC,
WT_FLAGS_TIME,
};
#define NEAR_FLAGS_MB 1
#define MATCH_SPECIES(species) MATCH_U24(MSG_COND_SPECIES, species)
#define MATCH_TYPES(type1, type2) MATCH_U8(MSG_COND_TYPE, type1, type2, 0)
// Checks that follower has *neither* of the two types
#define MATCH_NOT_TYPES(type1, type2) MATCH_U8(MSG_COND_TYPE, type1, type2, TYPE_NONE)
#define MATCH_STATUS(status) MATCH_U24(MSG_COND_STATUS, status)
#define MATCH_MAPSEC(mapsec) MATCH_U24(MSG_COND_MAPSEC, mapsec)
#define MATCH_MAP_RAW(mapGroup, mapNum) MATCH_U8(MSG_COND_MAP, mapGroup, mapNum, 0)
#define MATCH_MAP(map) MATCH_U8(MSG_COND_MAP, MAP_GROUP(map), MAP_NUM(map), 0)
// Matches one of two metatile behaviors follower is standing on
#define MATCH_ON_MB(mb1, mb2) MATCH_U8(MSG_COND_ON_MB, mb1, mb2, 0)
#define MATCH_WEATHER(weather1, weather2) MATCH_U8(MSG_COND_WEATHER, weather1, weather2, 0)
#define MATCH_MUSIC(song) MATCH_U24(MSG_COND_MUSIC, song)
#define MATCH_TIME_OF_DAY(time) MATCH_U24(MSG_COND_TIME_OF_DAY, time)
// Matches metatile behavior within a '+' shape of size `distance`
#define MATCH_NEAR_MB(mb, distance) MATCH_U8(MSG_COND_NEAR_MB, mb, distance, 0)
enum {
COND_MSG_CELEBI,
@ -125,5 +111,6 @@ enum {
};
extern const struct FollowerMsgInfoExtended gFollowerConditionalMessages[COND_MSG_COUNT];
extern const struct FollowerMessagePool gFollowerBasicMessages[FOLLOWER_EMOTION_LENGTH];
#endif //GUARD_FOLLOWER_HELPER_H

View file

@ -264,6 +264,11 @@ enum {
#define PLAYER_AVATAR_FLAG_FORCED_MOVE (1 << 6)
#define PLAYER_AVATAR_FLAG_DASH (1 << 7)
#define PLAYER_AVATAR_FLAG_BIKE (PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE)
// Player avatar flags for which follower pokemon are hidden
#define FOLLOWER_INVISIBLE_FLAGS (PLAYER_AVATAR_FLAG_SURFING | PLAYER_AVATAR_FLAG_UNDERWATER | \
PLAYER_AVATAR_FLAG_BIKE | PLAYER_AVATAR_FLAG_FORCED_MOVE)
enum
{
ACRO_BIKE_NORMAL,

View file

@ -613,6 +613,7 @@ extern const struct MoveInfo gMovesInfo[];
extern const u8 gFacilityClassToPicIndex[];
extern const u8 gFacilityClassToTrainerClass[];
extern const struct SpeciesInfo gSpeciesInfo[];
extern const void* const gFollowerPalettes[NUM_SPECIES][2];
extern const u32 gExperienceTables[][MAX_LEVEL + 1];
extern const u8 gPPUpGetMask[];
extern const u8 gPPUpClearMask[];

View file

@ -731,6 +731,9 @@ $(FLDEFFGFXDIR)/secret_power_tree.4bpp: %.4bpp: %.png
$(FLDEFFGFXDIR)/record_mix_lights.4bpp: %.4bpp: %.png
$(GFX) $< $@ -mwidth 4 -mheight 1
$(OBJEVENTGFXDIR)/pokemon/substitute.4bpp: %.4bpp: %.png
$(GFX) $< $@ -mwidth 4 -mheight 4
$(POKEMONGFXDIR)/bulbasaur/follower.4bpp: %.4bpp: %.png
$(GFX) $< $@ -mwidth 4 -mheight 4
@ -3990,5 +3993,8 @@ $(POKEMONGFXDIR)/marowak/alolan/follower.4bpp: %.4bpp: %.png
$(MISCGFXDIR)/emotes.4bpp: %.4bpp: %.png
$(GFX) $< $@ -mwidth 2 -mheight 2
# All pokeballs are 16x32
$(OBJEVENTGFXDIR)/misc/ball_%.4bpp: $(OBJEVENTGFXDIR)/misc/ball_%.png ; $(GFX) $< $@ -mwidth 2 -mheight 4
graphics/door_anims/battle_tower_multi_corridor.4bpp: %.4bpp: %.png
$(GFX) $< $@ -mwidth 2 -mheight 4

View file

@ -28,13 +28,13 @@ static const struct SpriteFrameImage sPicTable_ShadowExtraLarge[] = {
obj_frame_tiles(gFieldEffectObjectPic_ShadowExtraLarge),
};
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowSmall = {0xFFFF, TAG_WEATHER_START, &gObjectEventBaseOam_8x8, sAnimTable_Shadow, sPicTable_ShadowSmall, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowSmall = {TAG_NONE, TAG_WEATHER_START, &gObjectEventBaseOam_8x8, sAnimTable_Shadow, sPicTable_ShadowSmall, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowMedium = {0xFFFF, TAG_WEATHER_START, &gObjectEventBaseOam_16x8, sAnimTable_Shadow, sPicTable_ShadowMedium, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowMedium = {TAG_NONE, TAG_WEATHER_START, &gObjectEventBaseOam_16x8, sAnimTable_Shadow, sPicTable_ShadowMedium, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowLarge = {0xFFFF, TAG_WEATHER_START, &gObjectEventBaseOam_32x8, sAnimTable_Shadow, sPicTable_ShadowLarge, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowLarge = {TAG_NONE, TAG_WEATHER_START, &gObjectEventBaseOam_32x8, sAnimTable_Shadow, sPicTable_ShadowLarge, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowExtraLarge = {0xFFFF, TAG_WEATHER_START, &gObjectEventBaseOam_64x32, sAnimTable_Shadow, sPicTable_ShadowExtraLarge, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowExtraLarge = {TAG_NONE, TAG_WEATHER_START, &gObjectEventBaseOam_64x32, sAnimTable_Shadow, sPicTable_ShadowExtraLarge, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
static const struct SpriteFrameImage sPicTable_TallGrass[] = {
overworld_frame(gFieldEffectObjectPic_TallGrass, 2, 2, 0),

View file

@ -12,9 +12,9 @@ const u8 gMonIcon_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mark/ico
#if P_FOOTPRINTS
const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mark/footprint.1bpp");
#endif //P_FOOTPRINTS
//#if P_FOLLOWERS
const u32 gObjectEventPic_None[] = INCBIN_COMP("graphics/pokemon/porygon/follower.4bpp");
//#endif //P_FOLLOWERS
#if P_FOLLOWERS
const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_mark/follower.4bpp");
#endif //P_FOLLOWERS
#if P_FAMILY_BULBASAUR
const u32 gMonFrontPic_Bulbasaur[] = INCBIN_U32("graphics/pokemon/bulbasaur/anim_front.4bpp.lz");

View file

@ -217,6 +217,12 @@ static const union AnimCmd sAnim_FaceEast2F[] =
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_FaceEast2F_Asym[] =
{
ANIMCMD_FRAME(6, 16),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_GoSouth[] =
{
ANIMCMD_FRAME(3, 8),
@ -289,6 +295,15 @@ static const union AnimCmd sAnim_GoEast2F[] =
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_GoEast2F_Asym[] =
{
ANIMCMD_FRAME(6, 6),
ANIMCMD_FRAME(7, 6),
ANIMCMD_FRAME(7, 6),
ANIMCMD_FRAME(6, 6),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_GoFastSouth[] =
{
ANIMCMD_FRAME(3, 4),
@ -361,6 +376,15 @@ static const union AnimCmd sAnim_GoFastEast2F[] =
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_GoFastEast2F_Asym[] =
{
ANIMCMD_FRAME(6, 4),
ANIMCMD_FRAME(7, 4),
ANIMCMD_FRAME(7, 4),
ANIMCMD_FRAME(6, 4),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_GoFasterSouth[] =
{
ANIMCMD_FRAME(3, 2),
@ -422,6 +446,19 @@ static const union AnimCmd sAnim_ExitPokeballEast[] =
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_ExitPokeballEast_Asym[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(0, 1),
ANIMCMD_FRAME(1, 1),
ANIMCMD_FRAME(2, 1),
ANIMCMD_FRAME(3, 1),
ANIMCMD_FRAME(4, 1),
ANIMCMD_FRAME(6, 8),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_EnterSouth[] =
{
ANIMCMD_FRAME(0, 8),
@ -497,6 +534,18 @@ static const union AnimCmd sAnim_EnterEast[] =
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_EnterEast_Asym[] =
{
ANIMCMD_FRAME(6, 8),
ANIMCMD_FRAME(4, 1),
ANIMCMD_FRAME(3, 1),
ANIMCMD_FRAME(2, 1),
ANIMCMD_FRAME(1, 1),
ANIMCMD_FRAME(0, 1),
ANIMCMD_FRAME(0, 3),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_GoFastestSouth[] =
{
ANIMCMD_FRAME(3, 1),
@ -554,6 +603,18 @@ static const union AnimCmd sAnim_ExitPokeballFastEast[] =
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_ExitPokeballFastEast_Asym[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_FRAME(1, 1),
ANIMCMD_FRAME(2, 1),
ANIMCMD_FRAME(3, 1),
ANIMCMD_FRAME(4, 1),
ANIMCMD_FRAME(6, 2),
ANIMCMD_FRAME(6, 1),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_GoFastestNorth[] =
{
ANIMCMD_FRAME(5, 1),
@ -1084,31 +1145,59 @@ static const union AnimCmd *const sAnimTable_Standard[] = {
};
const union AnimCmd *const sAnimTable_Following[] = {
sAnim_FaceSouth,
sAnim_FaceNorth2F,
sAnim_FaceWest2F,
sAnim_FaceEast2F,
sAnim_GoSouth2F,
sAnim_GoNorth2F,
sAnim_GoWest2F,
sAnim_GoEast2F,
sAnim_GoFastSouth2F,
sAnim_GoFastNorth2F,
sAnim_GoFastWest2F,
sAnim_GoFastEast2F,
sAnim_EnterSouth,
sAnim_EnterNorth,
sAnim_EnterWest,
sAnim_EnterEast,
sAnim_ExitPokeballSouth,
sAnim_ExitPokeballNorth,
sAnim_ExitPokeballWest,
sAnim_ExitPokeballEast,
// ANIM_STD_COUNT =
sAnim_ExitPokeballFastSouth,
sAnim_ExitPokeballFastNorth,
sAnim_ExitPokeballFastWest,
sAnim_ExitPokeballFastEast,
[ANIM_STD_FACE_SOUTH] = sAnim_FaceSouth,
[ANIM_STD_FACE_NORTH] = sAnim_FaceNorth2F,
[ANIM_STD_FACE_WEST] = sAnim_FaceWest2F,
[ANIM_STD_FACE_EAST] = sAnim_FaceEast2F,
[ANIM_STD_GO_SOUTH] = sAnim_GoSouth2F,
[ANIM_STD_GO_NORTH] = sAnim_GoNorth2F,
[ANIM_STD_GO_WEST] = sAnim_GoWest2F,
[ANIM_STD_GO_EAST] = sAnim_GoEast2F,
[ANIM_STD_GO_FAST_SOUTH] = sAnim_GoFastSouth2F,
[ANIM_STD_GO_FAST_NORTH] = sAnim_GoFastNorth2F,
[ANIM_STD_GO_FAST_WEST] = sAnim_GoFastWest2F,
[ANIM_STD_GO_FAST_EAST] = sAnim_GoFastEast2F,
// 'Faster' and above used for entering/exiting pokeball
[ANIM_STD_GO_FASTER_SOUTH] = sAnim_EnterSouth,
[ANIM_STD_GO_FASTER_NORTH] = sAnim_EnterNorth,
[ANIM_STD_GO_FASTER_WEST] = sAnim_EnterWest,
[ANIM_STD_GO_FASTER_EAST] = sAnim_EnterEast,
[ANIM_STD_GO_FASTEST_SOUTH] = sAnim_ExitPokeballSouth,
[ANIM_STD_GO_FASTEST_NORTH] = sAnim_ExitPokeballNorth,
[ANIM_STD_GO_FASTEST_WEST] = sAnim_ExitPokeballWest,
[ANIM_STD_GO_FASTEST_EAST] = sAnim_ExitPokeballEast,
[ANIM_EXIT_POKEBALL_FAST_SOUTH] = sAnim_ExitPokeballFastSouth,
[ANIM_EXIT_POKEBALL_FAST_NORTH] = sAnim_ExitPokeballFastNorth,
[ANIM_EXIT_POKEBALL_FAST_WEST] = sAnim_ExitPokeballFastWest,
[ANIM_EXIT_POKEBALL_FAST_EAST] = sAnim_ExitPokeballFastEast,
};
// Like the above, but has separate frames for facing right
static const union AnimCmd *const sAnimTable_Following_Asym[] = {
[ANIM_STD_FACE_SOUTH] = sAnim_FaceSouth,
[ANIM_STD_FACE_NORTH] = sAnim_FaceNorth2F,
[ANIM_STD_FACE_WEST] = sAnim_FaceWest2F,
[ANIM_STD_FACE_EAST] = sAnim_FaceEast2F_Asym,
[ANIM_STD_GO_SOUTH] = sAnim_GoSouth2F,
[ANIM_STD_GO_NORTH] = sAnim_GoNorth2F,
[ANIM_STD_GO_WEST] = sAnim_GoWest2F,
[ANIM_STD_GO_EAST] = sAnim_GoEast2F_Asym,
[ANIM_STD_GO_FAST_SOUTH] = sAnim_GoFastSouth2F,
[ANIM_STD_GO_FAST_NORTH] = sAnim_GoFastNorth2F,
[ANIM_STD_GO_FAST_WEST] = sAnim_GoFastWest2F,
[ANIM_STD_GO_FAST_EAST] = sAnim_GoFastEast2F_Asym,
[ANIM_STD_GO_FASTER_SOUTH] = sAnim_EnterSouth,
[ANIM_STD_GO_FASTER_NORTH] = sAnim_EnterNorth,
[ANIM_STD_GO_FASTER_WEST] = sAnim_EnterWest,
[ANIM_STD_GO_FASTER_EAST] = sAnim_EnterEast_Asym,
[ANIM_STD_GO_FASTEST_SOUTH] = sAnim_ExitPokeballSouth,
[ANIM_STD_GO_FASTEST_NORTH] = sAnim_ExitPokeballNorth,
[ANIM_STD_GO_FASTEST_WEST] = sAnim_ExitPokeballWest,
[ANIM_STD_GO_FASTEST_EAST] = sAnim_ExitPokeballEast_Asym,
[ANIM_EXIT_POKEBALL_FAST_SOUTH] = sAnim_ExitPokeballFastSouth,
[ANIM_EXIT_POKEBALL_FAST_NORTH] = sAnim_ExitPokeballFastNorth,
[ANIM_EXIT_POKEBALL_FAST_WEST] = sAnim_ExitPokeballFastWest,
[ANIM_EXIT_POKEBALL_FAST_EAST] = sAnim_ExitPokeballFastEast_Asym,
};
static const union AnimCmd *const sAnimTable_HoOh[] = {

View file

@ -381,4 +381,75 @@ const u32 gObjectEventPic_RayquazaCutscene[] = INCBIN_U32("graphics/object_event
const u16 gObjectEventPal_HoOh[] = INCBIN_U16("graphics/object_events/palettes/ho_oh.gbapal");
const u16 gObjectEventPal_Lugia[] = INCBIN_U16("graphics/object_events/palettes/lugia.gbapal");
const u16 gObjectEventPal_Substitute[] = INCBIN_U16("graphics/pokemon/question_mark/follower.gbapal");
const u16 gObjectEventPaletteEmotes[] = INCBIN_U16("graphics/misc/emotes.gbapal");
#if OW_MON_POKEBALLS
const u32 gObjectEventPic_MasterBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_master.4bpp");
const u32 gObjectEventPic_UltraBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_ultra.4bpp");
const u32 gObjectEventPic_GreatBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_great.4bpp");
const u32 gObjectEventPic_SafariBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_safari.4bpp");
const u32 gObjectEventPic_NetBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_net.4bpp");
const u32 gObjectEventPic_DiveBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_dive.4bpp");
const u32 gObjectEventPic_NestBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_nest.4bpp");
const u32 gObjectEventPic_RepeatBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_repeat.4bpp");
const u32 gObjectEventPic_TimerBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_timer.4bpp");
const u32 gObjectEventPic_LuxuryBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_luxury.4bpp");
const u32 gObjectEventPic_PremierBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_premier.4bpp");
const u32 gObjectEventPic_DuskBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_dusk.4bpp");
const u32 gObjectEventPic_HealBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_heal.4bpp");
const u32 gObjectEventPic_QuickBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_quick.4bpp");
const u32 gObjectEventPic_CherishBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_cherish.4bpp");
const u32 gObjectEventPic_ParkBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_park.4bpp");
const u32 gObjectEventPic_FastBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_fast.4bpp");
const u32 gObjectEventPic_LevelBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_level.4bpp");
const u32 gObjectEventPic_LureBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_lure.4bpp");
const u32 gObjectEventPic_HeavyBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_heavy.4bpp");
const u32 gObjectEventPic_LoveBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_love.4bpp");
const u32 gObjectEventPic_FriendBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_friend.4bpp");
const u32 gObjectEventPic_MoonBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_moon.4bpp");
const u32 gObjectEventPic_SportBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_sport.4bpp");
const u32 gObjectEventPic_DreamBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_dream.4bpp");
const u32 gObjectEventPic_BeastBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_beast.4bpp");
#ifdef ITEM_STRANGE_BALL
const u32 gObjectEventPic_StrangeBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_strange.4bpp");
#endif
#endif
#if OW_MON_POKEBALLS
// Palettes are small, so always include all of the palettes (no #ifdef)
// Vanilla
const u16 gObjectEventPal_MasterBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_master.gbapal");
const u16 gObjectEventPal_UltraBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_ultra.gbapal");
const u16 gObjectEventPal_GreatBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_great.gbapal");
const u16 gObjectEventPal_SafariBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_safari.gbapal");
const u16 gObjectEventPal_NetBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_net.gbapal");
const u16 gObjectEventPal_DiveBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_dive.gbapal");
const u16 gObjectEventPal_NestBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_nest.gbapal");
const u16 gObjectEventPal_RepeatBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_repeat.gbapal");
const u16 gObjectEventPal_TimerBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_timer.gbapal");
const u16 gObjectEventPal_LuxuryBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_luxury.gbapal");
const u16 gObjectEventPal_PremierBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_premier.gbapal");
// Gen IV/Sinnoh
const u16 gObjectEventPal_DuskBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_dusk.gbapal");
const u16 gObjectEventPal_HealBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_heal.gbapal");
const u16 gObjectEventPal_QuickBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_quick.gbapal");
const u16 gObjectEventPal_CherishBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_cherish.gbapal");
const u16 gObjectEventPal_ParkBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_park.gbapal");
// Gen II/Johto Apricorns
const u16 gObjectEventPal_FastBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_fast.gbapal");
const u16 gObjectEventPal_LevelBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_level.gbapal");
const u16 gObjectEventPal_LureBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_lure.gbapal");
const u16 gObjectEventPal_HeavyBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_heavy.gbapal");
const u16 gObjectEventPal_LoveBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_love.gbapal");
const u16 gObjectEventPal_FriendBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_friend.gbapal");
const u16 gObjectEventPal_MoonBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_moon.gbapal");
const u16 gObjectEventPal_SportBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_sport.gbapal");
// Gen V
const u16 gObjectEventPal_DreamBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_dream.gbapal");
// Gen VII
const u16 gObjectEventPal_BeastBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_beast.gbapal");
// Gen VIII
const u16 gObjectEventPal_StrangeBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_strange.gbapal");
#endif

View file

@ -0,0 +1,67 @@
#if OW_MON_POKEBALLS
#define POKEBALL_GFX_INFO(NAME) \
[BALL_##NAME] = { \
.tileTag = TAG_NONE, \
.paletteTag = OBJ_EVENT_PAL_TAG_BALL_##NAME, \
.size = 256, \
.width = 16, \
.height = 32, \
.shadowSize = SHADOW_SIZE_M, \
.inanimate = TRUE, \
.oam = &gObjectEventBaseOam_16x32, \
.subspriteTables = sOamTables_16x32, \
.anims = sAnimTable_Following, \
.images = sPicTable_Ball_##NAME, \
.affineAnims = gDummySpriteAffineAnimTable, \
}
const struct ObjectEventGraphicsInfo gPokeballGraphics[POKEBALL_COUNT] = {
// Vanilla
POKEBALL_GFX_INFO(MASTER),
POKEBALL_GFX_INFO(ULTRA),
POKEBALL_GFX_INFO(GREAT),
POKEBALL_GFX_INFO(SAFARI),
POKEBALL_GFX_INFO(NET),
POKEBALL_GFX_INFO(DIVE),
POKEBALL_GFX_INFO(NEST),
POKEBALL_GFX_INFO(REPEAT),
POKEBALL_GFX_INFO(TIMER),
POKEBALL_GFX_INFO(LUXURY),
POKEBALL_GFX_INFO(PREMIER),
// Gen IV/Sinnoh pokeballs
#ifdef ITEM_DUSK_BALL
POKEBALL_GFX_INFO(DUSK),
POKEBALL_GFX_INFO(HEAL),
POKEBALL_GFX_INFO(QUICK),
POKEBALL_GFX_INFO(CHERISH),
#endif
#ifdef ITEM_PARK_BALL
POKEBALL_GFX_INFO(PARK),
#endif
// Gen II/Johto Apricorn pokeballs
#ifdef ITEM_FAST_BALL
POKEBALL_GFX_INFO(FAST),
POKEBALL_GFX_INFO(LEVEL),
POKEBALL_GFX_INFO(LURE),
POKEBALL_GFX_INFO(HEAVY),
POKEBALL_GFX_INFO(LOVE),
POKEBALL_GFX_INFO(FRIEND),
POKEBALL_GFX_INFO(MOON),
POKEBALL_GFX_INFO(SPORT),
#endif
// Gen V
#ifdef ITEM_DREAM_BALL
POKEBALL_GFX_INFO(DREAM),
#endif
// Gen VII
#ifdef ITEM_BEAST_BALL
POKEBALL_GFX_INFO(BEAST),
#endif
// Gen VIII
#ifdef ITEM_STRANGE_BALL
POKEBALL_GFX_INFO(STRANGE),
#endif
};
#endif

View file

@ -1113,9 +1113,109 @@ static const struct SpriteFrameImage sPicTable_Brandon[] = {
};
static const struct SpriteFrameImage sPicTable_AnimatedBall[] = {
overworld_ascending_frames(gObjectEventPic_AnimatedBall, 2, 4),
overworld_frame(gObjectEventPic_AnimatedBall, 2, 4, 0),
overworld_frame(gObjectEventPic_AnimatedBall, 2, 4, 1),
overworld_frame(gObjectEventPic_AnimatedBall, 2, 4, 2),
overworld_frame(gObjectEventPic_AnimatedBall, 2, 4, 3),
overworld_frame(gObjectEventPic_AnimatedBall, 2, 4, 4),
overworld_frame(gObjectEventPic_AnimatedBall, 2, 4, 0),
};
#if OW_MON_POKEBALLS
#define POKEBALL_PIC_FRAMES(name) \
overworld_frame(gObjectEventPic_##name##Ball, 2, 4, 0), \
overworld_frame(gObjectEventPic_##name##Ball, 2, 4, 1), \
overworld_frame(gObjectEventPic_##name##Ball, 2, 4, 2), \
overworld_frame(gObjectEventPic_##name##Ball, 2, 4, 3), \
overworld_frame(gObjectEventPic_##name##Ball, 2, 4, 4), \
overworld_frame(gObjectEventPic_##name##Ball, 2, 4, 0)
static const struct SpriteFrameImage sPicTable_Ball_MASTER[] = {
POKEBALL_PIC_FRAMES(Master),
};
static const struct SpriteFrameImage sPicTable_Ball_ULTRA[] = {
POKEBALL_PIC_FRAMES(Ultra),
};
static const struct SpriteFrameImage sPicTable_Ball_GREAT[] = {
POKEBALL_PIC_FRAMES(Great),
};
static const struct SpriteFrameImage sPicTable_Ball_SAFARI[] = {
POKEBALL_PIC_FRAMES(Safari),
};
static const struct SpriteFrameImage sPicTable_Ball_NET[] = {
POKEBALL_PIC_FRAMES(Net),
};
static const struct SpriteFrameImage sPicTable_Ball_DIVE[] = {
POKEBALL_PIC_FRAMES(Dive),
};
static const struct SpriteFrameImage sPicTable_Ball_NEST[] = {
POKEBALL_PIC_FRAMES(Nest),
};
static const struct SpriteFrameImage sPicTable_Ball_REPEAT[] = {
POKEBALL_PIC_FRAMES(Repeat),
};
static const struct SpriteFrameImage sPicTable_Ball_TIMER[] = {
POKEBALL_PIC_FRAMES(Timer),
};
static const struct SpriteFrameImage sPicTable_Ball_LUXURY[] = {
POKEBALL_PIC_FRAMES(Luxury),
};
static const struct SpriteFrameImage sPicTable_Ball_PREMIER[] = {
POKEBALL_PIC_FRAMES(Premier),
};
static const struct SpriteFrameImage sPicTable_Ball_DUSK[] = {
POKEBALL_PIC_FRAMES(Dusk),
};
static const struct SpriteFrameImage sPicTable_Ball_HEAL[] = {
POKEBALL_PIC_FRAMES(Heal),
};
static const struct SpriteFrameImage sPicTable_Ball_QUICK[] = {
POKEBALL_PIC_FRAMES(Quick),
};
static const struct SpriteFrameImage sPicTable_Ball_CHERISH[] = {
POKEBALL_PIC_FRAMES(Cherish),
};
static const struct SpriteFrameImage sPicTable_Ball_PARK[] = {
POKEBALL_PIC_FRAMES(Park),
};
static const struct SpriteFrameImage sPicTable_Ball_FAST[] = {
POKEBALL_PIC_FRAMES(Fast),
};
static const struct SpriteFrameImage sPicTable_Ball_LEVEL[] = {
POKEBALL_PIC_FRAMES(Level),
};
static const struct SpriteFrameImage sPicTable_Ball_LURE[] = {
POKEBALL_PIC_FRAMES(Lure),
};
static const struct SpriteFrameImage sPicTable_Ball_HEAVY[] = {
POKEBALL_PIC_FRAMES(Heavy),
};
static const struct SpriteFrameImage sPicTable_Ball_LOVE[] = {
POKEBALL_PIC_FRAMES(Love),
};
static const struct SpriteFrameImage sPicTable_Ball_FRIEND[] = {
POKEBALL_PIC_FRAMES(Friend),
};
static const struct SpriteFrameImage sPicTable_Ball_MOON[] = {
POKEBALL_PIC_FRAMES(Moon),
};
static const struct SpriteFrameImage sPicTable_Ball_SPORT[] = {
POKEBALL_PIC_FRAMES(Sport),
};
static const struct SpriteFrameImage sPicTable_Ball_DREAM[] = {
POKEBALL_PIC_FRAMES(Dream),
};
static const struct SpriteFrameImage sPicTable_Ball_BEAST[] = {
POKEBALL_PIC_FRAMES(Beast),
};
#ifdef ITEM_STRANGE_BALL
static const struct SpriteFrameImage sPicTable_Ball_STRANGE[] = {
POKEBALL_PIC_FRAMES(Strange),
};
#endif
#endif
static const struct SpriteFrameImage sPicTable_DeoxysOld[] = {
overworld_frame(gObjectEventPic_DeoxysOld, 4, 4, 0),
overworld_frame(gObjectEventPic_DeoxysOld, 4, 4, 0),

View file

@ -1,9 +1,7 @@
static const struct SpriteFrameImage sPicTable_None[] = {
overworld_ascending_frames(gObjectEventPic_None, 4, 4),
};
#if P_FOLLOWERS
static const struct SpriteFrameImage sPicTable_Substitute[] = {
overworld_ascending_frames(gObjectEventPic_Substitute, 4, 4),
};
#if P_FAMILY_BULBASAUR
static const struct SpriteFrameImage sPicTable_Bulbasaur[] = {

View file

@ -291,7 +291,7 @@ const struct SpeciesInfo gSpeciesInfo[] =
.backAnimId = BACK_ANIM_NONE,
PALETTES(CircledQuestionMark),
ICON(QuestionMark, 0),
.followerData = {TAG_NONE, OBJ_EVENT_PAL_TAG_DYNAMIC, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, COMP, TRACKS_FOOT, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_None, gDummySpriteAffineAnimTable},
.followerData = {TAG_NONE, OBJ_EVENT_PAL_TAG_SUBSTITUTE, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, COMP, TRACKS_FOOT, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_Substitute, gDummySpriteAffineAnimTable},
LEARNSETS(None),
},
@ -380,3 +380,16 @@ const struct SpeciesInfo gSpeciesInfo[] =
},
*/
};
// Standalone follower palettes
// If not NULL, entries here override the front-sprite-based pals
// used by OBJ_EVENT_PAL_TAG_DYNAMIC
// Palette data may be compressed, or not
const void* const gFollowerPalettes[NUM_SPECIES][2] =
{
// Must have at least one entry, or ARRAY_COUNT comparison fails
// (SPECIES_NONE does not use OBJ_EVENT_PAL_TAG_DYNAMIC anyway)
[SPECIES_NONE] = {gMonPalette_CircledQuestionMark, gMonShinyPalette_CircledQuestionMark},
};

View file

@ -50,7 +50,7 @@ static const u8 sHappyMsg27[] = _("Your POKéMON is smelling the scent\nof flowe
static const u8 sHappyMsg28[] = _("{STR_VAR_1} seems very happy to see\nyou!");
static const u8 sHappyMsg29[] = _("{STR_VAR_1} faced this way and\ngrinned.");
static const u8 sHappyMsg30[] = _("{STR_VAR_1} happily cuddled up to\nyou!");
// Conditional messages begin here, index 31
// Conditional messages begin here, index 31
static const u8 sHappyMsg31[] = _("Your POKéMON seems happy about the\ngreat weather.");
static const u8 sHappyMsg32[] = _("{STR_VAR_1} is very composed and\nsure of itself!");
@ -106,7 +106,7 @@ const struct FollowerMsgInfo gFollowerNeutralMessages[] = {
static const u8 sSadMsg00[] = _("{STR_VAR_1} is dizzy.");
static const u8 sSadMsg01[] = _("{STR_VAR_1} is stepping on your\nfeet!");
static const u8 sSadMsg02[] = _("{STR_VAR_1} seems a little tired.");
// Conditional messages begin, index 3
// Conditional messages begin, index 3
static const u8 sSadMsg03[] = _("{STR_VAR_1} is not happy.");
static const u8 sSadMsg04[] = _("{STR_VAR_1} is going to fall down!\n");
static const u8 sSadMsg05[] = _("{STR_VAR_1} seems to be about to\nfall over!");
@ -123,7 +123,7 @@ const struct FollowerMsgInfo gFollowerSadMessages[] = {
static const u8 sUpsetMsg00[] = _("{STR_VAR_1} seems unhappy somehow…");
static const u8 sUpsetMsg01[] = _("{STR_VAR_1} is making an unhappy\nface.");
static const u8 sUpsetMsg02[] = _("…Your POKéMON seems a little\ncold.");
// Conditional messages, index 3
// Conditional messages, index 3
static const u8 sUpsetMsg03[] = _("{STR_VAR_1} is taking shelter in the\ngrass from the rain.");
const struct FollowerMsgInfo gFollowerUpsetMessages[] = {
@ -225,7 +225,7 @@ static const u8 sSurpriseMsg16[] = _("{STR_VAR_1} sensed something strange\nand
static const u8 sSurpriseMsg17[] = _("{STR_VAR_1} is scared and snuggled\nup to you!");
static const u8 sSurpriseMsg18[] = _("{STR_VAR_1} is feeling an unusual\npresence…");
static const u8 sSurpriseMsg19[] = _("{STR_VAR_1} is getting tense with\nnervous energy.");
// Conditional messages, index 20
// Conditional messages, index 20
static const u8 sSurpriseMsg20[] = _("{STR_VAR_1} seems to be very\nsurprised that it is raining!");
const struct FollowerMsgInfo gFollowerSurpriseMessages[] = {

View file

@ -18,6 +18,24 @@ void LZDecompressVram(const u32 *src, void *dest)
LZ77UnCompVram(src, dest);
}
// Checks if `ptr` is likely LZ77 data
// Checks word-alignment, min/max size, and header byte
bool32 IsLZ77Data(const void *ptr, u32 minSize, u32 maxSize) {
const u8 *data = ptr;
u32 size;
// Compressed data must be word aligned
if (((u32)ptr) & 3)
return FALSE;
// Check LZ77 header byte
// See https://problemkaputt.de/gbatek.htm#biosdecompressionfunctions
if (data[0] != 0x10)
return FALSE;
// Read 24-bit uncompressed size
size = data[1] | (data[2] << 8) | (data[3] << 16);
return (size >= minSize && size <= maxSize);
}
u16 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src)
{
struct SpriteSheet dest;

File diff suppressed because it is too large Load diff

View file

@ -334,7 +334,7 @@ u32 FldEff_Shadow(void)
objectEventId = GetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
graphicsInfo = GetObjectEventGraphicsInfo(gObjectEvents[objectEventId].graphicsId);
if (graphicsInfo->shadowSize == SHADOW_SIZE_NONE) // don't create a shadow at all
return 0;
return 0;
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[sShadowEffectTemplateIds[graphicsInfo->shadowSize]], 0, 0, 0x94);
if (spriteId != MAX_SPRITES)
{

View file

@ -73,225 +73,222 @@ const struct FollowerMsgInfoExtended gFollowerConditionalMessages[COND_MSG_COUNT
.text = (u8*)sCelebiTexts,
.textSpread = 1,
.script = EventScript_FollowerDance,
.st = {.species = SPECIES_CELEBI},
.stFlags = ST_FLAGS_SPECIES,
.emotion = FOLLOWER_EMOTION_NEUTRAL,
.conditions = {MATCH_SPECIES(SPECIES_CELEBI)},
},
[COND_MSG_FIRE] =
{
.text = (u8*)sFireTexts,
.st = {.types = {.type1 = TYPE_FIRE, .type2 = TYPE_FIRE}},
.stFlags = ST_FLAGS_TYPE,
.emotion = FOLLOWER_EMOTION_NEUTRAL,
.textSpread = 1,
.emotion = FOLLOWER_EMOTION_NEUTRAL,
.conditions = {MATCH_TYPES(TYPE_FIRE, TYPE_FIRE)},
},
[COND_MSG_EVER_GRANDE] =
{
.text = sCondMsg06,
.script = EventScript_FollowerFaceUp,
.mm = {.map = {.mapNum = MAP_NUM(EVER_GRANDE_CITY), .mapGroup = MAP_GROUP(EVER_GRANDE_CITY)}},
.mmFlags = MM_FLAGS_MAP,
.emotion = FOLLOWER_EMOTION_HAPPY,
.conditions = {MATCH_MAP(EVER_GRANDE_CITY)},
},
[COND_MSG_ROUTE_112] =
{
.text = sCondMsg07,
.mm = {.map = {.mapNum = MAP_NUM(ROUTE112), .mapGroup = MAP_GROUP(ROUTE112)}},
.mmFlags = MM_FLAGS_MAP,
.emotion = FOLLOWER_EMOTION_HAPPY,
.conditions = {MATCH_MAP(ROUTE112)},
},
[COND_MSG_DAY_CARE] =
{
.text = sCondMsg08,
.script = EventScript_FollowerNostalgia,
.mm = {.map = {.mapNum = MAP_NUM(ROUTE117_POKEMON_DAY_CARE), .mapGroup = MAP_GROUP(ROUTE117_POKEMON_DAY_CARE)}},
.mmFlags = MM_FLAGS_MAP,
.emotion = FOLLOWER_EMOTION_NEUTRAL,
.conditions = {MATCH_MAP(ROUTE117_POKEMON_DAY_CARE)},
},
[COND_MSG_MART] =
{
.text = (u8*)sShopTexts,
.textSpread = 1,
.script = EventScript_FollowerLookAround,
.wt = {.song = MUS_POKE_MART},
.wtFlags = WT_FLAGS_MUSIC,
.emotion = FOLLOWER_EMOTION_NEUTRAL,
.conditions = {MATCH_MUSIC(MUS_POKE_MART)},
},
[COND_MSG_VICTORY_ROAD] =
{
.text = sCondMsg11,
.wt = {.song = MUS_VICTORY_ROAD},
.wtFlags = WT_FLAGS_MUSIC,
.emotion = FOLLOWER_EMOTION_PENSIVE,
.conditions = {MATCH_MUSIC(MUS_VICTORY_ROAD)},
},
[COND_MSG_BIKE_SHOP] =
{
.text = sCondMsg12,
.mm = {.map = {.mapNum = MAP_NUM(MAUVILLE_CITY_BIKE_SHOP), .mapGroup = MAP_GROUP(MAUVILLE_CITY_BIKE_SHOP)}},
.mmFlags = MM_FLAGS_MAP,
.emotion = FOLLOWER_EMOTION_PENSIVE,
.conditions = {MATCH_MAP(MAUVILLE_CITY_BIKE_SHOP)},
},
[COND_MSG_MACHINES] =
{
.text = (u8*)sMachineTexts,
.mm = {.map = {.mapNum = MAP_NUM(NEW_MAUVILLE_INSIDE), .mapGroup = MAP_GROUP(NEW_MAUVILLE_INSIDE)}},
.mmFlags = MM_FLAGS_MAP,
.emotion = FOLLOWER_EMOTION_MUSIC,
.textSpread = 1,
.emotion = FOLLOWER_EMOTION_MUSIC,
.orFlag = 1, // match any of these maps
.conditions = {
MATCH_MAP(NEW_MAUVILLE_INSIDE),
MATCH_MAP(SLATEPORT_CITY_STERNS_SHIPYARD_1F),
MATCH_MAP(SLATEPORT_CITY_STERNS_SHIPYARD_2F),
}
},
[COND_MSG_SAILING] =
{
.text = (u8*)sBoatTexts,
.script = EventScript_FollowerLookAround,
.wt = {.song = MUS_SAILING},
.wtFlags = WT_FLAGS_MUSIC,
.emotion = FOLLOWER_EMOTION_MUSIC,
.textSpread = 1,
.emotion = FOLLOWER_EMOTION_MUSIC,
.script = EventScript_FollowerLookAround,
.conditions = {MATCH_MUSIC(MUS_SAILING)},
},
[COND_MSG_PUDDLE] =
{
.text = sCondMsg18,
.script = EventScript_FollowerHopping,
.mm = {.mb = {.behavior1 = MB_SHALLOW_WATER, .behavior2 = MB_PUDDLE}},
.mmFlags = MM_FLAGS_MB,
.emotion = FOLLOWER_EMOTION_MUSIC,
.conditions = {MATCH_ON_MB(MB_SHALLOW_WATER, MB_PUDDLE)},
},
[COND_MSG_SAND] =
{
.text = sCondMsg19,
.mm = {.mb = {.behavior1 = MB_SAND, .behavior2 = MB_DEEP_SAND}},
.mmFlags = MM_FLAGS_MB,
.emotion = FOLLOWER_EMOTION_MUSIC,
.conditions = {MATCH_ON_MB(MB_SAND, MB_DEEP_SAND)},
},
[COND_MSG_GRASS] =
{
.text = sCondMsg20,
.mm = {.mb = {.behavior1 = MB_TALL_GRASS, .behavior2 = MB_LONG_GRASS}},
.mmFlags = MM_FLAGS_MB,
.emotion = FOLLOWER_EMOTION_MUSIC,
.conditions = {MATCH_ON_MB(MB_TALL_GRASS, MB_LONG_GRASS)},
},
[COND_MSG_FOOTPRINTS] =
{
.text = sCondMsg21,
.mm = {.mb = {.behavior1 = MB_SAND, .behavior2 = MB_FOOTPRINTS}},
.mmFlags = MM_FLAGS_MB,
.emotion = FOLLOWER_EMOTION_MUSIC,
.conditions = {MATCH_ON_MB(MB_SAND, MB_FOOTPRINTS)},
},
[COND_MSG_ELEVATOR] =
{
.text = (u8*)sElevatorTexts,
.textSpread = 1,
.mm = {.map = {.mapNum = MAP_NUM(LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR), .mapGroup = MAP_GROUP(LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR)}},
.mmFlags = MM_FLAGS_MAP,
.emotion = FOLLOWER_EMOTION_SURPRISE,
.conditions = {MATCH_MAP(LILYCOVE_CITY_DEPARTMENT_STORE_ELEVATOR)},
},
[COND_MSG_ICE_ROOM] =
{
.text = (u8*)sColdTexts,
.textSpread = 1,
.mm = {.map = {.mapNum = MAP_NUM(SHOAL_CAVE_LOW_TIDE_ICE_ROOM), .mapGroup = MAP_GROUP(SHOAL_CAVE_LOW_TIDE_ICE_ROOM)}},
.mmFlags = MM_FLAGS_MAP,
.emotion = FOLLOWER_EMOTION_SURPRISE,
.conditions = {MATCH_MAP(SHOAL_CAVE_LOW_TIDE_ICE_ROOM)},
},
[COND_MSG_ROUTE_117] =
{
.text = sCondMsg27,
.mm = {.map = {.mapNum = MAP_NUM(ROUTE117), .mapGroup = MAP_GROUP(ROUTE117)}},
.mmFlags = MM_FLAGS_MAP,
.emotion = FOLLOWER_EMOTION_SURPRISE,
.conditions = {MATCH_MAP(ROUTE117)},
},
[COND_MSG_DRAGON_GROWL] =
{
.text = sCondMsg28,
.st = {.types = {.type1 = TYPE_DRAGON, .type2 = TYPE_DRAGON}},
.stFlags = ST_FLAGS_TYPE,
.mm = {.mapSec = {.mapSec = MAPSEC_SKY_PILLAR}},
.mmFlags = MM_FLAGS_MAPSEC,
.emotion = FOLLOWER_EMOTION_UPSET,
.conditions = {
MATCH_TYPES(TYPE_DRAGON, TYPE_DRAGON),
MATCH_MAPSEC(MAPSEC_SKY_PILLAR),
}
},
[COND_MSG_FEAR] =
{
.text = (u8*)sFearTexts,
.textSpread = 1,
.st = {.types = {.type1 = TYPE_GHOST, .type2 = TYPE_NOT_TYPE1}},
.stFlags = ST_FLAGS_TYPE,
.mm = {.mapSec = {.mapSec = MAPSEC_MT_PYRE}},
.mmFlags = MM_FLAGS_MAPSEC,
.wt = {.song = MUS_MT_PYRE},
.wtFlags = WT_FLAGS_MUSIC,
.emotion = FOLLOWER_EMOTION_UPSET,
.conditions = {
MATCH_NOT_TYPES(TYPE_GHOST, TYPE_GHOST),
MATCH_MAPSEC(MAPSEC_MT_PYRE),
MATCH_MUSIC(MUS_MT_PYRE),
}
},
[COND_MSG_FIRE_RAIN] =
{
.text = sCondMsg31,
.st = {.types = {.type1 = TYPE_FIRE, .type2 = TYPE_FIRE}},
.stFlags = ST_FLAGS_TYPE,
.wt = {.weather = {.weather1 = WEATHER_RAIN, .weather2 = WEATHER_RAIN_THUNDERSTORM}},
.wtFlags = WT_FLAGS_WEATHER,
.emotion = FOLLOWER_EMOTION_UPSET,
.conditions = {
MATCH_TYPES(TYPE_FIRE, TYPE_FIRE),
MATCH_WEATHER(WEATHER_RAIN, WEATHER_RAIN_THUNDERSTORM),
}
},
[COND_MSG_FROZEN] =
{
.text = sCondMsg32,
.st = {.status = STATUS1_FREEZE},
.stFlags = ST_FLAGS_STATUS,
.emotion = FOLLOWER_EMOTION_UPSET,
.conditions = {
MATCH_STATUS(STATUS1_FREEZE),
}
},
[COND_MSG_SEASIDE] =
{
.text = (u8*)sSeaTexts,
.textSpread = 1,
.script = EventScript_FollowerFaceResult,
.near = {.mb = {.behavior = MB_OCEAN_WATER, .distance = 5}},
.nearFlags = NEAR_FLAGS_MB,
.emotion = FOLLOWER_EMOTION_MUSIC,
.conditions = {MATCH_NEAR_MB(MB_OCEAN_WATER, 5)},
},
[COND_MSG_WATERFALL] =
{
.text = sCondMsg36,
.script = EventScript_FollowerFaceResult,
.near = {.mb = {.behavior = MB_WATERFALL, .distance = 5}},
.nearFlags = NEAR_FLAGS_MB,
.emotion = FOLLOWER_EMOTION_MUSIC,
.conditions = {MATCH_NEAR_MB(MB_WATERFALL, 5)},
},
[COND_MSG_RAIN] =
{
.text = sCondMsg37,
.st = {.types = {.type1 = TYPE_FIRE, .type2 = TYPE_NOT_TYPE1}},
.stFlags = ST_FLAGS_TYPE,
.wt = {.weather = {.weather1 = WEATHER_RAIN, .weather2 = WEATHER_RAIN_THUNDERSTORM}},
.wtFlags = WT_FLAGS_WEATHER,
.emotion = FOLLOWER_EMOTION_MUSIC,
.conditions = {
MATCH_NOT_TYPES(TYPE_FIRE, TYPE_FIRE),
MATCH_WEATHER(WEATHER_RAIN, WEATHER_RAIN_THUNDERSTORM)
}
},
[COND_MSG_REFLECTION] =
{
.text = sCondMsg38,
.script = EventScript_FollowerFaceResult,
.near = {.mb = {.behavior = MB_POND_WATER, .distance = 1}},
.nearFlags = NEAR_FLAGS_MB,
.emotion = FOLLOWER_EMOTION_PENSIVE,
.conditions = {MATCH_NEAR_MB(MB_POND_WATER, 1)},
},
[COND_MSG_LEAVES] =
{
.text = sCondMsg39,
.mm = {.mapSec = {.mapSec = MAPSEC_PETALBURG_WOODS}},
.mmFlags = MM_FLAGS_MAPSEC,
.emotion = FOLLOWER_EMOTION_PENSIVE,
.conditions = {MATCH_MAPSEC(MAPSEC_PETALBURG_WOODS)},
},
[COND_MSG_ICE] =
{
.text = (u8*)sIceTexts,
.textSpread = 1,
.script = EventScript_FollowerFaceResult,
.near = {.mb = {.behavior = MB_ICE, .distance = 1}},
.nearFlags = NEAR_FLAGS_MB,
.emotion = FOLLOWER_EMOTION_PENSIVE,
.conditions = {MATCH_NEAR_MB(MB_ICE, 1)},
},
[COND_MSG_BURN] =
{
.text = sCondMsg42,
.st = {.status = STATUS1_BURN},
.stFlags = ST_FLAGS_STATUS,
.emotion = FOLLOWER_EMOTION_SAD,
.conditions = {MATCH_STATUS(STATUS1_BURN)},
},
};
// Pool of "unconditional" follower messages
const struct FollowerMessagePool gFollowerBasicMessages[FOLLOWER_EMOTION_LENGTH] = {
[FOLLOWER_EMOTION_HAPPY] = {gFollowerHappyMessages, EventScript_FollowerGeneric, N_FOLLOWER_HAPPY_MESSAGES},
[FOLLOWER_EMOTION_NEUTRAL] = {gFollowerNeutralMessages, EventScript_FollowerGeneric, N_FOLLOWER_NEUTRAL_MESSAGES},
[FOLLOWER_EMOTION_SAD] = {gFollowerSadMessages, EventScript_FollowerGeneric, N_FOLLOWER_SAD_MESSAGES},
[FOLLOWER_EMOTION_UPSET] = {gFollowerUpsetMessages, EventScript_FollowerGeneric, N_FOLLOWER_UPSET_MESSAGES},
[FOLLOWER_EMOTION_ANGRY] = {gFollowerAngryMessages, EventScript_FollowerGeneric, N_FOLLOWER_ANGRY_MESSAGES},
[FOLLOWER_EMOTION_PENSIVE] = {gFollowerPensiveMessages, EventScript_FollowerGeneric, N_FOLLOWER_PENSIVE_MESSAGES},
[FOLLOWER_EMOTION_LOVE] = {gFollowerLoveMessages, EventScript_FollowerGeneric, N_FOLLOWER_LOVE_MESSAGES},
[FOLLOWER_EMOTION_SURPRISE] = {gFollowerSurpriseMessages, EventScript_FollowerGeneric, N_FOLLOWER_SURPRISE_MESSAGES},
[FOLLOWER_EMOTION_CURIOUS] = {gFollowerCuriousMessages, EventScript_FollowerGeneric, N_FOLLOWER_CURIOUS_MESSAGES},
[FOLLOWER_EMOTION_MUSIC] = {gFollowerMusicMessages, EventScript_FollowerGeneric, N_FOLLOWER_MUSIC_MESSAGES},
[FOLLOWER_EMOTION_POISONED] = {gFollowerPoisonedMessages, EventScript_FollowerGeneric, N_FOLLOWER_POISONED_MESSAGES},
};

View file

@ -1016,9 +1016,9 @@ bool8 ScrCmd_applymovement(struct ScriptContext *ctx)
}
ScriptMovement_StartObjectMovementScript(localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, movementScript);
sMovingNpcId = localId;
// Force follower into pokeball
if (localId != OBJ_EVENT_ID_FOLLOWER && !FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT))
{
// Force follower into pokeball
objEvent = GetFollowerObject();
// return early if no follower or in shadowing state
if (objEvent == NULL || gSprites[objEvent->spriteId].data[1] == 0)
@ -2181,7 +2181,7 @@ bool8 ScrCmd_playmoncry(struct ScriptContext *ctx)
return FALSE;
}
bool8 ScrFunc_playfirstmoncry(struct ScriptContext *ctx)
bool8 ScrFunc_playfirstmoncry(struct ScriptContext *ctx)
{
u16 species = GetMonData(GetFirstLiveMon(), MON_DATA_SPECIES);
PlayCry_Script(species, 0);

View file

@ -161,101 +161,112 @@ static const struct SpriteFrameImage sSpriteImageTable_HeartIcon[] =
static const struct SpriteFrameImage sSpriteImageTable_Emotes[] =
{
{ .data = (u8 *)sEmotion_Gfx+0*0x80, .size = 0x80}, // FOLLOWER_EMOTION_HAPPY
{ .data = (u8 *)sEmotion_Gfx+1*0x80, .size = 0x80}, // FOLLOWER_EMOTION_HAPPY
{ .data = (u8 *)sEmotion_Gfx+2*0x80, .size = 0x80}, // FOLLOWER_EMOTION_NEUTRAL
{ .data = (u8 *)sEmotion_Gfx+3*0x80, .size = 0x80}, // FOLLOWER_EMOTION_NEUTRAL
{ .data = (u8 *)sEmotion_Gfx+4*0x80, .size = 0x80}, // FOLLOWER_EMOTION_SAD
{ .data = (u8 *)sEmotion_Gfx+5*0x80, .size = 0x80}, // FOLLOWER_EMOTION_SAD
{ .data = (u8 *)sEmotion_Gfx+6*0x80, .size = 0x80}, // FOLLOWER_EMOTION_UPSET
{ .data = (u8 *)sEmotion_Gfx+7*0x80, .size = 0x80}, // FOLLOWER_EMOTION_UPSET
{ .data = (u8 *)sEmotion_Gfx+8*0x80, .size = 0x80}, // FOLLOWER_EMOTION_ANGRY
{ .data = (u8 *)sEmotion_Gfx+9*0x80, .size = 0x80}, // FOLLOWER_EMOTION_ANGRY
{ .data = (u8 *)sEmotion_Gfx+10*0x80, .size = 0x80}, // FOLLOWER_EMOTION_PENSIVE
{ .data = (u8 *)sEmotion_Gfx+11*0x80, .size = 0x80}, // FOLLOWER_EMOTION_PENSIVE
{ .data = (u8 *)sEmotion_Gfx+12*0x80, .size = 0x80}, // FOLLOWER_EMOTION_LOVE
{ .data = (u8 *)sEmotion_Gfx+13*0x80, .size = 0x80}, // FOLLOWER_EMOTION_LOVE
{ .data = (u8 *)sEmotion_Gfx+14*0x80, .size = 0x80}, // FOLLOWER_EMOTION_SURPRISE
{ .data = (u8 *)sEmotion_Gfx+15*0x80, .size = 0x80}, // FOLLOWER_EMOTION_SURPRISE
{ .data = (u8 *)sEmotion_Gfx+16*0x80, .size = 0x80}, // FOLLOWER_EMOTION_CURIOUS
{ .data = (u8 *)sEmotion_Gfx+17*0x80, .size = 0x80}, // FOLLOWER_EMOTION_CURIOUS
{ .data = (u8 *)sEmotion_Gfx+18*0x80, .size = 0x80}, // FOLLOWER_EMOTION_MUSIC
{ .data = (u8 *)sEmotion_Gfx+19*0x80, .size = 0x80}, // FOLLOWER_EMOTION_MUSIC
{ .data = (u8 *)sEmotion_Gfx+20*0x80, .size = 0x80}, // FOLLOWER_EMOTION_POISONED
{ .data = (u8 *)sEmotion_Gfx+21*0x80, .size = 0x80}, // FOLLOWER_EMOTION_POISONED
overworld_frame(sEmotion_Gfx, 2, 2, 0), // FOLLOWER_EMOTION_HAPPY
overworld_frame(sEmotion_Gfx, 2, 2, 1), // FOLLOWER_EMOTION_HAPPY
overworld_frame(sEmotion_Gfx, 2, 2, 2), // FOLLOWER_EMOTION_NEUTRAL
overworld_frame(sEmotion_Gfx, 2, 2, 3), // FOLLOWER_EMOTION_NEUTRAL
overworld_frame(sEmotion_Gfx, 2, 2, 4), // FOLLOWER_EMOTION_SAD
overworld_frame(sEmotion_Gfx, 2, 2, 5), // FOLLOWER_EMOTION_SAD
overworld_frame(sEmotion_Gfx, 2, 2, 6), // FOLLOWER_EMOTION_UPSET
overworld_frame(sEmotion_Gfx, 2, 2, 7), // FOLLOWER_EMOTION_UPSET
overworld_frame(sEmotion_Gfx, 2, 2, 8), // FOLLOWER_EMOTION_ANGRY
overworld_frame(sEmotion_Gfx, 2, 2, 9), // FOLLOWER_EMOTION_ANGRY
overworld_frame(sEmotion_Gfx, 2, 2, 10), // FOLLOWER_EMOTION_PENSIVE
overworld_frame(sEmotion_Gfx, 2, 2, 11), // FOLLOWER_EMOTION_PENSIVE
overworld_frame(sEmotion_Gfx, 2, 2, 12), // FOLLOWER_EMOTION_LOVE
overworld_frame(sEmotion_Gfx, 2, 2, 13), // FOLLOWER_EMOTION_LOVE
overworld_frame(sEmotion_Gfx, 2, 2, 14), // FOLLOWER_EMOTION_SURPRISE
overworld_frame(sEmotion_Gfx, 2, 2, 15), // FOLLOWER_EMOTION_SURPRISE
overworld_frame(sEmotion_Gfx, 2, 2, 16), // FOLLOWER_EMOTION_CURIOUS
overworld_frame(sEmotion_Gfx, 2, 2, 17), // FOLLOWER_EMOTION_CURIOUS
overworld_frame(sEmotion_Gfx, 2, 2, 18), // FOLLOWER_EMOTION_MUSIC
overworld_frame(sEmotion_Gfx, 2, 2, 19), // FOLLOWER_EMOTION_MUSIC
overworld_frame(sEmotion_Gfx, 2, 2, 20), // FOLLOWER_EMOTION_POISONED
overworld_frame(sEmotion_Gfx, 2, 2, 21), // FOLLOWER_EMOTION_POISONED
};
static const union AnimCmd sSpriteAnim_Emotes0[] = {
static const union AnimCmd sSpriteAnim_Emotes0[] =
{
ANIMCMD_FRAME(0*2, 30),
ANIMCMD_FRAME(0*2+1, 25),
ANIMCMD_FRAME(0*2, 30),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Emotes1[] = {
static const union AnimCmd sSpriteAnim_Emotes1[] =
{
ANIMCMD_FRAME(1*2, 30),
ANIMCMD_FRAME(1*2+1, 25),
ANIMCMD_FRAME(1*2, 30),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Emotes2[] = {
static const union AnimCmd sSpriteAnim_Emotes2[] =
{
ANIMCMD_FRAME(2*2, 30),
ANIMCMD_FRAME(2*2+1, 25),
ANIMCMD_FRAME(2*2, 30),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Emotes3[] = {
static const union AnimCmd sSpriteAnim_Emotes3[] =
{
ANIMCMD_FRAME(3*2, 30),
ANIMCMD_FRAME(3*2+1, 25),
ANIMCMD_FRAME(3*2, 30),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Emotes4[] = {
static const union AnimCmd sSpriteAnim_Emotes4[] =
{
ANIMCMD_FRAME(4*2, 30),
ANIMCMD_FRAME(4*2+1, 25),
ANIMCMD_FRAME(4*2, 30),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Emotes5[] = {
static const union AnimCmd sSpriteAnim_Emotes5[] =
{
ANIMCMD_FRAME(5*2, 30),
ANIMCMD_FRAME(5*2+1, 25),
ANIMCMD_FRAME(5*2, 30),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Emotes6[] = {
static const union AnimCmd sSpriteAnim_Emotes6[] =
{
ANIMCMD_FRAME(6*2, 30),
ANIMCMD_FRAME(6*2+1, 25),
ANIMCMD_FRAME(6*2, 30),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Emotes7[] = {
static const union AnimCmd sSpriteAnim_Emotes7[] =
{
ANIMCMD_FRAME(7*2, 30),
ANIMCMD_FRAME(7*2+1, 25),
ANIMCMD_FRAME(7*2, 30),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Emotes8[] = {
static const union AnimCmd sSpriteAnim_Emotes8[] =
{
ANIMCMD_FRAME(8*2, 30),
ANIMCMD_FRAME(8*2+1, 25),
ANIMCMD_FRAME(8*2, 30),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Emotes9[] = {
static const union AnimCmd sSpriteAnim_Emotes9[] =
{
ANIMCMD_FRAME(9*2, 30),
ANIMCMD_FRAME(9*2+1, 25),
ANIMCMD_FRAME(9*2, 30),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Emotes10[] = {
static const union AnimCmd sSpriteAnim_Emotes10[] =
{
ANIMCMD_FRAME(10*2, 30),
ANIMCMD_FRAME(10*2+1, 25),
ANIMCMD_FRAME(10*2, 30),
@ -336,8 +347,9 @@ static const struct SpriteTemplate sSpriteTemplate_HeartIcon =
.callback = SpriteCB_TrainerIcons
};
static const struct SpriteTemplate sSpriteTemplate_Emote = {
.tileTag = 0xffff,
static const struct SpriteTemplate sSpriteTemplate_Emote =
{
.tileTag = TAG_NONE,
.paletteTag = OBJ_EVENT_PAL_TAG_EMOTES,
.oam = &sOamData_Icons,
.anims = sSpriteAnimTable_Emotes,