Merge branch 'followers' into lighting
4
.git-blame-ignore-revs
Normal file
@ -0,0 +1,4 @@
|
||||
725252905baf28dbb9298dd5fa0daaf0e804a455
|
||||
afbb88d77ada8a636a318ec32b61b4ea849d85ab
|
||||
f861504cfc50941768286c0703d24ab0aaceb88e
|
||||
ebbcb7d025cff716eec5008b5dd2b7d55aa8c3f3
|
||||
57
README.md
@ -7,13 +7,21 @@ This fork tries to maintain vanilla compatibility whenever possible. It doesn't
|
||||
There are several branches, each with one main feature (and sometimes some extra stuff):
|
||||
|
||||
**followers** branch:
|
||||
* [HGSS-style pokémon followers](https://bulbapedia.bulbagarden.net/wiki/Walking_Pok%C3%A9mon#Pok.C3.A9mon_HeartGold_and_SoulSilver) for all 386 pokémon, including emotes, the 28 Unown forms and a majority of follower messages.
|
||||
* Dynamic overworld palettes & reflections compatible with vanilla berry trees.
|
||||
* PID (but not legitimacy) preserving Pokémon nature-changing function
|
||||
* Function to detect modern emulators/GBA hardware.
|
||||
* [HGSS-style pokémon followers](https://bulbapedia.bulbagarden.net/wiki/Walking_Pok%C3%A9mon#Pok.C3.A9mon_HeartGold_and_SoulSilver) for all 386 pokémon (including forms & shinies)
|
||||
* Includes follower emotes and a majority of the HGSS messages
|
||||
* Custom pokeball sprites for Gen 1-7 pokéballs
|
||||
* Followers can use field moves in the overworld
|
||||
* Overworld form changes for Ditto, Mew, Castform, etc.
|
||||
* Asymmetrical & 64x64 OW support
|
||||
* Dynamic Overworld Palette System (DOWP) & reflections compatible with berry trees, etc.
|
||||
|
||||
> Note: Unless you have a specific need for it, you should probably use `followers-expanded-id` over this.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
**icons** branch:
|
||||
* Everything from the **followers** branch.
|
||||
* All pokemon icons updated to Gen 6, based on [this repo](https://github.com/msikma/pokesprite/tree/master/icons/pokemon/regular)
|
||||
@ -32,7 +40,7 @@ There are several branches, each with one main feature (and sometimes some extra
|
||||
|
||||
**just-lighting** branch:
|
||||
* `lighting-expanded-id` but with following pokémon code & assets completely removed. (This allows for more than 255 OW graphics)
|
||||
* Saves with following pokémon can safely be loaded.
|
||||
* Saves with following pokémon can still safely be loaded.
|
||||
|
||||
**followers-expanded-id** branch:
|
||||
* Like `followers`, but includes expands OW graphicsIds to 16-bits
|
||||
@ -45,6 +53,12 @@ Additional branches to mention:
|
||||
|
||||
To set up the repository, see [INSTALL.md](INSTALL.md).
|
||||
|
||||
**guillotine** branch:
|
||||
* ~~Decapitates~~ Decapitalizes **all** text at runtime, with some exceptions (see the [FAQ](#guillotine-q-how-can-i-keep-my-strings-from-being-decapped))
|
||||
* Future-proof, does not require mass-replacing strings
|
||||
|
||||
To set up the repository, see [INSTALL.md](INSTALL.md).
|
||||
|
||||
## FAQ
|
||||
### `(followers*)` Q: Where are the config settings?
|
||||
A: Configuration for the follower system is mostly in [event_objects.h](include/constants/event_objects.h):
|
||||
@ -57,6 +71,10 @@ A: Configuration for the follower system is mostly in [event_objects.h](include/
|
||||
// to OW code so that large (48x48, 64x64) OWs
|
||||
// will display correctly under bridges, etc.
|
||||
#define LARGE_OW_SUPPORT TRUE
|
||||
|
||||
// Followers will emerge from the pokeball they are stored in,
|
||||
// instead of a normal pokeball
|
||||
#define OW_MON_POKEBALLS TRUE
|
||||
```
|
||||
|
||||
### `(lighting)` Q: How do I mark certain colors in a palette as light-blended?
|
||||
@ -76,6 +94,35 @@ on separate lines to mark those colors as being light-blended, i.e:
|
||||
|
||||
You might have to `make mostlyclean` or change the `.pal` file to pick up the changes.
|
||||
|
||||
### `(guillotine)` Q: How can I keep my string(s) from being decapped?
|
||||
A: There are a number of ways to make a string "fixed case" so that it will not be decapitalized when displayed:
|
||||
|
||||
C strings: Replace the `_` with `_C`:
|
||||
```c
|
||||
// _C = fixed (C)ase string!
|
||||
const u8 gText_IDNumber[] = _C("IDNo.");
|
||||
```
|
||||
ASM strings: Replace `.string` with `.fixstr`:
|
||||
```arm
|
||||
gText_SavingDontTurnOff::
|
||||
@ Lasts until the string terminator '$'
|
||||
.fixstr "SAVING…\n"
|
||||
.string "DON'T TURN OFF THE POWER.$"
|
||||
```
|
||||
You can fix-case/unfix parts of a string like so:
|
||||
```arm
|
||||
.string "{FIXED_CASE}WARNING!{UNFIX_CASE}\p"
|
||||
```
|
||||
For a placeholder (only the placeholder will be fixed-case):
|
||||
```arm
|
||||
.string "{STR_VAR_2_FIXED} was transferred to\n"
|
||||
.string "BOX “{STR_VAR_1}.”$"
|
||||
```
|
||||
See also the configuration in [text.h](gflib/text.h).
|
||||
|
||||
There's also special handling for "separated bigrams"; basically, two letter words.
|
||||
This includes: `"TM01", "PC", "EV"`, any two uppercase characters surrounded by digits, whitespace, or the start/end of a string. These will not be decapped.
|
||||
|
||||
## See also
|
||||
|
||||
For contacts and other pret projects, see [pret.github.io](https://pret.github.io/).
|
||||
|
||||
@ -84,3 +84,4 @@ AncientTomb_EventScript_RanFromRegisteel::
|
||||
setvar VAR_0x8004, SPECIES_REGISTEEL
|
||||
goto Common_EventScript_LegendaryFlewAway
|
||||
end
|
||||
|
||||
|
||||
@ -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.$"
|
||||
|
||||
|
||||
@ -434,3 +434,4 @@ BattleFrontier_BattlePikeLobby_Text_ExplainMonOrderRules:
|
||||
.string "changed.\p"
|
||||
.string "The sequence must be set before\n"
|
||||
.string "starting your challenge.$"
|
||||
|
||||
|
||||
@ -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.$"
|
||||
|
||||
|
||||
@ -84,3 +84,4 @@ DesertRuins_EventScript_RanFromRegirock::
|
||||
setvar VAR_0x8004, SPECIES_REGIROCK
|
||||
goto Common_EventScript_LegendaryFlewAway
|
||||
end
|
||||
|
||||
|
||||
@ -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!$"
|
||||
|
||||
|
||||
@ -438,3 +438,4 @@ SlateportCity_OceanicMuseum_2F_Text_SSAnneReplica:
|
||||
.string "“S.S. ANNE\p"
|
||||
.string "“A replica of the luxury liner that\n"
|
||||
.string "circles the globe.”$"
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -56,7 +56,6 @@ static void AddSpritesToOamBuffer(void);
|
||||
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);
|
||||
|
||||
@ -298,6 +298,7 @@ void SetOamMatrixRotationScaling(u8 matrixNum, s16 xScale, s16 yScale, u16 rotat
|
||||
u16 LoadSpriteSheet(const struct SpriteSheet *sheet);
|
||||
u16 LoadSpriteSheetByTemplate(const struct SpriteTemplate *template, u8 frame);
|
||||
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);
|
||||
|
||||
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 9.1 KiB |
BIN
graphics/object_events/pics/misc/ball_beast.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
graphics/object_events/pics/misc/ball_cherish.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_dive.png
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
graphics/object_events/pics/misc/ball_dream.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
graphics/object_events/pics/misc/ball_dusk.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_fast.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_friend.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_great.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
graphics/object_events/pics/misc/ball_heal.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_heavy.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_level.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_love.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
graphics/object_events/pics/misc/ball_lure.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_luxury.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_master.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
graphics/object_events/pics/misc/ball_moon.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_nest.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
graphics/object_events/pics/misc/ball_net.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_park.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
graphics/object_events/pics/misc/ball_premier.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
graphics/object_events/pics/misc/ball_quick.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
graphics/object_events/pics/misc/ball_repeat.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_safari.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/misc/ball_sport.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
graphics/object_events/pics/misc/ball_strange.png
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
graphics/object_events/pics/misc/ball_timer.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
graphics/object_events/pics/misc/ball_ultra.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
graphics/object_events/pics/pokemon/substitute.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 1.2 KiB |
@ -276,6 +276,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)
|
||||
|
||||
@ -286,6 +286,10 @@
|
||||
// will display correctly under bridges, etc.
|
||||
#define LARGE_OW_SUPPORT TRUE
|
||||
|
||||
// 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
|
||||
|
||||
@ -110,7 +110,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
|
||||
|
||||
@ -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);
|
||||
void LoadCompressedSpriteSheetOverrideBuffer(const struct CompressedSpriteSheet *src, void *buffer);
|
||||
bool8 LoadCompressedSpriteSheetUsingHeap(const struct CompressedSpriteSheet *src);
|
||||
|
||||
@ -292,6 +292,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 *);
|
||||
|
||||
@ -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,
|
||||
@ -127,5 +113,6 @@ enum {
|
||||
};
|
||||
|
||||
extern const struct FollowerMsgInfoExtended gFollowerConditionalMessages[COND_MSG_COUNT];
|
||||
extern const struct FollowerMessagePool gFollowerBasicMessages[FOLLOWER_EMOTION_LENGTH];
|
||||
|
||||
#endif //GUARD_FOLLOWER_HELPER_H
|
||||
|
||||
@ -275,6 +275,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,
|
||||
|
||||
@ -538,7 +538,6 @@ struct SaveBlock2
|
||||
extern struct SaveBlock2 *gSaveBlock2Ptr;
|
||||
|
||||
extern u8 UpdateSpritePaletteWithTime(u8);
|
||||
extern bool8 IsAccurateGBA(void);
|
||||
|
||||
struct SecretBaseParty
|
||||
{
|
||||
|
||||
@ -11,7 +11,23 @@ remote_path=$(git remote get-url build | sed -nr -e "s/ssh:\/\/\w+@?\w*://p") #
|
||||
make_cmd=$(git config --local remake.make)
|
||||
make_product=$(git config --local remake.src)
|
||||
make_dest=$(git config --local remake.dest)
|
||||
set -x
|
||||
old_head=$(git rev-parse --short @)
|
||||
set +e
|
||||
# Make a temp commit for unstaged changes
|
||||
temp_commit_msg="temp build"
|
||||
git commit -aem "$temp_commit_msg"
|
||||
retVal=$?
|
||||
set -e
|
||||
# set -x
|
||||
git push build --force-with-lease
|
||||
ssh $remote_host "cd $remote_path && git reset --hard && git checkout $git_branch && $make_cmd"
|
||||
scp "$remote_host:$remote_path/$make_product" $make_dest
|
||||
# { set +x; } 2>/dev/null
|
||||
# Reset temp commit
|
||||
if [[ $retVal -eq 0 ]]; then
|
||||
commit_msg=$(git log -1 --pretty=%B)
|
||||
if [[ "$commit_msg" == "$temp_commit_msg" ]]; then
|
||||
git reset "$old_head" &>/dev/null
|
||||
fi
|
||||
fi
|
||||
set -x
|
||||
ssh -o "VisualHostKey=no" $remote_host "cd $remote_path && git reset --hard && git checkout $git_branch && $make_cmd"
|
||||
scp -o "VisualHostKey=no" "$remote_host:$remote_path/$make_product" $make_dest
|
||||
|
||||
@ -687,6 +687,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
|
||||
|
||||
$(OBJEVENTGFXDIR)/pokemon/bulbasaur.4bpp: %.4bpp: %.png
|
||||
$(GFX) $< $@ -mwidth 4 -mheight 4
|
||||
|
||||
@ -1938,5 +1941,8 @@ $(OBJEVENTGFXDIR)/pokemon/deoxys.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
|
||||
|
||||
@ -1053,7 +1053,7 @@ void Bike_HandleBumpySlopeJump(void)
|
||||
|
||||
bool32 IsRunningDisallowed(u8 metatile)
|
||||
{
|
||||
if (IsRunningDisallowedByMetatile(metatile) == TRUE)
|
||||
if (!gMapHeader.allowRunning || IsRunningDisallowedByMetatile(metatile) == TRUE)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
@ -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[] = {
|
||||
};
|
||||
|
||||
static 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[] = {
|
||||
|
||||
@ -346,6 +346,56 @@ const u32 gObjectEventPic_Noland[] = INCBIN_U32("graphics/object_events/pics/peo
|
||||
const u32 gObjectEventPic_Lucy[] = INCBIN_U32("graphics/object_events/pics/people/frontier_brains/lucy.4bpp");
|
||||
const u32 gObjectEventPic_Brandon[] = INCBIN_U32("graphics/object_events/pics/people/frontier_brains/brandon.4bpp");
|
||||
const u32 gObjectEventPic_AnimatedBall[] = INCBIN_U32("graphics/object_events/pics/misc/animated_ball.4bpp");
|
||||
|
||||
#if OW_MON_POKEBALLS
|
||||
// Vanilla
|
||||
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");
|
||||
// Gen IV/Sinnoh
|
||||
#ifdef ITEM_DUSK_BALL
|
||||
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");
|
||||
#endif
|
||||
#ifdef ITEM_PARK_BALL
|
||||
const u32 gObjectEventPic_ParkBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_park.4bpp");
|
||||
#endif
|
||||
// Gen II/Johto Apricorns
|
||||
#ifdef ITEM_FAST_BALL
|
||||
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");
|
||||
#endif
|
||||
// Gen V
|
||||
#ifdef ITEM_DREAM_BALL
|
||||
const u32 gObjectEventPic_DreamBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_dream.4bpp");
|
||||
#endif
|
||||
// Gen VII
|
||||
#ifdef ITEM_BEAST_BALL
|
||||
const u32 gObjectEventPic_BeastBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_beast.4bpp");
|
||||
#endif
|
||||
// Gen VIII
|
||||
#ifdef ITEM_STRANGE_BALL
|
||||
const u32 gObjectEventPic_StrangeBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_strange.4bpp");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const u32 gObjectEventPic_Substitute[] = INCBIN_U32("graphics/object_events/pics/pokemon/substitute.4bpp");
|
||||
const u32 gObjectEventPic_Bulbasaur[] = INCBIN_U32("graphics/object_events/pics/pokemon/bulbasaur.4bpp");
|
||||
const u32 gObjectEventPic_Ivysaur[] = INCBIN_U32("graphics/object_events/pics/pokemon/ivysaur.4bpp");
|
||||
const u32 gObjectEventPic_Venusaur[] = INCBIN_U32("graphics/object_events/pics/pokemon/venusaur.4bpp");
|
||||
@ -792,5 +842,44 @@ const u16 gObjectEventPal_Lugia[] = INCBIN_U16("graphics/object_events/palettes/
|
||||
|
||||
const u16 gObjectEventPaletteLight[] = INCBIN_U16("graphics/object_events/palettes/light.gbapal");
|
||||
const u16 gObjectEventPaletteLight2[] = INCBIN_U16("graphics/object_events/palettes/light2.gbapal");
|
||||
const u16 gObjectEventPal_Substitute[] = INCBIN_U16("graphics/object_events/pics/pokemon/substitute.gbapal");
|
||||
|
||||
const u16 gObjectEventPaletteEmotes[] = INCBIN_U16("graphics/misc/emotes.gbapal");
|
||||
const u16 gObjectEventPaletteNeonLight[] = INCBIN_U16("graphics/object_events/palettes/neon_light.gbapal");
|
||||
|
||||
#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
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
// Species-indexed pokemon object event table
|
||||
const struct ObjectEventGraphicsInfo gPokemonObjectGraphics[] = {
|
||||
// placeholder gfx, used when other gfx aren't found
|
||||
[SPECIES_NONE] = {0xFFFF, OBJ_EVENT_PAL_TAG_SUBSTITUTE, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_Substitute, gDummySpriteAffineAnimTable},
|
||||
[SPECIES_BULBASAUR] = {0xFFFF, OBJ_EVENT_PAL_TAG_DYNAMIC, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_FOOT, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_Bulbasaur, gDummySpriteAffineAnimTable},
|
||||
[SPECIES_IVYSAUR] = {0xFFFF, OBJ_EVENT_PAL_TAG_DYNAMIC, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_FOOT, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_Ivysaur, gDummySpriteAffineAnimTable},
|
||||
[SPECIES_VENUSAUR] = {0xFFFF, OBJ_EVENT_PAL_TAG_DYNAMIC, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_FOOT, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_Venusaur, gDummySpriteAffineAnimTable},
|
||||
@ -416,9 +418,89 @@ const struct ObjectEventGraphicsInfo gPokemonObjectGraphics[] = {
|
||||
};
|
||||
|
||||
// Normal, sunny, rainy, snowy
|
||||
const struct ObjectEventGraphicsInfo gCastformObjectGraphics[] = {
|
||||
{0xFFFF, OBJ_EVENT_PAL_TAG_DYNAMIC, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_Castform, gDummySpriteAffineAnimTable},
|
||||
{0xFFFF, OBJ_EVENT_PAL_TAG_CASTFORM_SUNNY, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_CastformSunny, gDummySpriteAffineAnimTable},
|
||||
{0xFFFF, OBJ_EVENT_PAL_TAG_CASTFORM_RAINY, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_CastformRainy, gDummySpriteAffineAnimTable},
|
||||
{0xFFFF, OBJ_EVENT_PAL_TAG_CASTFORM_SNOWY, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_CastformSnowy, gDummySpriteAffineAnimTable},
|
||||
const struct ObjectEventGraphicsInfo gCastformObjectGraphics[] =
|
||||
{
|
||||
{TAG_NONE, OBJ_EVENT_PAL_TAG_DYNAMIC, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_Castform, gDummySpriteAffineAnimTable},
|
||||
{TAG_NONE, OBJ_EVENT_PAL_TAG_CASTFORM_SUNNY, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_CastformSunny, gDummySpriteAffineAnimTable},
|
||||
{TAG_NONE, OBJ_EVENT_PAL_TAG_CASTFORM_RAINY, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_CastformRainy, gDummySpriteAffineAnimTable},
|
||||
{TAG_NONE, OBJ_EVENT_PAL_TAG_CASTFORM_SNOWY, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_CastformSnowy, gDummySpriteAffineAnimTable},
|
||||
};
|
||||
|
||||
// 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[][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},
|
||||
};
|
||||
|
||||
#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
|
||||
|
||||
@ -1987,11 +1987,146 @@ static const struct SpriteFrameImage sPicTable_AnimatedBall[] = {
|
||||
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, 5),
|
||||
overworld_frame(gObjectEventPic_AnimatedBall, 2, 4, 0),
|
||||
};
|
||||
|
||||
extern const struct SpriteFrameImage gFieldEffectObjectPicTable_BallLight[];
|
||||
|
||||
#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),
|
||||
};
|
||||
|
||||
// Gen IV/Sinnoh
|
||||
#ifdef ITEM_DUSK_BALL
|
||||
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),
|
||||
};
|
||||
#endif
|
||||
#ifdef ITEM_PARK_BALL
|
||||
static const struct SpriteFrameImage sPicTable_Ball_PARK[] = {
|
||||
POKEBALL_PIC_FRAMES(Park),
|
||||
};
|
||||
#endif
|
||||
|
||||
// Gen II/Johto Apricorns
|
||||
#ifdef ITEM_FAST_BALL
|
||||
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),
|
||||
};
|
||||
#endif
|
||||
|
||||
// Gen V
|
||||
#ifdef ITEM_DREAM_BALL
|
||||
static const struct SpriteFrameImage sPicTable_Ball_DREAM[] = {
|
||||
POKEBALL_PIC_FRAMES(Dream),
|
||||
};
|
||||
#endif
|
||||
|
||||
// Gen VII
|
||||
#ifdef ITEM_BEAST_BALL
|
||||
static const struct SpriteFrameImage sPicTable_Ball_BEAST[] = {
|
||||
POKEBALL_PIC_FRAMES(Beast),
|
||||
};
|
||||
#endif
|
||||
|
||||
// Gen VIII
|
||||
#ifdef ITEM_STRANGE_BALL
|
||||
static const struct SpriteFrameImage sPicTable_Ball_STRANGE[] = {
|
||||
POKEBALL_PIC_FRAMES(Strange),
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static const struct SpriteFrameImage sPicTable_Substitute[] = {
|
||||
overworld_frame(gObjectEventPic_Substitute, 4, 4, 0),
|
||||
overworld_frame(gObjectEventPic_Substitute, 4, 4, 1),
|
||||
overworld_frame(gObjectEventPic_Substitute, 4, 4, 2),
|
||||
overworld_frame(gObjectEventPic_Substitute, 4, 4, 3),
|
||||
overworld_frame(gObjectEventPic_Substitute, 4, 4, 4),
|
||||
overworld_frame(gObjectEventPic_Substitute, 4, 4, 5),
|
||||
};
|
||||
static const struct SpriteFrameImage sPicTable_Bulbasaur[] = {
|
||||
overworld_frame(gObjectEventPic_Bulbasaur, 4, 4, 0),
|
||||
overworld_frame(gObjectEventPic_Bulbasaur, 4, 4, 1),
|
||||
|
||||
@ -19,6 +19,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;
|
||||
|
||||
@ -687,7 +687,8 @@ static void Task_DoDoorWarp(u8 taskId)
|
||||
FreezeObjectEvents();
|
||||
PlayerGetDestCoords(x, y);
|
||||
PlaySE(GetDoorSoundEffect(*x, *y - 1));
|
||||
if (followerObject) { // Put follower into pokeball
|
||||
if (followerObject) {
|
||||
// Put follower into pokeball
|
||||
ClearObjectEventMovement(followerObject, &gSprites[followerObject->spriteId]);
|
||||
ObjectEventSetHeldMovement(followerObject, MOVEMENT_ACTION_ENTER_POKEBALL);
|
||||
}
|
||||
|
||||
@ -80,241 +80,236 @@ 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)},
|
||||
},
|
||||
[COND_MSG_DAY] =
|
||||
{
|
||||
.text = (u8*)sDayTexts,
|
||||
.textSpread = 1,
|
||||
.wt = {.timeOfDay = TIME_OF_DAY_DAY},
|
||||
.wtFlags = 3, // time
|
||||
.emotion = FOLLOWER_EMOTION_MUSIC,
|
||||
.conditions = {MATCH_TIME_OF_DAY(TIME_OF_DAY_DAY)},
|
||||
},
|
||||
[COND_MSG_NIGHT] =
|
||||
{
|
||||
.text = (u8*)sNightTexts,
|
||||
.textSpread = 1,
|
||||
.wt = {.timeOfDay = TIME_OF_DAY_NIGHT},
|
||||
.wtFlags = 3, // time
|
||||
.emotion = FOLLOWER_EMOTION_MUSIC,
|
||||
.conditions = {MATCH_TIME_OF_DAY(TIME_OF_DAY_NIGHT)},
|
||||
},
|
||||
};
|
||||
|
||||
// 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},
|
||||
};
|
||||
|
||||
10
src/main.c
@ -441,13 +441,3 @@ void ClearPokemonCrySongs(void)
|
||||
{
|
||||
CpuFill16(0, gPokemonCrySongs, MAX_POKEMON_CRIES * sizeof(struct PokemonCrySong));
|
||||
}
|
||||
|
||||
// TODO: Needs to be updated if compiling for a different processor than the GBA's
|
||||
bool8 IsAccurateGBA(void) { // tests to see whether running on either an accurate emulator in >=2020, or real hardware
|
||||
u32 code[5] = {0xFF1EE12F, 0xE1DF00B0, 0xE12FFF1E, 0xAAAABBBB, 0xCCCCDDDD}; // ARM: _;ldrh r0, [pc];bx lr
|
||||
u32 func = (u32) &code[0];
|
||||
if (func & 3) // not word aligned; safer to just return false here
|
||||
return FALSE;
|
||||
func = (func & ~3) | 0x2; // misalign PC to test PC-relative loading
|
||||
return ((u32 (*)(void)) func)() == code[3] >> 16;
|
||||
}
|
||||
|
||||
@ -206,7 +206,6 @@ EWRAM_DATA static u16 sAmbientCrySpecies = 0;
|
||||
EWRAM_DATA static bool8 sIsAmbientCryWaterMon = FALSE;
|
||||
EWRAM_DATA struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4] = {0};
|
||||
|
||||
|
||||
static const struct WarpData sDummyWarpData =
|
||||
{
|
||||
.mapGroup = MAP_GROUP(UNDEFINED),
|
||||
@ -2130,6 +2129,7 @@ static bool32 ReturnToFieldLocal(u8 *state)
|
||||
case 3:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@ -512,13 +512,12 @@ static u8 UpdateTimeOfDayPaletteFade(void)
|
||||
|
||||
// First pply TOD blend to relevant subset of palettes
|
||||
if (gPaletteFade.objPaletteToggle) { // Sprite palettes, don't blend those with tags
|
||||
u8 i;
|
||||
u16 j = 1;
|
||||
u32 i;
|
||||
u32 j = 1;
|
||||
for (i = 0; i < 16; i++, j <<= 1) { // Mask out palettes that should not be light blended
|
||||
if ((selectedPalettes & j) && !(GetSpritePaletteTagByPaletteNum(i) >> 15))
|
||||
timePalettes |= j;
|
||||
}
|
||||
|
||||
} else { // tile palettes, don't blend [13, 15]
|
||||
timePalettes = selectedPalettes & 0x1FFF;
|
||||
}
|
||||
|
||||
@ -3360,36 +3360,23 @@ static void PrintRibbonCount(void)
|
||||
PrintTextOnWindow(AddWindowFromTemplateList(sPageSkillsTemplate, PSS_DATA_WINDOW_SKILLS_RIBBON_COUNT), text, x, 1, 0, 0);
|
||||
}
|
||||
|
||||
// Based on https://www.pokecommunity.com/showpost.php?p=10024409&postcount=21
|
||||
static void BufferStat(u8 *dst, s8 natureMod, u32 stat, u32 strId, u32 n) {
|
||||
static const u8 textNatureMinus[] = _("{COLOR_HIGHLIGHT_SHADOW}{BLUE}{TRANSPARENT}{07}"); // Blue
|
||||
static const u8 textNaturePlus[] = _("{COLOR_HIGHLIGHT_SHADOW}{05}{TRANSPARENT}{06}"); // Red
|
||||
static const u8 textNatureNone[] = _("{COLOR_HIGHLIGHT_SHADOW}{01}{TRANSPARENT}{DARK_GRAY}"); // Black
|
||||
u8 *txtPtr;
|
||||
if (natureMod == 0)
|
||||
txtPtr = StringCopy(dst, textNatureNone);
|
||||
else if (natureMod > 0)
|
||||
txtPtr = StringCopy(dst, textNaturePlus);
|
||||
else
|
||||
txtPtr = StringCopy(dst, textNatureMinus);
|
||||
|
||||
ConvertIntToDecimalStringN(txtPtr, stat, STR_CONV_MODE_RIGHT_ALIGN, n);
|
||||
DynamicPlaceholderTextUtil_SetPlaceholderPtr(strId, dst);
|
||||
}
|
||||
|
||||
static void BufferLeftColumnStats(void)
|
||||
{
|
||||
u8 *currentHPString = Alloc(20);
|
||||
u8 *maxHPString = Alloc(20);
|
||||
u8 *attackString = Alloc(20);
|
||||
u8 *defenseString = Alloc(20);
|
||||
const s8 *natureMod = gNatureStatTable[sMonSummaryScreen->summary.nature];
|
||||
u8 *currentHPString = Alloc(8);
|
||||
u8 *maxHPString = Alloc(8);
|
||||
u8 *attackString = Alloc(8);
|
||||
u8 *defenseString = Alloc(8);
|
||||
|
||||
ConvertIntToDecimalStringN(currentHPString, sMonSummaryScreen->summary.currentHP, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
ConvertIntToDecimalStringN(maxHPString, sMonSummaryScreen->summary.maxHP, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
ConvertIntToDecimalStringN(attackString, sMonSummaryScreen->summary.atk, STR_CONV_MODE_RIGHT_ALIGN, 7);
|
||||
ConvertIntToDecimalStringN(defenseString, sMonSummaryScreen->summary.def, STR_CONV_MODE_RIGHT_ALIGN, 7);
|
||||
|
||||
DynamicPlaceholderTextUtil_Reset();
|
||||
BufferStat(currentHPString, 0, sMonSummaryScreen->summary.currentHP, 0, 3);
|
||||
BufferStat(maxHPString, 0, sMonSummaryScreen->summary.maxHP, 1, 3);
|
||||
BufferStat(attackString, natureMod[STAT_ATK - 1], sMonSummaryScreen->summary.atk, 2, 7);
|
||||
BufferStat(defenseString, natureMod[STAT_DEF - 1], sMonSummaryScreen->summary.def, 3, 7);
|
||||
DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, currentHPString);
|
||||
DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, maxHPString);
|
||||
DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, attackString);
|
||||
DynamicPlaceholderTextUtil_SetPlaceholderPtr(3, defenseString);
|
||||
DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar4, sStatsLeftColumnLayout);
|
||||
|
||||
Free(currentHPString);
|
||||
@ -3405,12 +3392,14 @@ static void PrintLeftColumnStats(void)
|
||||
|
||||
static void BufferRightColumnStats(void)
|
||||
{
|
||||
const s8 *natureMod = gNatureStatTable[sMonSummaryScreen->summary.nature];
|
||||
ConvertIntToDecimalStringN(gStringVar1, sMonSummaryScreen->summary.spatk, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
ConvertIntToDecimalStringN(gStringVar2, sMonSummaryScreen->summary.spdef, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
ConvertIntToDecimalStringN(gStringVar3, sMonSummaryScreen->summary.speed, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
|
||||
DynamicPlaceholderTextUtil_Reset();
|
||||
BufferStat(gStringVar1, natureMod[STAT_SPATK - 1], sMonSummaryScreen->summary.spatk, 0, 3);
|
||||
BufferStat(gStringVar2, natureMod[STAT_SPDEF - 1], sMonSummaryScreen->summary.spdef, 1, 3);
|
||||
BufferStat(gStringVar3, natureMod[STAT_SPEED - 1], sMonSummaryScreen->summary.speed, 2, 3);
|
||||
DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1);
|
||||
DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, gStringVar2);
|
||||
DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, gStringVar3);
|
||||
DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar4, sStatsRightColumnLayout);
|
||||
}
|
||||
|
||||
|
||||
@ -1019,7 +1019,8 @@ bool8 ScrCmd_applymovement(struct ScriptContext *ctx)
|
||||
}
|
||||
ScriptMovement_StartObjectMovementScript(localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, movementScript);
|
||||
sMovingNpcId = localId;
|
||||
if (localId != OBJ_EVENT_ID_FOLLOWER && !FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT)) { // Force follower into pokeball
|
||||
// Force follower into pokeball
|
||||
if (localId != OBJ_EVENT_ID_FOLLOWER && !FlagGet(FLAG_SAFE_FOLLOWER_MOVEMENT)) {
|
||||
objEvent = GetFollowerObject();
|
||||
// return early if no follower or in shadowing state
|
||||
if (objEvent == NULL || gSprites[objEvent->spriteId].data[1] == 0)
|
||||
|
||||
@ -867,7 +867,10 @@ static void BuyMenuCollectObjectEventData(void)
|
||||
u8 objEventId = GetObjectEventIdByXY(facingX - 4 + x, facingY - 2 + y);
|
||||
|
||||
// skip if invalid or an overworld pokemon that is not following the player
|
||||
if (objEventId != OBJECT_EVENTS_COUNT && !(gObjectEvents[objEventId].active && gObjectEvents[objEventId].graphicsId == OBJ_EVENT_GFX_OW_MON && gObjectEvents[objEventId].localId != OBJ_EVENT_ID_FOLLOWER))
|
||||
if (objEventId != OBJECT_EVENTS_COUNT
|
||||
&& !(gObjectEvents[objEventId].active
|
||||
&& gObjectEvents[objEventId].graphicsId == OBJ_EVENT_GFX_OW_MON
|
||||
&& gObjectEvents[objEventId].localId != OBJ_EVENT_ID_FOLLOWER))
|
||||
{
|
||||
sShopData->viewportObjects[numObjects][OBJ_EVENT_ID] = objEventId;
|
||||
sShopData->viewportObjects[numObjects][X_COORD] = x;
|
||||
|
||||
@ -152,101 +152,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),
|
||||
@ -271,7 +282,8 @@ static const union AnimCmd *const sSpriteAnimTable_Icons[] =
|
||||
sSpriteAnim_Icons2
|
||||
};
|
||||
|
||||
static const union AnimCmd *const sSpriteAnimTable_Emotes[] = {
|
||||
static const union AnimCmd *const sSpriteAnimTable_Emotes[] =
|
||||
{
|
||||
sSpriteAnim_Emotes0,
|
||||
sSpriteAnim_Emotes1,
|
||||
sSpriteAnim_Emotes2,
|
||||
@ -311,8 +323,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,
|
||||
@ -842,7 +855,8 @@ u8 FldEff_ExclamationMarkIcon(void)
|
||||
u8 FldEff_QuestionMarkIcon(void)
|
||||
{
|
||||
u8 spriteId;
|
||||
if (gFieldEffectArguments[7] >= 0) { // Use follower emotes
|
||||
if (gFieldEffectArguments[7] >= 0) {
|
||||
// Use follower emotes
|
||||
u8 emotion = gFieldEffectArguments[7];
|
||||
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_Emote, 0, 0, 0x52);
|
||||
if (spriteId == MAX_SPRITES)
|
||||
|
||||