diff --git a/data/scripts/berry_tree.inc b/data/scripts/berry_tree.inc index 8ad300df52..c302f07eb0 100644 --- a/data/scripts/berry_tree.inc +++ b/data/scripts/berry_tree.inc @@ -103,13 +103,25 @@ BerryTree_EventScript_CheckBerryFullyGrown:: lock faceplayer special ObjectEventInteractionGetBerryCountString +.if OW_BERRY_MUTATIONS == TRUE + goto_if_eq VAR_RESULT, TRUE, BerryTree_EventScript_CheckBerryFullyGrown_Mutation +.endif msgbox BerryTree_Text_WantToPick, MSGBOX_YESNO goto_if_eq VAR_RESULT, YES, BerryTree_EventScript_PickBerry goto_if_eq VAR_RESULT, NO, BerryTree_EventScript_CancelPickingBerry +.set BERRY_NORMAL_BAG_FULL, 0 +.set BERRY_NORMAL_SPACE_IN_BAG, 1 +.set BERRY_MUTATION_BAG_FULL, 2 +.set BERRY_MUTATION_SPACE_IN_BAG, 3 + BerryTree_EventScript_PickBerry:: special ObjectEventInteractionPickBerryTree - goto_if_eq VAR_0x8004, 0, BerryTree_EventScript_BerryPocketFull + goto_if_eq VAR_0x8004, BERRY_NORMAL_BAG_FULL, BerryTree_EventScript_BerryPocketFull +.if OW_BERRY_MUTATIONS == TRUE + goto_if_eq VAR_0x8004, BERRY_MUTATION_BAG_FULL, BerryTree_EventScript_BerryPocketFull_Mutation + goto_if_eq VAR_0x8004, BERRY_MUTATION_SPACE_IN_BAG, BerryTree_EventScript_PickBerry_Mutation +.endif special IncrementDailyPickedBerries special ObjectEventInteractionRemoveBerryTree message BerryTree_Text_PickedTheBerry @@ -249,3 +261,65 @@ BerryTree_Text_PlantIsDelighted: BerryTree_Text_ExclamationPoint: .string "!$" + +.if OW_BERRY_MUTATIONS == TRUE +BerryTree_EventScript_CheckBerryFullyGrown_Mutation: + msgbox BerryTree_Text_WantToPick_Mutation, MSGBOX_YESNO + goto_if_eq VAR_RESULT, YES, BerryTree_EventScript_PickBerry + goto_if_eq VAR_RESULT, NO, BerryTree_EventScript_CancelPickingBerry_Mutation + +BerryTree_EventScript_CancelPickingBerry_Mutation:: + message BerryTree_Text_BerryLeftUnpicked_Mutation + waitmessage + waitbuttonpress + release + end + +BerryTree_EventScript_BerryPocketFull_Mutation:: + message BerryTree_Text_BerryPocketFull_Mutation + waitmessage + waitbuttonpress + release + end + +BerryTree_EventScript_PickBerry_Mutation:: + @ add items + special IncrementDailyPickedBerries + special ObjectEventInteractionRemoveBerryTree + message BerryTree_Text_PickedTheBerry_Mutation + playfanfare MUS_OBTAIN_BERRY + waitmessage + waitfanfare + waitbuttonpress + message BerryTree_Text_PutAwayBerry_Mutation + waitmessage + waitbuttonpress + release + end + +BerryTree_Text_WantToPick_Mutation: + .string "You found {STR_VAR_2} {STR_VAR_1}\n" + .string "and 1 {STR_VAR_3}!\p" + .string "Do you want to pick them?$" + +BerryTree_Text_BerryLeftUnpicked_Mutation: + .string "{PLAYER} left the {STR_VAR_1}\n" + .string "and the {STR_VAR_3} unpicked.$" + +BerryTree_Text_BerryPocketFull_Mutation: + .string "The BAG's BERRIES POCKET is full.\p" + .string "The {STR_VAR_1} and the\n" + .string "{STR_VAR_3} couldn't be taken.$" + +BerryTree_Text_PickedTheBerry_Mutation: + .string "{PLAYER} picked the {STR_VAR_2} {STR_VAR_1}\n" + .string "and the {STR_VAR_3}.$" + +BerryTree_Text_PutAwayBerry_Mutation: + .string "{PLAYER} put away the {STR_VAR_1}\n" + .string "and the {STR_VAR_3} in the BAG's\l" + .string "BERRIES POCKET.\p" + .string "The soil returned to its soft and\n" + .string "loamy state.$" + +.endif diff --git a/include/config/overworld.h b/include/config/overworld.h index 3488064421..fb24c680b0 100644 --- a/include/config/overworld.h +++ b/include/config/overworld.h @@ -12,6 +12,9 @@ #define OW_PC_PRESS_B GEN_LATEST // In Gen4, pressing B when holding a Pokémon is equivalent to placing it. In Gen3, it gives the "You're holding a Pokémon!" error. #define OW_PC_JAPAN_WALDA_ICONS TRUE // In the US release of Emerald, the Cross, Bolt, and Plusle icons for Walda's wallpapers were left blank from the Japan release. Setting this to TRUE will restore them. +// Berry settings +#define OW_BERRY_MUTATIONS FALSE // If enabled, Berry plants can mutate based on berries planted next to them. + // Out-of-battle Ability effects #define OW_SYNCHRONIZE_NATURE GEN_LATEST // In Gen8, if a Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same Nature, as opposed to 50% previously. Stationary Pokémon are excluded in Gen3. In Gen6, all No Eggs Discovered gift Pokémon will have the same Nature, while in Gen7 all gift Pokémon will, regardless of Egg Group - In Gen 8, no gift Pokémon are affected. In Gen9, this ability has no out-of-battle effect. #define OW_COMPOUND_EYES GEN_LATEST // Prior to Gen9, if a Pokémon with Compound Eyes is leading the party, the wild held item rate is increased to 60%/20%. diff --git a/include/global.berry.h b/include/global.berry.h index 29f1cfe14a..cd6e18e7fb 100644 --- a/include/global.berry.h +++ b/include/global.berry.h @@ -62,16 +62,24 @@ struct BattleEnigmaBerry struct BerryTree { - u8 berry; - u8 stage:7; + u8 berry:7; + u8 weeds:1; + u8 stage:3; + u8 mulch:4; u8 stopGrowth:1; - u16 minutesUntilNextStage; - u8 berryYield; + u16 minutesUntilNextStage:14; + u16 mutationA:2; + u8 berryYield:5; + u8 pests:1; + u8 mutationB:2; u8 regrowthCount:4; u8 watered1:1; u8 watered2:1; u8 watered3:1; u8 watered4:1; + u16 moistureLevel:7; + u16 moistureClock:6; + u16 mutationC:3; }; #endif // GUARD_GLOBAL_BERRY_H diff --git a/src/berry.c b/src/berry.c index 88a5d0f9f3..c2698295ec 100644 --- a/src/berry.c +++ b/src/berry.c @@ -23,6 +23,8 @@ static u8 CalcBerryYieldInternal(u16 max, u16 min, u8 water); static u8 CalcBerryYield(struct BerryTree *tree); static u8 GetBerryCountByBerryTreeId(u8 id); static u16 GetStageDurationByBerryType(u8); +static void SetTreeMutations(u8 id, u8 berry); +static u8 GetTreeMutationValue(u8 id); //.rodata static const u8 sBerryDescriptionPart1_Cheri[] = _("Blooms with delicate pretty flowers."); @@ -1627,6 +1629,8 @@ void PlantBerryTree(u8 id, u8 berry, u8 stage, bool8 allowGrowth) // allowGrowth is always true for berry trees the player has planted if (!allowGrowth) tree->stopGrowth = TRUE; + + SetTreeMutations(id, berry); } void RemoveBerryTree(u8 id) @@ -1787,6 +1791,15 @@ void ObjectEventInteractionGetBerryCountString(void) u8 berry = GetBerryTypeByBerryTreeId(treeId); u8 count = GetBerryCountByBerryTreeId(treeId); GetBerryCountStringByBerryType(berry, gStringVar1, count); + berry = GetTreeMutationValue(treeId); + if (berry > 0) + { + count = 1; + GetBerryCountStringByBerryType(berry, gStringVar3, count); + gSpecialVar_Result = TRUE; + } + else + gSpecialVar_Result = FALSE; } void Bag_ChooseBerry(void) @@ -1806,8 +1819,19 @@ void ObjectEventInteractionPickBerryTree(void) { u8 id = GetObjectEventBerryTreeId(gSelectedObjectEvent); u8 berry = GetBerryTypeByBerryTreeId(id); + u8 mutation = GetTreeMutationValue(id); - gSpecialVar_0x8004 = AddBagItem(BerryTypeToItemId(berry), GetBerryCountByBerryTreeId(id)); + if (!OW_BERRY_MUTATIONS || mutation == 0) + { + gSpecialVar_0x8004 = AddBagItem(BerryTypeToItemId(berry), GetBerryCountByBerryTreeId(id)); + return; + } + gSpecialVar_0x8004 = (CheckBagHasSpace(BerryTypeToItemId(berry), GetBerryCountByBerryTreeId(id)) && CheckBagHasSpace(BerryTypeToItemId(mutation), 1)) + 2; + if (gSpecialVar_0x8004 == 3) + { + AddBagItem(BerryTypeToItemId(berry), GetBerryCountByBerryTreeId(id)); + AddBagItem(BerryTypeToItemId(mutation), 1); + } } void ObjectEventInteractionRemoveBerryTree(void) @@ -1849,3 +1873,109 @@ void SetBerryTreesSeen(void) } } } + +// Berry mutations +#if OW_BERRY_MUTATIONS == TRUE +#define BERRY_MUTATION_CHANCE 25 + +static const u8 sBerryMutations[][3] = { + {ITEM_TO_BERRY(ITEM_IAPAPA_BERRY), ITEM_TO_BERRY(ITEM_MAGO_BERRY), ITEM_TO_BERRY(ITEM_POMEG_BERRY)}, + {ITEM_TO_BERRY(ITEM_CHESTO_BERRY), ITEM_TO_BERRY(ITEM_PERSIM_BERRY), ITEM_TO_BERRY(ITEM_KELPSY_BERRY)}, + {ITEM_TO_BERRY(ITEM_ORAN_BERRY), ITEM_TO_BERRY(ITEM_PECHA_BERRY), ITEM_TO_BERRY(ITEM_QUALOT_BERRY)}, + {ITEM_TO_BERRY(ITEM_CHESTO_BERRY), ITEM_TO_BERRY(ITEM_PERSIM_BERRY), ITEM_TO_BERRY(ITEM_KELPSY_BERRY)}, + {ITEM_TO_BERRY(ITEM_ASPEAR_BERRY), ITEM_TO_BERRY(ITEM_LEPPA_BERRY), ITEM_TO_BERRY(ITEM_HONDEW_BERRY)}, + {ITEM_TO_BERRY(ITEM_AGUAV_BERRY), ITEM_TO_BERRY(ITEM_FIGY_BERRY), ITEM_TO_BERRY(ITEM_GREPA_BERRY)}, + {ITEM_TO_BERRY(ITEM_LUM_BERRY), ITEM_TO_BERRY(ITEM_SITRUS_BERRY), ITEM_TO_BERRY(ITEM_TAMATO_BERRY)}, + {ITEM_TO_BERRY(ITEM_HONDEW_BERRY), ITEM_TO_BERRY(ITEM_YACHE_BERRY), ITEM_TO_BERRY(ITEM_LIECHI_BERRY)}, + {ITEM_TO_BERRY(ITEM_QUALOT_BERRY), ITEM_TO_BERRY(ITEM_TANGA_BERRY), ITEM_TO_BERRY(ITEM_GANLON_BERRY)}, + {ITEM_TO_BERRY(ITEM_GREPA_BERRY), ITEM_TO_BERRY(ITEM_ROSELI_BERRY), ITEM_TO_BERRY(ITEM_SALAC_BERRY)}, + {ITEM_TO_BERRY(ITEM_POMEG_BERRY), ITEM_TO_BERRY(ITEM_KASIB_BERRY), ITEM_TO_BERRY(ITEM_PETAYA_BERRY)}, + {ITEM_TO_BERRY(ITEM_KELPSY_BERRY), ITEM_TO_BERRY(ITEM_WACAN_BERRY), ITEM_TO_BERRY(ITEM_APICOT_BERRY)}, + {ITEM_TO_BERRY(ITEM_GANLON_BERRY), ITEM_TO_BERRY(ITEM_LIECHI_BERRY), ITEM_TO_BERRY(ITEM_KEE_BERRY)}, + {ITEM_TO_BERRY(ITEM_SALAC_BERRY), ITEM_TO_BERRY(ITEM_PETAYA_BERRY), ITEM_TO_BERRY(ITEM_MARANGA_BERRY)}, +}; + +static u8 GetMutationOutcome(u8 berry1, u8 berry2) +{ + u8 i; + for(i = 0; i < ARRAY_COUNT(sBerryMutations); i++) + { + if ((sBerryMutations[i][0] == berry1 && sBerryMutations[i][1] == berry2) + ||(sBerryMutations[i][0] == berry2 && sBerryMutations[i][1] == berry1)) + return sBerryMutations[i][2]; + } + return 0; +} + +static u8 TryForMutation(u8 berryTreeId, u8 berry) +{ + u8 i, j; + s16 x1, x2, y1, y2; + + // Get location of current tree + for (i = 0; i < OBJECT_EVENTS_COUNT; i++) + { + if (gObjectEvents[i].trainerRange_berryTreeId == berryTreeId && gObjectEvents[i].movementType == MOVEMENT_TYPE_BERRY_TREE_GROWTH) + break; + } + if (i == OBJECT_EVENTS_COUNT) + return 0; + + x1 = gObjectEvents[i].currentCoords.x; + y1 = gObjectEvents[i].currentCoords.y; + + // Try mutation for each adjacent tree + for (j = 0; j < OBJECT_EVENTS_COUNT; j++) + { + if (gObjectEvents[j].active && gObjectEvents[j].movementType == MOVEMENT_TYPE_BERRY_TREE_GROWTH && GetStageByBerryTreeId(GetObjectEventBerryTreeId(j)) != BERRY_STAGE_NO_BERRY && j != i) + { + x2 = gObjectEvents[j].currentCoords.x; + y2 = gObjectEvents[j].currentCoords.y; + if (Random() % 100 < BERRY_MUTATION_CHANCE && ( + (x1 == x2 && y1 == y2 - 1) || + (x1 == x2 && y1 == y2 + 1) || + (x1 == x2 - 1 && y1 == y2) || + (x1 == x2 + 1 && y1 == y2))) + return GetMutationOutcome(berry, gSaveBlock1Ptr->berryTrees[GetObjectEventBerryTreeId(j)].berry); + } + } + return 0; +} +#endif + +struct TreeMutationBitfield { + u8 a: 2; + u8 b: 2; + u8 c: 3; + u8 unused: 1; +}; + +union TreeMutation { + u8 value; + struct TreeMutationBitfield asField; +}; + +static u8 GetTreeMutationValue(u8 id) +{ + struct BerryTree *tree = GetBerryTreeInfo(id); + union TreeMutation myMutation; + if (!OW_BERRY_MUTATIONS || tree->stopGrowth) // Pre-generated trees shouldn't have mutations + return 0; + myMutation.asField.a = tree->mutationA; + myMutation.asField.b = tree->mutationB; + myMutation.asField.c = tree->mutationC; + return myMutation.value; +} + +static void SetTreeMutations(u8 id, u8 berry) +{ +#if OW_BERRY_MUTATIONS == TRUE + struct BerryTree *tree = GetBerryTreeInfo(id); + union TreeMutation myMutation; + + myMutation.value = TryForMutation(id, berry); + tree->mutationA = myMutation.asField.a; + tree->mutationB = myMutation.asField.b; + tree->mutationC = myMutation.asField.c; +#endif +}