#include "global.h"
#include "berry.h"
#include "event_object_movement.h"
#include "field_control_avatar.h"
#include "fieldmap.h"
#include "item.h"
#include "item_menu.h"
#include "item_use.h"
#include "main.h"
#include "menu.h"
#include "random.h"
#include "task.h"
#include "text.h"
#include "constants/berry.h"
#include "constants/event_object_movement.h"
#include "constants/items.h"

#ifdef ENGLISH
#define NAME_CHERI_BERRY   _("CHERI")
#define NAME_CHESTO_BERRY  _("CHESTO")
#define NAME_PECHA_BERRY   _("PECHA")
#define NAME_RAWST_BERRY   _("RAWST")
#define NAME_ASPEAR_BERRY  _("ASPEAR")
#define NAME_LEPPA_BERRY   _("LEPPA")
#define NAME_ORAN_BERRY    _("ORAN")
#define NAME_PERSIM_BERRY  _("PERSIM")
#define NAME_LUM_BERRY     _("LUM")
#define NAME_SITRUS_BERRY  _("SITRUS")
#define NAME_FIGY_BERRY    _("FIGY")
#define NAME_WIKI_BERRY    _("WIKI")
#define NAME_MAGO_BERRY    _("MAGO")
#define NAME_AGUAV_BERRY   _("AGUAV")
#define NAME_IAPAPA_BERRY  _("IAPAPA")
#define NAME_RAZZ_BERRY    _("RAZZ")
#define NAME_BLUK_BERRY    _("BLUK")
#define NAME_NANAB_BERRY   _("NANAB")
#define NAME_WEPEAR_BERRY  _("WEPEAR")
#define NAME_PINAP_BERRY   _("PINAP")
#define NAME_POMEG_BERRY   _("POMEG")
#define NAME_KELPSY_BERRY  _("KELPSY")
#define NAME_QUALOT_BERRY  _("QUALOT")
#define NAME_HONDEW_BERRY  _("HONDEW")
#define NAME_GREPA_BERRY   _("GREPA")
#define NAME_TAMATO_BERRY  _("TAMATO")
#define NAME_CORNN_BERRY   _("CORNN")
#define NAME_MAGOST_BERRY  _("MAGOST")
#define NAME_RABUTA_BERRY  _("RABUTA")
#define NAME_NOMEL_BERRY   _("NOMEL")
#define NAME_SPELON_BERRY  _("SPELON")
#define NAME_PAMTRE_BERRY  _("PAMTRE")
#define NAME_WATMEL_BERRY  _("WATMEL")
#define NAME_DURIN_BERRY   _("DURIN")
#define NAME_BELUE_BERRY   _("BELUE")
#define NAME_LIECHI_BERRY  _("LIECHI")
#define NAME_GANLON_BERRY  _("GANLON")
#define NAME_SALAC_BERRY   _("SALAC")
#define NAME_PETAYA_BERRY  _("PETAYA")
#define NAME_APICOT_BERRY  _("APICOT")
#define NAME_LANSAT_BERRY  _("LANSAT")
#define NAME_STARF_BERRY   _("STARF")
#define NAME_ENIGMA_BERRY  _("ENIGMA")

static const u8 sBerryDescriptionPart1_Cheri[] = _("Blooms with delicate pretty flowers.");
static const u8 sBerryDescriptionPart2_Cheri[] = _("The bright red BERRY is very spicy.");
static const u8 sBerryDescriptionPart1_Chesto[] = _("The BERRY's thick skin and fruit are");
static const u8 sBerryDescriptionPart2_Chesto[] = _("very tough. It is dry-tasting all over.");
static const u8 sBerryDescriptionPart1_Pecha[] = _("Very sweet and delicious.");
static const u8 sBerryDescriptionPart2_Pecha[] = _("Also very tender - handle with care.");
static const u8 sBerryDescriptionPart1_Rawst[] = _("If the leaves grow long and curly,");
static const u8 sBerryDescriptionPart2_Rawst[] = _("the BERRY seems to grow very bitter.");
static const u8 sBerryDescriptionPart1_Aspear[] = _("The hard BERRY is dense with a rich");
static const u8 sBerryDescriptionPart2_Aspear[] = _("juice. It is quite sour.");
static const u8 sBerryDescriptionPart1_Leppa[] = _("Grows slower than CHERI and others.");
static const u8 sBerryDescriptionPart2_Leppa[] = _("The smaller the BERRY, the tastier.");
static const u8 sBerryDescriptionPart1_Oran[] = _("A peculiar BERRY with a mix of flavors.");
static const u8 sBerryDescriptionPart2_Oran[] = _("BERRIES grow in half a day.");
static const u8 sBerryDescriptionPart1_Persim[] = _("Loves sunlight. The BERRY's color");
static const u8 sBerryDescriptionPart2_Persim[] = _("grows vivid when exposed to the sun.");
static const u8 sBerryDescriptionPart1_Lum[] = _("Slow to grow. If raised with loving");
static const u8 sBerryDescriptionPart2_Lum[] = _("care, it may grow two BERRIES.");
static const u8 sBerryDescriptionPart1_Sitrus[] = _("Closely related to ORAN. The large");
static const u8 sBerryDescriptionPart2_Sitrus[] = _("BERRY has a well-rounded flavor.");
static const u8 sBerryDescriptionPart1_Figy[] = _("The BERRY, which looks chewed up,");
static const u8 sBerryDescriptionPart2_Figy[] = _("brims with spicy substances.");
static const u8 sBerryDescriptionPart1_Wiki[] = _("The BERRY is said to have grown lumpy");
static const u8 sBerryDescriptionPart2_Wiki[] = _("to help POKéMON grip it.");
static const u8 sBerryDescriptionPart1_Mago[] = _("The BERRY turns curvy as it grows.");
static const u8 sBerryDescriptionPart2_Mago[] = _("The curvier, the sweeter and tastier.");
static const u8 sBerryDescriptionPart1_Aguav[] = _("The flower is dainty. It is rare in its");
static const u8 sBerryDescriptionPart2_Aguav[] = _("ability to grow without light.");
static const u8 sBerryDescriptionPart1_Iapapa[] = _("The BERRY is very big and sour.");
static const u8 sBerryDescriptionPart2_Iapapa[] = _("It takes at least a day to grow.");
static const u8 sBerryDescriptionPart1_Razz[] = _("The red BERRY tastes slightly spicy.");
static const u8 sBerryDescriptionPart2_Razz[] = _("It grows quickly in just four hours.");
static const u8 sBerryDescriptionPart1_Bluk[] = _("The BERRY is blue on the outside, but");
static const u8 sBerryDescriptionPart2_Bluk[] = _("it blackens the mouth when eaten.");
static const u8 sBerryDescriptionPart1_Nanab[] = _("This BERRY was the seventh");
static const u8 sBerryDescriptionPart2_Nanab[] = _("discovered in the world. It is sweet.");
static const u8 sBerryDescriptionPart1_Wepear[] = _("The flower is small and white. It has a");
static const u8 sBerryDescriptionPart2_Wepear[] = _("delicate balance of bitter and sour.");
static const u8 sBerryDescriptionPart1_Pinap[] = _("Weak against wind and cold.");
static const u8 sBerryDescriptionPart2_Pinap[] = _("The fruit is spicy and the skin, sour.");
static const u8 sBerryDescriptionPart1_Pomeg[] = _("However much it is watered,");
static const u8 sBerryDescriptionPart2_Pomeg[] = _("it only grows up to six BERRIES.");
static const u8 sBerryDescriptionPart1_Kelpsy[] = _("A rare variety shaped like a root.");
static const u8 sBerryDescriptionPart2_Kelpsy[] = _("Grows a very large flower.");
static const u8 sBerryDescriptionPart1_Qualot[] = _("Loves water. Grows strong even in");
static const u8 sBerryDescriptionPart2_Qualot[] = _("locations with constant rainfall.");
static const u8 sBerryDescriptionPart1_Hondew[] = _("A BERRY that is very valuable and");
static const u8 sBerryDescriptionPart2_Hondew[] = _("rarely seen. It is very delicious.");
static const u8 sBerryDescriptionPart1_Grepa[] = _("Despite its tenderness and round");
static const u8 sBerryDescriptionPart2_Grepa[] = _("shape, the BERRY is unimaginably sour.");
static const u8 sBerryDescriptionPart1_Tamato[] = _("The BERRY is lip-bendingly spicy.");
static const u8 sBerryDescriptionPart2_Tamato[] = _("It takes time to grow.");
static const u8 sBerryDescriptionPart1_Cornn[] = _("A BERRY from an ancient era. May not");
static const u8 sBerryDescriptionPart2_Cornn[] = _("grow unless planted in quantity.");
static const u8 sBerryDescriptionPart1_Magost[] = _("A BERRY that is widely said to have");
static const u8 sBerryDescriptionPart2_Magost[] = _("a finely balanced flavor.");
static const u8 sBerryDescriptionPart1_Rabuta[] = _("A rare variety that is overgrown with");
static const u8 sBerryDescriptionPart2_Rabuta[] = _("hair. It is quite bitter.");
static const u8 sBerryDescriptionPart1_Nomel[] = _("Quite sour. Just one bite makes it");
static const u8 sBerryDescriptionPart2_Nomel[] = _("impossible to taste for three days.");
static const u8 sBerryDescriptionPart1_Spelon[] = _("The vividly red BERRY is very spicy.");
static const u8 sBerryDescriptionPart2_Spelon[] = _("Its warts secrete a spicy substance.");
static const u8 sBerryDescriptionPart1_Pamtre[] = _("Drifts on the sea from somewhere.");
static const u8 sBerryDescriptionPart2_Pamtre[] = _("It is thought to grow elsewhere.");
static const u8 sBerryDescriptionPart1_Watmel[] = _("A huge BERRY, with some over 20");
static const u8 sBerryDescriptionPart2_Watmel[] = _("inches discovered. Exceedingly sweet.");
static const u8 sBerryDescriptionPart1_Durin[] = _("Bitter to even look at. It is so");
static const u8 sBerryDescriptionPart2_Durin[] = _("bitter, no one has ever eaten it as is.");
static const u8 sBerryDescriptionPart1_Belue[] = _("It is glossy and looks delicious, but");
static const u8 sBerryDescriptionPart2_Belue[] = _("it is awfully sour. Takes time to grow.");
static const u8 sBerryDescriptionPart1_Liechi[] = _("A mysterious BERRY. It is rumored to");
static const u8 sBerryDescriptionPart2_Liechi[] = _("contain the power of the sea.");
static const u8 sBerryDescriptionPart1_Ganlon[] = _("A mysterious BERRY. It is rumored to");
static const u8 sBerryDescriptionPart2_Ganlon[] = _("contain the power of the land.");
static const u8 sBerryDescriptionPart1_Salac[] = _("A mysterious BERRY. It is rumored to");
static const u8 sBerryDescriptionPart2_Salac[] = _("contain the power of the sky.");
static const u8 sBerryDescriptionPart1_Petaya[] = _("A mysterious BERRY. It is rumored to");
static const u8 sBerryDescriptionPart2_Petaya[] = _("contain the power of all living things.");
static const u8 sBerryDescriptionPart1_Apicot[] = _("A very mystifying BERRY. No telling");
static const u8 sBerryDescriptionPart2_Apicot[] = _("what may happen or how it can be used.");
static const u8 sBerryDescriptionPart1_Lansat[] = _("Said to be a legendary BERRY.");
static const u8 sBerryDescriptionPart2_Lansat[] = _("Holding it supposedly brings joy.");
static const u8 sBerryDescriptionPart1_Starf[] = _("So strong, it was abandoned at the");
static const u8 sBerryDescriptionPart2_Starf[] = _("world's edge. Considered a mirage.");
static const u8 sBerryDescriptionPart1_Enigma[] = _("A completely enigmatic BERRY.");
static const u8 sBerryDescriptionPart2_Enigma[] = _("Appears to have the power of stars.");
#elif defined(GERMAN)
#define NAME_CHERI_BERRY   _("AMRENA")
#define NAME_CHESTO_BERRY  _("MARON")
#define NAME_PECHA_BERRY   _("PIRSIF")
#define NAME_RAWST_BERRY   _("FRAGIA")
#define NAME_ASPEAR_BERRY  _("WILBIR")
#define NAME_LEPPA_BERRY   _("JONAGO")
#define NAME_ORAN_BERRY    _("SINEL")
#define NAME_PERSIM_BERRY  _("PERSIM")
#define NAME_LUM_BERRY     _("PRUNUS")
#define NAME_SITRUS_BERRY  _("TSITRU")
#define NAME_FIGY_BERRY    _("GIEFE")
#define NAME_WIKI_BERRY    _("WIKI")
#define NAME_MAGO_BERRY    _("MAGO")
#define NAME_AGUAV_BERRY   _("GAUVE")
#define NAME_IAPAPA_BERRY  _("YAPA")
#define NAME_RAZZ_BERRY    _("HIMMIH")
#define NAME_BLUK_BERRY    _("MORB")
#define NAME_NANAB_BERRY   _("NANAB")
#define NAME_WEPEAR_BERRY  _("NIRBE")
#define NAME_PINAP_BERRY   _("SANANA")
#define NAME_POMEG_BERRY   _("GRANA")
#define NAME_KELPSY_BERRY  _("SETANG")
#define NAME_QUALOT_BERRY  _("QUALOT")
#define NAME_HONDEW_BERRY  _("HONMEL")
#define NAME_GREPA_BERRY   _("LABRUS")
#define NAME_TAMATO_BERRY  _("TAMOT")
#define NAME_CORNN_BERRY   _("SAIM")
#define NAME_MAGOST_BERRY  _("MAGOST")
#define NAME_RABUTA_BERRY  _("RABUTA")
#define NAME_NOMEL_BERRY   _("TRONZI")
#define NAME_SPELON_BERRY  _("KIWAN")
#define NAME_PAMTRE_BERRY  _("PALLM")
#define NAME_WATMEL_BERRY  _("WASMEL")
#define NAME_DURIN_BERRY   _("DURIN")
#define NAME_BELUE_BERRY   _("MYRTIL")
#define NAME_LIECHI_BERRY  _("LYDZI")
#define NAME_GANLON_BERRY  _("LINGAN")
#define NAME_SALAC_BERRY   _("SALKA")
#define NAME_PETAYA_BERRY  _("TAHAY")
#define NAME_APICOT_BERRY  _("APIKO")
#define NAME_LANSAT_BERRY  _("LANSAT")
#define NAME_STARF_BERRY   _("KRAMBO")
#define NAME_ENIGMA_BERRY  _("ENIGMA")

static const u8 sBerryDescriptionPart1_Cheri[] = _("Erblüht mit hübschen, zarten Blumen.");
static const u8 sBerryDescriptionPart2_Cheri[] = _("Diese knallrote BEERE ist sehr scharf.");
static const u8 sBerryDescriptionPart1_Chesto[] = _("Diese BEERE hat eine dicke Haut und");
static const u8 sBerryDescriptionPart2_Chesto[] = _("hartes Fruchtfleisch. Trocken!");
static const u8 sBerryDescriptionPart1_Pecha[] = _("Sehr süß und delikat.");
static const u8 sBerryDescriptionPart2_Pecha[] = _("Sehr zart. Vorsichtig anfassen!");
static const u8 sBerryDescriptionPart1_Rawst[] = _("Wenn die Blätter lang und wellig sind,");
static const u8 sBerryDescriptionPart2_Rawst[] = _("wird die BEERE sehr bitter.");
static const u8 sBerryDescriptionPart1_Aspear[] = _("Diese harte BEERE ist sehr");
static const u8 sBerryDescriptionPart2_Aspear[] = _("saftig und sauer im Geschmack!");
static const u8 sBerryDescriptionPart1_Leppa[] = _("Wächst langsamer als AMRENA und");
static const u8 sBerryDescriptionPart2_Leppa[] = _("andere. Je kleiner, desto delikater.");
static const u8 sBerryDescriptionPart1_Oran[] = _("Eine BEERE unterschiedlichsten Ge-");
static const u8 sBerryDescriptionPart2_Oran[] = _("schmacks. Wächst an einem halben Tag.");
static const u8 sBerryDescriptionPart1_Persim[] = _("Liebt Sonnenlicht. Die BEERE");
static const u8 sBerryDescriptionPart2_Persim[] = _("wächst im Sonnenlicht sehr schnell.");
static const u8 sBerryDescriptionPart1_Lum[] = _("Langsamer Wuchs. Wird sie liebevoll ge-");
static const u8 sBerryDescriptionPart2_Lum[] = _("pflegt, kann sie 2 BEEREN tragen.");
static const u8 sBerryDescriptionPart1_Sitrus[] = _("Eng verwandt mit SINEL. Diese große");
static const u8 sBerryDescriptionPart2_Sitrus[] = _("BEERE ist von rundem Geschmack.");
static const u8 sBerryDescriptionPart1_Figy[] = _("Die BEERE sieht angekaut aus. Sie ist");
static const u8 sBerryDescriptionPart2_Figy[] = _("voller scharfer Substanzen.");
static const u8 sBerryDescriptionPart1_Wiki[] = _("Die BEERE wächst unförmig,");
static const u8 sBerryDescriptionPart2_Wiki[] = _("damit PKMN sie besser greifen können.");
static const u8 sBerryDescriptionPart1_Mago[] = _("Die BEERE hat Ausbeulungen. Je mehr");
static const u8 sBerryDescriptionPart2_Mago[] = _("Beulen, desto schmackhafter ist sie.");
static const u8 sBerryDescriptionPart1_Aguav[] = _("Die Blume ist zart. Sie ist fähig,");
static const u8 sBerryDescriptionPart2_Aguav[] = _("ohne Licht wachsen zu können.");
static const u8 sBerryDescriptionPart1_Iapapa[] = _("Die BEERE ist groß und sauer.");
static const u8 sBerryDescriptionPart2_Iapapa[] = _("Sie braucht einen Tag zum Wachsen.");
static const u8 sBerryDescriptionPart1_Razz[] = _("Diese rote BEERE schmeckt etwas");
static const u8 sBerryDescriptionPart2_Razz[] = _("scharf. Sie wächst in nur 4 Stunden.");
static const u8 sBerryDescriptionPart1_Bluk[] = _("Die BEERE ist außen blau, verfärbt");
static const u8 sBerryDescriptionPart2_Bluk[] = _("sich im Mund aber schwarz.");
static const u8 sBerryDescriptionPart1_Nanab[] = _("Diese BEERE war die 7., die auf der");
static const u8 sBerryDescriptionPart2_Nanab[] = _("Welt entdeckt wurde. Sie ist süß.");
static const u8 sBerryDescriptionPart1_Wepear[] = _("Die Blume ist klein und weiß. Angenehm");
static const u8 sBerryDescriptionPart2_Wepear[] = _("bitter und sauer zugleich.");
static const u8 sBerryDescriptionPart1_Pinap[] = _("Wind und Kälte verträgt sie nicht.");
static const u8 sBerryDescriptionPart2_Pinap[] = _("Fruchtfleisch: Scharf. Haut: Sauer.");
static const u8 sBerryDescriptionPart1_Pomeg[] = _("Egal wie viel Wasser sie bekommt, sie");
static const u8 sBerryDescriptionPart2_Pomeg[] = _("trägt immer bis zu 6 BEEREN.");
static const u8 sBerryDescriptionPart1_Kelpsy[] = _("Eine Seltenheit. Geformt wie eine");
static const u8 sBerryDescriptionPart2_Kelpsy[] = _("Wurzel. Hat eine große Blume.");
static const u8 sBerryDescriptionPart1_Qualot[] = _("Liebt das Wasser. Wächst besonders");
static const u8 sBerryDescriptionPart2_Qualot[] = _("gut in regenreichen Gegenden.");
static const u8 sBerryDescriptionPart1_Hondew[] = _("Eine wertvolle und seltene BEERE.");
static const u8 sBerryDescriptionPart2_Hondew[] = _("Sie ist sehr schmackhaft.");
static const u8 sBerryDescriptionPart1_Grepa[] = _("Die BEERE ist zart und von runder");
static const u8 sBerryDescriptionPart2_Grepa[] = _("Form. Aber sie ist unglaublich sauer!");
static const u8 sBerryDescriptionPart1_Tamato[] = _("Die Schärfe der BEERE verbrennt die");
static const u8 sBerryDescriptionPart2_Tamato[] = _("Lippen. Sie braucht Zeit zum Wachsen.");
static const u8 sBerryDescriptionPart1_Cornn[] = _("Eine BEERE aus alten Zeiten. Wächst");
static const u8 sBerryDescriptionPart2_Cornn[] = _("nur, wenn in großen Mengen gepflanzt.");
static const u8 sBerryDescriptionPart1_Magost[] = _("Eine BEERE, die für ihren feinen, aus-");
static const u8 sBerryDescriptionPart2_Magost[] = _("gewogenen Geschmack bekannt ist.");
static const u8 sBerryDescriptionPart1_Rabuta[] = _("Eine Seltenheit, die über und über mit");
static const u8 sBerryDescriptionPart2_Rabuta[] = _("Haaren bewachsen ist. Sehr bitter!");
static const u8 sBerryDescriptionPart1_Nomel[] = _("Sehr sauer. Ein Biss betäubt die");
static const u8 sBerryDescriptionPart2_Nomel[] = _("Geschmacksnerven für 3 Tage!");
static const u8 sBerryDescriptionPart1_Spelon[] = _("Die leuchtend rote BEERE ist sehr");
static const u8 sBerryDescriptionPart2_Spelon[] = _("scharf. Gibt scharfe Substanzen ab!");
static const u8 sBerryDescriptionPart1_Pamtre[] = _("Wird vom Meer angespült. Sie wächst");
static const u8 sBerryDescriptionPart2_Pamtre[] = _("an einem anderen Ort.");
static const u8 sBerryDescriptionPart1_Watmel[] = _("Eine große BEERE, 25 cm groß.");
static const u8 sBerryDescriptionPart2_Watmel[] = _("Außergewöhnlich süß.");
static const u8 sBerryDescriptionPart1_Durin[] = _("Bitter schon ihr Anblick! Sie ist so");
static const u8 sBerryDescriptionPart2_Durin[] = _("bitter, dass niemand sie pur isst.");
static const u8 sBerryDescriptionPart1_Belue[] = _("Sie glänzt, sieht zart aus, ist extrem");
static const u8 sBerryDescriptionPart2_Belue[] = _("sauer und braucht Zeit zum Wachsen.");
static const u8 sBerryDescriptionPart1_Liechi[] = _("Eine geheimnisvolle BEERE. Man sagt,");
static const u8 sBerryDescriptionPart2_Liechi[] = _("sie enthalte die Kraft des Meeres.");
static const u8 sBerryDescriptionPart1_Ganlon[] = _("Eine geheimnisvolle BEERE. Man sagt,");
static const u8 sBerryDescriptionPart2_Ganlon[] = _("sie enthalte die Kraft des Landes.");
static const u8 sBerryDescriptionPart1_Salac[] = _("Eine geheimnisvolle BEERE. Man sagt,");
static const u8 sBerryDescriptionPart2_Salac[] = _("sie enthalte die Kraft des Himmels.");
static const u8 sBerryDescriptionPart1_Petaya[] = _("Eine geheimnisvolle BEERE. Man sagt,");
static const u8 sBerryDescriptionPart2_Petaya[] = _("sie enthalte die Kraft allen Lebens.");
static const u8 sBerryDescriptionPart1_Apicot[] = _("Eine rätselhafte BEERE. Man kann");
static const u8 sBerryDescriptionPart2_Apicot[] = _("nicht sagen, wie und was sie ist.");
static const u8 sBerryDescriptionPart1_Lansat[] = _("Eine legendäre BEERE. Sie zu");
static const u8 sBerryDescriptionPart2_Lansat[] = _("tragen bringt Freude.");
static const u8 sBerryDescriptionPart1_Starf[] = _("So stark, dass sie an den Rand der");
static const u8 sBerryDescriptionPart2_Starf[] = _("Welt verbannt wurde. Ein Märchen?");
static const u8 sBerryDescriptionPart1_Enigma[] = _("Eine enigmatische BEERE. Sie scheint");
static const u8 sBerryDescriptionPart2_Enigma[] = _("die Macht der Sterne zu besitzen.");
#endif

const struct Berry gBerries[] =
{
    {
        .name = NAME_CHERI_BERRY,
        .firmness = BERRY_FIRMNESS_SOFT,
        .size = 20,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Cheri,
        .description2 = sBerryDescriptionPart2_Cheri,
        .stageDuration = 3,
        .spicy = 10,
        .dry = 0,
        .sweet = 0,
        .bitter = 0,
        .sour = 0,
        .smoothness = 25,
    },
    {
        .name = NAME_CHESTO_BERRY,
        .firmness = BERRY_FIRMNESS_SUPER_HARD,
        .size = 80,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Chesto,
        .description2 = sBerryDescriptionPart2_Chesto,
        .stageDuration = 3,
        .spicy = 0,
        .dry = 10,
        .sweet = 0,
        .bitter = 0,
        .sour = 0,
        .smoothness = 25,
    },
    {
        .name = NAME_PECHA_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_SOFT,
        .size = 40,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Pecha,
        .description2 = sBerryDescriptionPart2_Pecha,
        .stageDuration = 3,
        .spicy = 0,
        .dry = 0,
        .sweet = 10,
        .bitter = 0,
        .sour = 0,
        .smoothness = 25,
    },
    {
        .name = NAME_RAWST_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 32,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Rawst,
        .description2 = sBerryDescriptionPart2_Rawst,
        .stageDuration = 3,
        .spicy = 0,
        .dry = 0,
        .sweet = 0,
        .bitter = 10,
        .sour = 0,
        .smoothness = 25,
    },
    {
        .name = NAME_ASPEAR_BERRY,
        .firmness = BERRY_FIRMNESS_SUPER_HARD,
        .size = 50,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Aspear,
        .description2 = sBerryDescriptionPart2_Aspear,
        .stageDuration = 3,
        .spicy = 0,
        .dry = 0,
        .sweet = 0,
        .bitter = 0,
        .sour = 10,
        .smoothness = 25,
    },
    {
        .name = NAME_LEPPA_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_HARD,
        .size = 28,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Leppa,
        .description2 = sBerryDescriptionPart2_Leppa,
        .stageDuration = 4,
        .spicy = 10,
        .dry = 0,
        .sweet = 10,
        .bitter = 10,
        .sour = 10,
        .smoothness = 20,
    },
    {
        .name = NAME_ORAN_BERRY,
        .firmness = BERRY_FIRMNESS_SUPER_HARD,
        .size = 35,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Oran,
        .description2 = sBerryDescriptionPart2_Oran,
        .stageDuration = 3,
        .spicy = 10,
        .dry = 10,
        .sweet = 10,
        .bitter = 10,
        .sour = 10,
        .smoothness = 20,
    },
    {
        .name = NAME_PERSIM_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 47,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Persim,
        .description2 = sBerryDescriptionPart2_Persim,
        .stageDuration = 3,
        .spicy = 10,
        .dry = 10,
        .sweet = 10,
        .bitter = 10,
        .sour = 10,
        .smoothness = 20,
    },
    {
        .name = NAME_LUM_BERRY,
        .firmness = BERRY_FIRMNESS_SUPER_HARD,
        .size = 34,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Lum,
        .description2 = sBerryDescriptionPart2_Lum,
        .stageDuration = 12,
        .spicy = 10,
        .dry = 10,
        .sweet = 10,
        .bitter = 10,
        .sour = 10,
        .smoothness = 20,
    },
    {
        .name = NAME_SITRUS_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_HARD,
        .size = 95,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Sitrus,
        .description2 = sBerryDescriptionPart2_Sitrus,
        .stageDuration = 6,
        .spicy = 10,
        .dry = 10,
        .sweet = 10,
        .bitter = 10,
        .sour = 10,
        .smoothness = 20,
    },
    {
        .name = NAME_FIGY_BERRY,
        .firmness = BERRY_FIRMNESS_SOFT,
        .size = 100,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Figy,
        .description2 = sBerryDescriptionPart2_Figy,
        .stageDuration = 6,
        .spicy = 10,
        .dry = 0,
        .sweet = 0,
        .bitter = 0,
        .sour = 0,
        .smoothness = 25,
    },
    {
        .name = NAME_WIKI_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 115,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Wiki,
        .description2 = sBerryDescriptionPart2_Wiki,
        .stageDuration = 6,
        .spicy = 0,
        .dry = 10,
        .sweet = 0,
        .bitter = 0,
        .sour = 0,
        .smoothness = 25,
    },
    {
        .name = NAME_MAGO_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 126,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Mago,
        .description2 = sBerryDescriptionPart2_Mago,
        .stageDuration = 6,
        .spicy = 0,
        .dry = 0,
        .sweet = 10,
        .bitter = 0,
        .sour = 0,
        .smoothness = 25,
    },
    {
        .name = NAME_AGUAV_BERRY,
        .firmness = BERRY_FIRMNESS_SUPER_HARD,
        .size = 64,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Aguav,
        .description2 = sBerryDescriptionPart2_Aguav,
        .stageDuration = 6,
        .spicy = 0,
        .dry = 0,
        .sweet = 0,
        .bitter = 10,
        .sour = 0,
        .smoothness = 25,
    },
    {
        .name = NAME_IAPAPA_BERRY,
        .firmness = BERRY_FIRMNESS_SOFT,
        .size = 223,
        .maxYield = 3,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Iapapa,
        .description2 = sBerryDescriptionPart2_Iapapa,
        .stageDuration = 6,
        .spicy = 0,
        .dry = 0,
        .sweet = 0,
        .bitter = 0,
        .sour = 10,
        .smoothness = 25,
    },
    {
        .name = NAME_RAZZ_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_HARD,
        .size = 120,
        .maxYield = 6,
        .minYield = 3,
        .description1 = sBerryDescriptionPart1_Razz,
        .description2 = sBerryDescriptionPart2_Razz,
        .stageDuration = 1,
        .spicy = 10,
        .dry = 10,
        .sweet = 0,
        .bitter = 0,
        .sour = 0,
        .smoothness = 20,
    },
    {
        .name = NAME_BLUK_BERRY,
        .firmness = BERRY_FIRMNESS_SOFT,
        .size = 108,
        .maxYield = 6,
        .minYield = 3,
        .description1 = sBerryDescriptionPart1_Bluk,
        .description2 = sBerryDescriptionPart2_Bluk,
        .stageDuration = 1,
        .spicy = 0,
        .dry = 10,
        .sweet = 10,
        .bitter = 0,
        .sour = 0,
        .smoothness = 20,
    },
    {
        .name = NAME_NANAB_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_HARD,
        .size = 77,
        .maxYield = 6,
        .minYield = 3,
        .description1 = sBerryDescriptionPart1_Nanab,
        .description2 = sBerryDescriptionPart2_Nanab,
        .stageDuration = 1,
        .spicy = 0,
        .dry = 0,
        .sweet = 10,
        .bitter = 10,
        .sour = 0,
        .smoothness = 20,
    },
    {
        .name = NAME_WEPEAR_BERRY,
        .firmness = BERRY_FIRMNESS_SUPER_HARD,
        .size = 74,
        .maxYield = 6,
        .minYield = 3,
        .description1 = sBerryDescriptionPart1_Wepear,
        .description2 = sBerryDescriptionPart2_Wepear,
        .stageDuration = 1,
        .spicy = 0,
        .dry = 0,
        .sweet = 0,
        .bitter = 10,
        .sour = 10,
        .smoothness = 20,
    },
    {
        .name = NAME_PINAP_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 80,
        .maxYield = 6,
        .minYield = 3,
        .description1 = sBerryDescriptionPart1_Pinap,
        .description2 = sBerryDescriptionPart2_Pinap,
        .stageDuration = 1,
        .spicy = 10,
        .dry = 0,
        .sweet = 0,
        .bitter = 0,
        .sour = 10,
        .smoothness = 20,
    },
    {
        .name = NAME_POMEG_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_HARD,
        .size = 135,
        .maxYield = 6,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Pomeg,
        .description2 = sBerryDescriptionPart2_Pomeg,
        .stageDuration = 3,
        .spicy = 10,
        .dry = 0,
        .sweet = 10,
        .bitter = 10,
        .sour = 0,
        .smoothness = 20,
    },
    {
        .name = NAME_KELPSY_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 150,
        .maxYield = 6,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Kelpsy,
        .description2 = sBerryDescriptionPart2_Kelpsy,
        .stageDuration = 3,
        .spicy = 0,
        .dry = 10,
        .sweet = 0,
        .bitter = 10,
        .sour = 10,
        .smoothness = 20,
    },
    {
        .name = NAME_QUALOT_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 110,
        .maxYield = 6,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Qualot,
        .description2 = sBerryDescriptionPart2_Qualot,
        .stageDuration = 3,
        .spicy = 10,
        .dry = 0,
        .sweet = 10,
        .bitter = 0,
        .sour = 10,
        .smoothness = 20,
    },
    {
        .name = NAME_HONDEW_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 162,
        .maxYield = 6,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Hondew,
        .description2 = sBerryDescriptionPart2_Hondew,
        .stageDuration = 3,
        .spicy = 10,
        .dry = 10,
        .sweet = 0,
        .bitter = 10,
        .sour = 0,
        .smoothness = 20,
    },
    {
        .name = NAME_GREPA_BERRY,
        .firmness = BERRY_FIRMNESS_SOFT,
        .size = 149,
        .maxYield = 6,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Grepa,
        .description2 = sBerryDescriptionPart2_Grepa,
        .stageDuration = 3,
        .spicy = 0,
        .dry = 10,
        .sweet = 10,
        .bitter = 0,
        .sour = 10,
        .smoothness = 20,
    },
    {
        .name = NAME_TAMATO_BERRY,
        .firmness = BERRY_FIRMNESS_SOFT,
        .size = 200,
        .maxYield = 4,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Tamato,
        .description2 = sBerryDescriptionPart2_Tamato,
        .stageDuration = 6,
        .spicy = 20,
        .dry = 10,
        .sweet = 0,
        .bitter = 0,
        .sour = 0,
        .smoothness = 30,
    },
    {
        .name = NAME_CORNN_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 75,
        .maxYield = 4,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Cornn,
        .description2 = sBerryDescriptionPart2_Cornn,
        .stageDuration = 6,
        .spicy = 0,
        .dry = 20,
        .sweet = 10,
        .bitter = 0,
        .sour = 0,
        .smoothness = 30,
    },
    {
        .name = NAME_MAGOST_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 140,
        .maxYield = 4,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Magost,
        .description2 = sBerryDescriptionPart2_Magost,
        .stageDuration = 6,
        .spicy = 0,
        .dry = 0,
        .sweet = 20,
        .bitter = 10,
        .sour = 0,
        .smoothness = 30,
    },
    {
        .name = NAME_RABUTA_BERRY,
        .firmness = BERRY_FIRMNESS_SOFT,
        .size = 226,
        .maxYield = 4,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Rabuta,
        .description2 = sBerryDescriptionPart2_Rabuta,
        .stageDuration = 6,
        .spicy = 0,
        .dry = 0,
        .sweet = 0,
        .bitter = 20,
        .sour = 10,
        .smoothness = 30,
    },
    {
        .name = NAME_NOMEL_BERRY,
        .firmness = BERRY_FIRMNESS_SUPER_HARD,
        .size = 285,
        .maxYield = 4,
        .minYield = 2,
        .description1 = sBerryDescriptionPart1_Nomel,
        .description2 = sBerryDescriptionPart2_Nomel,
        .stageDuration = 6,
        .spicy = 10,
        .dry = 0,
        .sweet = 0,
        .bitter = 0,
        .sour = 20,
        .smoothness = 30,
    },
    {
        .name = NAME_SPELON_BERRY,
        .firmness = BERRY_FIRMNESS_SOFT,
        .size = 133,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Spelon,
        .description2 = sBerryDescriptionPart2_Spelon,
        .stageDuration = 18,
        .spicy = 40,
        .dry = 10,
        .sweet = 0,
        .bitter = 0,
        .sour = 0,
        .smoothness = 70,
    },
    {
        .name = NAME_PAMTRE_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_SOFT,
        .size = 244,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Pamtre,
        .description2 = sBerryDescriptionPart2_Pamtre,
        .stageDuration = 18,
        .spicy = 0,
        .dry = 40,
        .sweet = 10,
        .bitter = 0,
        .sour = 0,
        .smoothness = 70,
    },
    {
        .name = NAME_WATMEL_BERRY,
        .firmness = BERRY_FIRMNESS_SOFT,
        .size = 250,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Watmel,
        .description2 = sBerryDescriptionPart2_Watmel,
        .stageDuration = 18,
        .spicy = 0,
        .dry = 0,
        .sweet = 40,
        .bitter = 10,
        .sour = 0,
        .smoothness = 70,
    },
    {
        .name = NAME_DURIN_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 280,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Durin,
        .description2 = sBerryDescriptionPart2_Durin,
        .stageDuration = 18,
        .spicy = 0,
        .dry = 0,
        .sweet = 0,
        .bitter = 40,
        .sour = 10,
        .smoothness = 70,
    },
    {
        .name = NAME_BELUE_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_SOFT,
        .size = 300,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Belue,
        .description2 = sBerryDescriptionPart2_Belue,
        .stageDuration = 18,
        .spicy = 10,
        .dry = 0,
        .sweet = 0,
        .bitter = 0,
        .sour = 40,
        .smoothness = 70,
    },
    {
        .name = NAME_LIECHI_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_HARD,
        .size = 111,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Liechi,
        .description2 = sBerryDescriptionPart2_Liechi,
        .stageDuration = 24,
        .spicy = 40,
        .dry = 0,
        .sweet = 40,
        .bitter = 0,
        .sour = 10,
        .smoothness = 80,
    },
    {
        .name = NAME_GANLON_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_HARD,
        .size = 33,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Ganlon,
        .description2 = sBerryDescriptionPart2_Ganlon,
        .stageDuration = 24,
        .spicy = 0,
        .dry = 40,
        .sweet = 0,
        .bitter = 40,
        .sour = 0,
        .smoothness = 80,
    },
    {
        .name = NAME_SALAC_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_HARD,
        .size = 95,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Salac,
        .description2 = sBerryDescriptionPart2_Salac,
        .stageDuration = 24,
        .spicy = 0,
        .dry = 0,
        .sweet = 40,
        .bitter = 0,
        .sour = 40,
        .smoothness = 80,
    },
    {
        .name = NAME_PETAYA_BERRY,
        .firmness = BERRY_FIRMNESS_VERY_HARD,
        .size = 237,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Petaya,
        .description2 = sBerryDescriptionPart2_Petaya,
        .stageDuration = 24,
        .spicy = 40,
        .dry = 0,
        .sweet = 0,
        .bitter = 40,
        .sour = 0,
        .smoothness = 80,
    },
    {
        .name = NAME_APICOT_BERRY,
        .firmness = BERRY_FIRMNESS_HARD,
        .size = 75,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Apicot,
        .description2 = sBerryDescriptionPart2_Apicot,
        .stageDuration = 24,
        .spicy = 0,
        .dry = 40,
        .sweet = 0,
        .bitter = 0,
        .sour = 40,
        .smoothness = 80,
    },
    {
        .name = NAME_LANSAT_BERRY,
        .firmness = BERRY_FIRMNESS_SOFT,
        .size = 97,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Lansat,
        .description2 = sBerryDescriptionPart2_Lansat,
        .stageDuration = 24,
        .spicy = 10,
        .dry = 10,
        .sweet = 10,
        .bitter = 10,
        .sour = 10,
        .smoothness = 30,
    },
    {
        .name = NAME_STARF_BERRY,
        .firmness = BERRY_FIRMNESS_SUPER_HARD,
        .size = 153,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Starf,
        .description2 = sBerryDescriptionPart2_Starf,
        .stageDuration = 24,
        .spicy = 10,
        .dry = 10,
        .sweet = 10,
        .bitter = 10,
        .sour = 10,
        .smoothness = 30,
    },
    {
        .name = NAME_ENIGMA_BERRY,
        .firmness = BERRY_FIRMNESS_UNKNOWN,
        .size = 0,
        .maxYield = 2,
        .minYield = 1,
        .description1 = sBerryDescriptionPart1_Enigma,
        .description2 = sBerryDescriptionPart2_Enigma,
        .stageDuration = 24,
        .spicy = 40,
        .dry = 40,
        .sweet = 40,
        .bitter = 40,
        .sour = 40,
        .smoothness = 40,
    },
};

static const struct BerryTree gBlankBerryTree = {0};

extern u8 S_BerryTree[];
extern u16 gSpecialVar_LastTalked;
extern u16 gSpecialVar_0x8004;
extern u16 gSpecialVar_0x8005;
extern u16 gSpecialVar_0x8006;

/*
    An enigma berry is a type of berry which functions
    as though it is a custom berry. Because it behaves
    like its a custom berry, it doesn't hold an identity
    represented in its icons or descriptions, leaving its
    information to be decided by the e-reader cards
    which were intended to deliver these custom
    berries.
*/

static u8 CalcBerryYield(struct BerryTree *tree);
static u16 GetStageDurationByBerryType(u8 berry);

#if DEBUG

extern u8 sub_80B47D8(u16 var);

u8 debug_sub_80C2B04(void)
{
    u8 taskId = sub_80B47D8(0);

    gTasks[taskId].data[4]--;
    CloseMenu();
    return 1;
}

u8 debug_sub_80C2B30(void)
{
    u8 taskId = sub_80B47D8(1);

    gTasks[taskId].data[4]--;
    CloseMenu();
    return 1;
}

#endif

// unused
// this could be static, but making it so causes a compile-time warning.
void ClearEnigmaBerries(void)
{
    CpuFill16(0, &gSaveBlock1.enigmaBerry, sizeof(gSaveBlock1.enigmaBerry));
}

void SetEnigmaBerry(u8 *src)
{
    // initialize the enigma berry by copying the data from the script.
    u32 i;
    u8 *dest = (u8*)&gSaveBlock1.enigmaBerry;

    for (i = 0; i < sizeof(gSaveBlock1.enigmaBerry); i++)
        dest[i] = src[i];

    // at this point, the description pointer is not yet initialized. we need to initialize it since
    // we dont know where in memory this is going to be. set the berry desc pointers to the
    // EnigmaBerry struct's description arrays since these are where the descriptions are stored.
    gSaveBlock1.enigmaBerry.berry.description1 = gSaveBlock1.enigmaBerry.description1;
    gSaveBlock1.enigmaBerry.berry.description2 = gSaveBlock1.enigmaBerry.description2;
}

static u32 GetEnigmaBerryChecksum(struct EnigmaBerry *enigmaBerry)
{
    const u8 *description1;
    const u8 *description2;
    u32 i;
    u32 checksum;
    u8 *dest;

    // the description pointers could be pointing to anywhere in memory. we do not want these
    // pointers to factor into the checksum as it will produce a different result every time: so
    // back the pointers up and set them to null so the checksum is safe to calculate.
    description1 = gSaveBlock1.enigmaBerry.berry.description1;
    description2 = gSaveBlock1.enigmaBerry.berry.description2;
    gSaveBlock1.enigmaBerry.berry.description1 = NULL;
    gSaveBlock1.enigmaBerry.berry.description2 = NULL;

    dest = (u8*)enigmaBerry;
    checksum = 0;
    for (i = 0; i < ((u32)&gSaveBlock1.enigmaBerry.checksum - (u32)&gSaveBlock1.enigmaBerry); i++)
        checksum += dest[i];

    // the checksum is calculated: the descriptions are safe to restore now.
    gSaveBlock1.enigmaBerry.berry.description1 = description1;
    gSaveBlock1.enigmaBerry.berry.description2 = description2;

    return checksum;
}

#if DEBUG

extern const u8 gSpriteImage_UnusedCherry[];
extern const u16 gSpritePalette_UnusedCherry[];
extern u8 gUnknown_Debug_839B6CE[];

static const u8 gUnknown_Debug_083F7F84[] = DTR("そとから　きた　きのみ", "An exterior BERRY");
static const u8 gUnknown_Debug_083F7F90[] = DTR("ただいま　かいはつちゅう", "Currently under development");

void debug_sub_80C2C18(const u8 *name, u8 holdEffect, u8 holdEffectParam)
{
    s32 i;

    gSaveBlock1.enigmaBerry.berry = gBerries[0];
    StringCopy(gSaveBlock1.enigmaBerry.berry.name, name);
    StringCopy(gSaveBlock1.enigmaBerry.description1, gUnknown_Debug_083F7F84);
    StringCopy(gSaveBlock1.enigmaBerry.description2, gUnknown_Debug_083F7F90);
    gSaveBlock1.enigmaBerry.berry.description1 = gSaveBlock1.enigmaBerry.description1;
    gSaveBlock1.enigmaBerry.berry.description2 = gSaveBlock1.enigmaBerry.description2;
    for (i = 0; i < 0x480; i++)
        gSaveBlock1.enigmaBerry.pic[i] = gSpriteImage_UnusedCherry[i];
    for (i = 0; i < 16; i++)
        gSaveBlock1.enigmaBerry.palette[i] = gSpritePalette_UnusedCherry[i];
    for (i = 0; i < 18; i++)
        gSaveBlock1.enigmaBerry.itemEffect[i] = gUnknown_Debug_839B6CE[i];
    gSaveBlock1.enigmaBerry.holdEffect = holdEffect;
    gSaveBlock1.enigmaBerry.holdEffectParam = holdEffectParam;
    gSaveBlock1.enigmaBerry.checksum = GetEnigmaBerryChecksum(&gSaveBlock1.enigmaBerry);
}

void debug_sub_80C2D24(u8 spicy, u8 dry, u8 sweet, u8 bitter, u8 sour, u8 smoothness)
{
    gSaveBlock1.enigmaBerry.berry.spicy = spicy;
    gSaveBlock1.enigmaBerry.berry.dry = dry;
    gSaveBlock1.enigmaBerry.berry.sweet = sweet;
    gSaveBlock1.enigmaBerry.berry.bitter = bitter;
    gSaveBlock1.enigmaBerry.berry.sour = sour;
    gSaveBlock1.enigmaBerry.berry.smoothness = smoothness;
    gSaveBlock1.enigmaBerry.checksum = GetEnigmaBerryChecksum(&gSaveBlock1.enigmaBerry);
}

#endif

// due to e-reader scans being particularly volatile to failure, it is a requirement to check for
// their integrity here due to scans possibly failing to produce the correct result.
bool32 IsEnigmaBerryValid(void)
{
    if (gSaveBlock1.enigmaBerry.berry.stageDuration == 0)
        return FALSE;
    if (gSaveBlock1.enigmaBerry.berry.maxYield == 0)
        return FALSE;
    if (GetEnigmaBerryChecksum(&gSaveBlock1.enigmaBerry) != gSaveBlock1.enigmaBerry.checksum)
        return FALSE;
    return TRUE;
}

const struct Berry *GetBerryInfo(u8 berry)
{
    // when getting the pointer to the berry info, enigma berries are handled differently. if your
    // berry is an Enigma Berry and its checksum is valid, fetch the pointer to its information in
    // the save block.
    if (berry == ITEM_TO_BERRY(ITEM_ENIGMA_BERRY) && IsEnigmaBerryValid())
        return &gSaveBlock1.enigmaBerry.berry;
    else
    {
        // invalid berries will be flattened into a cheri berry. Interestingly, if your berry was
        // an enigma berry whos checksum failed, the game will use the Enigma Berry information
        // for this: meaning if you see the Enigma Berry information, its actually because the
        // checksum failed.
        if (berry == BERRY_NONE || berry > ITEM_TO_BERRY(LAST_BERRY_INDEX))
            berry = ITEM_TO_BERRY(FIRST_BERRY_INDEX);
        return &gBerries[berry - 1];
    }
}

// the save file can handle up to a number of 128 berry trees as indicated by its definition
// in global.h. Interestingly, this function does not check that limit of 128.
static struct BerryTree *GetBerryTreeInfo(u8 id)
{
    return &gSaveBlock1.berryTrees[id];
}

// this was called because the berry script was successful: meaning the player chose to
// water the tree. We need to check for the current tree stage and set the appropriate
// water flag to true.
bool32 ObjectEventInteractionWaterBerryTree(void)
{
    // GetBerryTreeInfo does not sanitize the tree retrieved, but there are no known
    // instances where this can cause problems.
    struct BerryTree *tree = GetBerryTreeInfo(ObjectEventGetBerryTreeId(gSelectedObjectEvent));

    switch (tree->stage)
    {
    case BERRY_STAGE_PLANTED:
        tree->watered1 = TRUE;
        break;
    case BERRY_STAGE_SPROUTED:
        tree->watered2 = TRUE;
        break;
    case BERRY_STAGE_TALLER:
        tree->watered3 = TRUE;
        break;
    case BERRY_STAGE_FLOWERING:
        tree->watered4 = TRUE;
        break;
    default:
        return FALSE;
    }
    return TRUE;
}

bool8 IsPlayerFacingUnplantedSoil(void)
{
    if (GetObjectEventScriptPointerPlayerFacing() == S_BerryTree
     && GetStageByBerryTreeId(ObjectEventGetBerryTreeId(gSelectedObjectEvent)) == BERRY_STAGE_NO_BERRY)
        return TRUE;
    else
        return FALSE;
}

bool8 TryToWaterBerryTree(void)
{
    if (GetObjectEventScriptPointerPlayerFacing() != S_BerryTree)
        return FALSE;
    else
        return ObjectEventInteractionWaterBerryTree();
}

void ClearBerryTrees(void)
{
    int i;
    struct SaveBlock1 *saveBlock1 = &gSaveBlock1;
    struct BerryTree berryTree = gBlankBerryTree;

    for (i = 0; i < MAX_BERRY_TREES; i++)
        saveBlock1->berryTrees[i] = berryTree;
}

// when the player does not interact with the tree for a period of time, this is called
// to advance the grow state.
static bool32 BerryTreeGrow(struct BerryTree *tree)
{
    if (tree->growthSparkle)
        return FALSE;
    switch (tree->stage)
    {
    case BERRY_STAGE_NO_BERRY:
        return FALSE;
    case BERRY_STAGE_FLOWERING:
        tree->berryYield = CalcBerryYield(tree);
    case BERRY_STAGE_PLANTED:
    case BERRY_STAGE_SPROUTED:
    case BERRY_STAGE_TALLER:
        tree->stage++;
        break;
    case BERRY_STAGE_BERRIES:
        tree->watered1 = 0;
        tree->watered2 = 0;
        tree->watered3 = 0;
        tree->watered4 = 0;
        tree->berryYield = 0;
        tree->stage = BERRY_STAGE_SPROUTED;
        if (++tree->regrowthCount == BERRY_REGROW_LIMIT)
            *tree = gBlankBerryTree;
        break;
    }
    return TRUE;
}

void BerryTreeTimeUpdate(s32 minutesPassed)
{
    int i;
    struct BerryTree *tree;

    for (i = 0; i < MAX_BERRY_TREES; i++)
    {
        tree = &gSaveBlock1.berryTrees[i];

        if (tree->berry != BERRY_NONE && tree->stage != BERRY_STAGE_NO_BERRY && tree->growthSparkle == FALSE)
        {
            // the player has waited too long to water the berry. Reset the tree. This is because
            // if the berry state is not in the unwatered state, the tree will grow anyway despite this
            // check, which means BerryTreeGrow will handle the regrow process for this, removing the
            // need for this check. This only handles the unwatered soil state.
            if (minutesPassed >= GetStageDurationByBerryType(tree->berry) * 71)
            {
                *tree = gBlankBerryTree;
            }
            else
            {
                // because time is altered below, perhaps they thought it was unsafe to change it, even
                // though that is not how passed arguments behave.
                s32 time = minutesPassed;

                while (time != 0)
                {
                    if (tree->minutesUntilNextStage > time)
                    {
                        // its been X minutes since the last berry update, so update
                        // minutesUntilNextStage appropriately to match the time offset
                        // that has passed since the update.
                        tree->minutesUntilNextStage -= time;
                        break;
                    }
                    // perform the subtraction the other way around to get the number of minutes since
                    // the inferred stage update that occured, since minutesUntilNextStage is <= time.
                    // we may need this variable to simulate multiple berry cycles in the while loop.
                    time -= tree->minutesUntilNextStage;
                    tree->minutesUntilNextStage = GetStageDurationByBerryType(tree->berry); // since the tree was inferred to update, set the new minutesUntilNextStage.
                    if (BerryTreeGrow(tree) == FALSE)
                        break;
                    if (tree->stage == BERRY_STAGE_BERRIES)
                        tree->minutesUntilNextStage *= 4;
                }
            }
        }
    }
}

void PlantBerryTree(u8 id, u8 berry, u8 stage, bool8 sparkle)
{
    struct BerryTree *tree = GetBerryTreeInfo(id);

    *tree = gBlankBerryTree;
    tree->berry = berry;
    tree->minutesUntilNextStage = GetStageDurationByBerryType(berry);
    tree->stage = stage;
    if (stage == BERRY_STAGE_BERRIES)
    {
        tree->berryYield = CalcBerryYield(tree);
        tree->minutesUntilNextStage *= 4;
    }
    if (!sparkle)
    {
        tree->growthSparkle = TRUE;
    }
}

void RemoveBerryTree(u8 id)
{
    gSaveBlock1.berryTrees[id] = gBlankBerryTree;
}

u8 GetBerryTypeByBerryTreeId(u8 id)
{
    return gSaveBlock1.berryTrees[id].berry;
}

u8 GetStageByBerryTreeId(u8 id)
{
    return gSaveBlock1.berryTrees[id].stage;
}

u8 ItemIdToBerryType(u16 item)
{
    u16 berry = item - FIRST_BERRY_INDEX;

    if (berry > LAST_BERRY_INDEX - FIRST_BERRY_INDEX)
        return ITEM_TO_BERRY(FIRST_BERRY_INDEX);
    else
        return ITEM_TO_BERRY(item);
}

static u16 BerryTypeToItemId(u16 berry)
{
    u16 item = berry - 1;

    if (item > LAST_BERRY_INDEX - FIRST_BERRY_INDEX)
        return FIRST_BERRY_INDEX;
    else
        return berry + FIRST_BERRY_INDEX - 1;
}

void GetBerryNameByBerryType(u8 berry, u8 *string)
{
    memcpy(string, GetBerryInfo(berry)->name, BERRY_NAME_LENGTH);
    string[BERRY_NAME_LENGTH] = EOS;
}

void ResetBerryTreeSparkleFlag(u8 id)
{
    GetBerryTreeInfo(id)->growthSparkle = FALSE;
}

static u8 BerryTreeGetNumStagesWatered(struct BerryTree *tree)
{
    u8 count = 0;

    if (tree->watered1)
        count++;
    if (tree->watered2)
        count++;
    if (tree->watered3)
        count++;
    if (tree->watered4)
        count++;
    return count;
}

static u8 GetNumStagesWateredByBerryTreeId(u8 id)
{
    return BerryTreeGetNumStagesWatered(GetBerryTreeInfo(id));
}

static u8 CalcBerryYieldInternal(u16 max, u16 min, u8 water)
{
    u32 randMin;
    u32 randMax;
    u32 rand;
    u32 extraYield;

    // depending on if the player gave the tree plenty of water, berry yield will be affected proportionally.

    if (water == 0)
        return min;
    else
    {
        randMin = (max - min) * (water - 1);
        randMax = (max - min) * (water);
        rand = randMin + Random() % (randMax - randMin + 1);

        if ((rand % 4) > 1)
            extraYield = rand / 4 + 1;
        else
            extraYield = rand / 4;
        return extraYield + min;
    }
}

static u8 CalcBerryYield(struct BerryTree *tree)
{
    const struct Berry *berry = GetBerryInfo(tree->berry);
    u8 min = berry->minYield;
    u8 max = berry->maxYield;

    return CalcBerryYieldInternal(max, min, BerryTreeGetNumStagesWatered(tree));
}

static u8 GetBerryCountByBerryTreeId(u8 id)
{
    return gSaveBlock1.berryTrees[id].berryYield;
}

static u16 GetStageDurationByBerryType(u8 berry)
{
    return GetBerryInfo(berry)->stageDuration * 60;
}

void ObjectEventInteractionGetBerryTreeData(void)
{
    u8 id;
    u8 berry;
    u8 localId;
    u8 group;
    u8 num;

    id = ObjectEventGetBerryTreeId(gSelectedObjectEvent);
    berry = GetBerryTypeByBerryTreeId(id);
    ResetBerryTreeSparkleFlag(id);
    localId = gSpecialVar_LastTalked;
    num = gSaveBlock1.location.mapNum;
    group = gSaveBlock1.location.mapGroup;
    if (IsBerryTreeSparkling(localId, num, group))
    {
        // we cannot allow the player to grow/interact with the tree while the tree
        // is undergoing the sparkling effect, so set the special var to the sparkling
        // state and let the event script process the flag.
        gSpecialVar_0x8004 = BERRY_STAGE_SPARKLING;
    }
    else
        gSpecialVar_0x8004 = GetStageByBerryTreeId(id);
    gSpecialVar_0x8005 = GetNumStagesWateredByBerryTreeId(id);
    gSpecialVar_0x8006 = GetBerryCountByBerryTreeId(id);
    GetBerryNameByBerryType(berry, gStringVar1);
}

void Berry_FadeAndGoToBerryBagMenu(void)
{
    SetMainCallback2(CB2_ChooseBerry);
}

void ObjectEventInteractionPlantBerryTree(void)
{
    u8 berry = ItemIdToBerryType(gSpecialVar_ItemId);

    PlantBerryTree(ObjectEventGetBerryTreeId(gSelectedObjectEvent), berry, 1, TRUE);
    ObjectEventInteractionGetBerryTreeData();
}

void ObjectEventInteractionPickBerryTree(void)
{
    u8 id = ObjectEventGetBerryTreeId(gSelectedObjectEvent);
    u8 berry = GetBerryTypeByBerryTreeId(id);

    gSpecialVar_0x8004 = AddBagItem(BerryTypeToItemId(berry), GetBerryCountByBerryTreeId(id));
}

void ObjectEventInteractionRemoveBerryTree(void)
{
    RemoveBerryTree(ObjectEventGetBerryTreeId(gSelectedObjectEvent));
    sub_8060288(gSpecialVar_LastTalked, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
}

bool8 PlayerHasBerries(void)
{
    return IsBagPocketNonEmpty(BAG_BERRIES);
}

#if DEBUG
void debug_sub_80C33FC(const u8 *buffer, s32 value, u8 n)
{
    StringAppend(gStringVar4, buffer);
    ConvertIntToDecimalStringN(gStringVar1, value, STR_CONV_MODE_LEADING_ZEROS, n);
    StringAppend(gStringVar4, gStringVar1);
}

static const u8 gUnknown_Debug_083F7F9D[] = _("POS:");
static const u8 gUnknown_Debug_083F7FA2[] = _("\nTYPE:");
static const u8 gUnknown_Debug_083F7FA9[] = _("\nGROW:");
static const u8 gUnknown_Debug_083F7FB0[] = _("\nTIME:");
static const u8 gUnknown_Debug_083F7FB7[] = _("\nFCNT:");
static const u8 gUnknown_Debug_083F7FBE[] = _("\nSCNT:");
static const u8 gUnknown_Debug_083F7FC5[] = _("\nHOOK:");
static const u8 gUnknown_Debug_083F7FCC[] = _("\nWBIT:");
static const u8 gUnknown_Debug_083F7FD3[] = _("");

u8* DebugOpenBerryInfo(void)
{
    if (GetObjectEventScriptPointerPlayerFacing() != S_BerryTree)
    {
        return NULL;
    }
    else
    {
        u32 berryTreeId = ObjectEventGetBerryTreeId(gSelectedObjectEvent);
        struct BerryTree *berryTree = GetBerryTreeInfo(berryTreeId);
        s32 i;

        for (i = 0; i < 500; i++)
            gStringVar4[i] = EOS;

        debug_sub_80C33FC(gUnknown_Debug_083F7F9D, berryTreeId, 3);
        debug_sub_80C33FC(gUnknown_Debug_083F7FA2, berryTree->berry, 2);
        debug_sub_80C33FC(gUnknown_Debug_083F7FA9, berryTree->stage, 2);
        debug_sub_80C33FC(gUnknown_Debug_083F7FB0, berryTree->minutesUntilNextStage, 5);
        debug_sub_80C33FC(gUnknown_Debug_083F7FB7, berryTree->berryYield, 2);
        debug_sub_80C33FC(gUnknown_Debug_083F7FBE, berryTree->regrowthCount, 3);
        debug_sub_80C33FC(gUnknown_Debug_083F7FC5, berryTree->growthSparkle, 1);
        debug_sub_80C33FC(gUnknown_Debug_083F7FCC, berryTree->watered1, 1);
        debug_sub_80C33FC(gUnknown_Debug_083F7FD3, berryTree->watered2, 1);
        debug_sub_80C33FC(gUnknown_Debug_083F7FD3, berryTree->watered3, 1);
        debug_sub_80C33FC(gUnknown_Debug_083F7FD3, berryTree->watered4, 1);

        return gStringVar4;
    }
}

#endif

// whenever the player is not within view of the berry tree during its sparkle state, the
// sparkle state will be reset.
void ResetBerryTreeSparkleFlags(void)
{
    s16 cam_left;
    s16 cam_top;
    s16 left;
    s16 top;
    s16 right;
    s16 bottom;
    int i;

    GetCameraCoords(&cam_left, &cam_top);
    left = cam_left;
    top = cam_top + 3;
    right = cam_left + 14;
    bottom = top + 8;
    for (i = 0; i < OBJECT_EVENTS_COUNT; i++)
    {
        if (gObjectEvents[i].active && gObjectEvents[i].movementType == MOVEMENT_TYPE_BERRY_TREE_GROWTH)
        {
            cam_left = gObjectEvents[i].currentCoords.x;
            cam_top = gObjectEvents[i].currentCoords.y;
            if (left <= cam_left && cam_left <= right && top <= cam_top && cam_top <= bottom)
                ResetBerryTreeSparkleFlag(gObjectEvents[i].trainerRange_berryTreeId);
        }
    }
}
