From 2358ee88e375ee9dd2a6b850c6a7642795e51eb1 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Sun, 19 May 2024 12:41:51 +0200 Subject: [PATCH 1/5] Fix virtual object events --- asm/macros/event.inc | 2 +- src/scrcmd.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/asm/macros/event.inc b/asm/macros/event.inc index ef1ba30270..25f688aff1 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -1347,7 +1347,7 @@ @ The specified id can be used to refer to the sprite again later with turnvobject. .macro createvobject graphicsId:req, id:req, x:req, y:req, elevation=3, direction=DIR_SOUTH .byte 0xaa - .byte \graphicsId + .2byte \graphicsId .byte \id .2byte \x .2byte \y diff --git a/src/scrcmd.c b/src/scrcmd.c index a3531d3094..64c8c9880c 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1210,10 +1210,10 @@ bool8 ScrCmd_setobjectmovementtype(struct ScriptContext *ctx) bool8 ScrCmd_createvobject(struct ScriptContext *ctx) { - u16 graphicsId = ScriptReadByte(ctx); // Support u16 in createvobject + u16 graphicsId = ScriptReadHalfWord(ctx); // Support u16 in createvobject u8 virtualObjId = ScriptReadByte(ctx); u16 x = VarGet(ScriptReadHalfword(ctx)); - u32 y = VarGet(ScriptReadHalfword(ctx)); + u16 y = VarGet(ScriptReadHalfword(ctx)); u8 elevation = ScriptReadByte(ctx); u8 direction = ScriptReadByte(ctx); From 689f41803da6551a556ba761ad5fdd9658d89548 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Tue, 21 May 2024 09:46:27 +0200 Subject: [PATCH 2/5] fix uppercase typo --- src/scrcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scrcmd.c b/src/scrcmd.c index 64c8c9880c..4083dd82ba 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1210,7 +1210,7 @@ bool8 ScrCmd_setobjectmovementtype(struct ScriptContext *ctx) bool8 ScrCmd_createvobject(struct ScriptContext *ctx) { - u16 graphicsId = ScriptReadHalfWord(ctx); // Support u16 in createvobject + u16 graphicsId = ScriptReadHalfword(ctx); // Support u16 in createvobject u8 virtualObjId = ScriptReadByte(ctx); u16 x = VarGet(ScriptReadHalfword(ctx)); u16 y = VarGet(ScriptReadHalfword(ctx)); From b37d9b30005e63e09f4ff301a3dd35fac1d27444 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Tue, 21 May 2024 22:14:29 -0400 Subject: [PATCH 3/5] fix: disable followers in Union Room Fixed #17 --- data/maps/UnionRoom/scripts.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/maps/UnionRoom/scripts.inc b/data/maps/UnionRoom/scripts.inc index 8a9e7682a5..927c406184 100644 --- a/data/maps/UnionRoom/scripts.inc +++ b/data/maps/UnionRoom/scripts.inc @@ -26,6 +26,7 @@ UnionRoom_OnResume: end UnionRoom_OnTransition: + setflag FLAG_TEMP_HIDE_FOLLOWER end UnionRoom_EventScript_Player1:: @@ -106,4 +107,3 @@ UnionRoom_EventScript_Unused:: waitstate releaseall end - From 0630acce442ae7a2641a602deb71af4bb8a7c3f7 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Mon, 27 May 2024 18:09:12 -0400 Subject: [PATCH 4/5] fix: make `LoadSheetGraphicsInfo` load, then free, tiles Fixes follower pokeball gfx showing garbage for 1 frame when emerging --- src/event_object_movement.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/event_object_movement.c b/src/event_object_movement.c index b8cfb591b3..686bbdd267 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1587,10 +1587,12 @@ u16 LoadSheetGraphicsInfo(const struct ObjectEventGraphicsInfo *info, u16 uuid, u32 sheetSpan = GetSpanPerImage(info->oam->shape, info->oam->size); u16 oldTiles = 0; u16 tileStart; + bool32 oldInvisible; if (tag == TAG_NONE) tag = COMP_OW_TILE_TAG_BASE + uuid; if (sprite) { + oldInvisible = sprite->invisible; oldTiles = sprite->sheetTileStart; sprite->sheetTileStart = 0; // mark unused // Note: If sprite was not allocated to use a sheet, @@ -1604,9 +1606,19 @@ u16 LoadSheetGraphicsInfo(const struct ObjectEventGraphicsInfo *info, u16 uuid, if (tileStart == TAG_NONE) { struct SpriteFrameImage image = {.size = info->size, .data = info->images->data}; struct SpriteTemplate template = {.tileTag = tag, .images = &image}; - if (oldTiles) - FieldEffectFreeTilesIfUnused(oldTiles); + // Load, then free, in order to avoid displaying garbage data + // before sprite's `sheetTileStart` is repointed tileStart = LoadCompressedSpriteSheetByTemplate(&template, TILE_SIZE_4BPP << sheetSpan); + if (oldTiles) { + FieldEffectFreeTilesIfUnused(oldTiles); + // We weren't able to load the sheet; + // retry (after having freed), and set sprite to invisible until done + if (tileStart <= 0) { + if (sprite) + sprite->invisible = TRUE; + tileStart = LoadCompressedSpriteSheetByTemplate(&template, TILE_SIZE_4BPP << sheetSpan); + } + } // sheet loaded; unload any *other* sheet for sprite } else if (oldTiles && oldTiles != tileStart) { FieldEffectFreeTilesIfUnused(oldTiles); @@ -1616,6 +1628,7 @@ u16 LoadSheetGraphicsInfo(const struct ObjectEventGraphicsInfo *info, u16 uuid, sprite->sheetTileStart = tileStart; sprite->sheetSpan = sheetSpan; sprite->usingSheet = TRUE; + sprite->invisible = oldInvisible; } // Going from sheet -> !sheet, reset tile number // (sheet stays loaded) From 3727be9511973783d191633b53d3bffd5a50a46c Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Sat, 1 Jun 2024 14:46:45 -0400 Subject: [PATCH 5/5] fix: fixed a few oversights with follower message generation --- include/follower_helper.h | 2 +- src/event_object_movement.c | 12 +++++++----- src/random.c | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/follower_helper.h b/include/follower_helper.h index bfe19fb2d4..4d316ba1a3 100644 --- a/include/follower_helper.h +++ b/include/follower_helper.h @@ -65,7 +65,7 @@ struct FollowerMsgInfoExtended { #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_NOT_TYPES(type1, type2) MATCH_U8(MSG_COND_TYPE, type1, type2, TYPE_NONE | 1) #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) diff --git a/src/event_object_movement.c b/src/event_object_movement.c index c16de175cc..436f048a5a 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -2114,12 +2114,12 @@ bool32 CheckMsgCondition(const struct MsgCondition *cond, struct Pokemon *mon, u case MSG_COND_TYPE: multi = (SpeciesHasType(species, cond->data.bytes[0]) || SpeciesHasType(species, cond->data.bytes[1])); - // if bytes[2] == TYPE_NONE, + // if bytes[2] nonzero, // invert; check that mon has *neither* type! - if (cond->data.bytes[2] == 0) - return multi; - else + if (cond->data.bytes[2] != 0) return !multi; + else + return multi; break; case MSG_COND_STATUS: return (cond->data.raw & mon->status); @@ -2190,9 +2190,11 @@ bool8 ScrFunc_getfolloweraction(struct ScriptContext *ctx) // Essentially a big [FOLLOWER_EMOTION_UPSET] = 15, [FOLLOWER_EMOTION_ANGRY] = 15, [FOLLOWER_EMOTION_PENSIVE] = 15, + [FOLLOWER_EMOTION_LOVE] = 0, [FOLLOWER_EMOTION_SURPRISE] = 10, [FOLLOWER_EMOTION_CURIOUS] = 10, [FOLLOWER_EMOTION_MUSIC] = 15, + [FOLLOWER_EMOTION_POISONED] = 0, }; u32 i, j; bool32 pickedCondition = FALSE; @@ -2220,7 +2222,7 @@ bool8 ScrFunc_getfolloweraction(struct ScriptContext *ctx) // Essentially a big if (GetCurrentWeather() == WEATHER_SUNNY_CLOUDS) condEmotes[condCount++] = (struct SpecialEmote) {.emotion=FOLLOWER_EMOTION_HAPPY, .index=31}; // Health & status-related - multi = mon->hp * 100 / mon->maxHP; + multi = SAFE_DIV(mon->hp * 100, mon->maxHP); if (multi < 20) { emotion_weight[FOLLOWER_EMOTION_SAD] = 30; condEmotes[condCount++] = (struct SpecialEmote) {.emotion=FOLLOWER_EMOTION_SAD, .index=4}; diff --git a/src/random.c b/src/random.c index 145da9bf63..c7f8212bdd 100644 --- a/src/random.c +++ b/src/random.c @@ -35,15 +35,15 @@ u16 Random2(void) // Returns a random index according to a list of weights u8 RandomWeightedIndex(u8 *weights, u8 length) { u32 i; - u16 random_value; + u16 randomValue; u16 weightSum = 0; for (i = 0; i < length; i++) weightSum += weights[i]; - random_value = Random() % weightSum; + randomValue = weightSum > 0 ? Random() % weightSum : 0; weightSum = 0; for (i = 0; i < length; i++) { weightSum += weights[i]; - if (random_value <= weightSum) + if (randomValue <= weightSum) return i; } }