summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYamaArashi <YamaArashi@users.noreply.github.com>2016-10-28 12:44:32 -0700
committerGitHub <noreply@github.com>2016-10-28 12:44:32 -0700
commitb350c7e9fa867af2871ac2c6b92f95e8bb77617c (patch)
treedfa26bc0b921e09ed0adcaeb2c7988511bf5bbf1 /src
parent4c74840c08660db73df40febe94dde07b2dfe4f8 (diff)
parent0c7d1385e8747383295d7df37ab10c440d20b603 (diff)
Merge pull request #75 from yenatch/master
Decompile berry.c.
Diffstat (limited to 'src')
-rw-r--r--src/berry.c471
1 files changed, 471 insertions, 0 deletions
diff --git a/src/berry.c b/src/berry.c
new file mode 100644
index 000000000..11d261790
--- /dev/null
+++ b/src/berry.c
@@ -0,0 +1,471 @@
+#include "global.h"
+
+#define FIRST_BERRY 0x85 // ITEM_CHERI_BERRY
+#define LAST_BERRY 0xaf // ITEM_ENIGMA_BERRY
+
+extern u8 GetStageByBerryTreeId(u8);
+extern u16 GetStageDurationByBerryType(u8);
+extern void SetMainCallback2(void*);
+extern void sub_80A68CC();
+extern u16 Random(void);
+extern u8 sub_8060234(u8, u8, u8);
+extern u8 AddBagItem(u16, u8);
+extern void sub_8060288(u8, u8, u8);
+extern u8 IsBagPocketNonEmpty(u8);
+extern void GetCameraCoords(s16*, s16*);
+extern u8 FieldObjectGetBerryTreeId(u8);
+extern u8 *GetFieldObjectScriptPointerForComparison();
+
+extern struct Berry gBerries[];
+extern u8 BerryTreeScript;
+extern struct BerryTree gUnknown_083CD780;
+extern u16 gUnknown_0202E8DE;
+extern u16 gUnknown_0202E8CC;
+extern u16 gUnknown_0202E8CE;
+extern u16 gUnknown_0202E8D0;
+
+u8 CalcBerryYield(struct BerryTree *tree);
+
+void unref_sub_80B4884(void)
+{
+ CpuFill16(0, &gSaveBlock1.enigmaBerry, sizeof(gSaveBlock1.enigmaBerry));
+}
+
+// setEnigmaBerry
+void sub_80B48A8(u8 *src)
+{
+ u8 *dest;
+ struct SaveBlock1 *saveBlock;
+ unsigned int i;
+ dest = (u8*)&gSaveBlock1.enigmaBerry;
+ saveBlock = &gSaveBlock1;
+ for (i = 0; i < sizeof(gSaveBlock1.enigmaBerry); i++)
+ {
+ dest[i] = src[i];
+ }
+ gSaveBlock1.enigmaBerry.berry.description1 = gSaveBlock1.enigmaBerry.description1;
+ gSaveBlock1.enigmaBerry.berry.description2 = gSaveBlock1.enigmaBerry.description2;
+}
+
+// checksum
+u32 sub_80B48F8(struct EnigmaBerry *enigmaBerry)
+{
+ u8 *description1;
+ u8 *description2;
+ unsigned int i;
+ u32 checksum;
+ u8 *dest;
+
+ description1 = gSaveBlock1.enigmaBerry.berry.description1;
+ description2 = gSaveBlock1.enigmaBerry.berry.description2;
+ gSaveBlock1.enigmaBerry.berry.description1 = 0;
+ gSaveBlock1.enigmaBerry.berry.description2 = 0;
+
+ dest = (u8*)enigmaBerry;
+ checksum = 0;
+ for (i = 0; i < ((int)&gSaveBlock1.enigmaBerry.checksum - (int)&gSaveBlock1.enigmaBerry); i++)
+ {
+ checksum += dest[i];
+ }
+
+ gSaveBlock1.enigmaBerry.berry.description1 = description1;
+ gSaveBlock1.enigmaBerry.berry.description2 = description2;
+
+ return checksum;
+}
+
+int sub_80B4940(void)
+{
+ if (!gSaveBlock1.enigmaBerry.berry.stageDuration)
+ return 0;
+ if (!gSaveBlock1.enigmaBerry.berry.maxYield)
+ return 0;
+ if (sub_80B48F8(&gSaveBlock1.enigmaBerry) != gSaveBlock1.enigmaBerry.checksum)
+ return 0;
+ return 1;
+}
+
+struct Berry *GetBerryInfo(u8 berry)
+{
+ if ((u8)berry == 0x2b)
+ {
+ if (sub_80B4940())
+ return &gSaveBlock1.enigmaBerry.berry;
+ }
+ if ((u8)(berry - 1) > 0x2a)
+ {
+ berry = 1;
+ }
+ return &gBerries[berry - 1];
+}
+
+struct BerryTree *GetBerryTreeInfo(u8 id)
+{
+ return &gSaveBlock1.berryTrees[id];
+}
+
+int FieldObjectInteractionWaterBerryTree(void)
+{
+ struct BerryTree *tree = GetBerryTreeInfo(FieldObjectGetBerryTreeId(gSelectedMapObject));
+ switch (tree->stage)
+ {
+ case 1:
+ tree->watered1 = 1;
+ break;
+ case 2:
+ tree->watered2 = 1;
+ break;
+ case 3:
+ tree->watered3 = 1;
+ break;
+ case 4:
+ tree->watered4 = 1;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int IsPlayerFacingPlantedBerryTree(void)
+{
+ if (GetFieldObjectScriptPointerForComparison() == &BerryTreeScript)
+ if (GetStageByBerryTreeId(FieldObjectGetBerryTreeId(gSelectedMapObject)) == 0)
+ return 1;
+ return 0;
+}
+
+u8 WaterBerryTree(void)
+{
+ if (GetFieldObjectScriptPointerForComparison() != &BerryTreeScript)
+ return 0;
+ return FieldObjectInteractionWaterBerryTree();
+}
+
+void sub_80B4A90(void)
+{
+ int i;
+ struct SaveBlock1 *saveBlock1 = &gSaveBlock1;
+ struct BerryTree berryTree = gUnknown_083CD780;
+ for (i = 127; i >= 0; i--)
+ {
+ saveBlock1->berryTrees[i] = berryTree;
+ }
+}
+
+int BerryTreeGrow(struct BerryTree *tree)
+{
+ if (tree->growthSparkle)
+ return 0;
+ switch (tree->stage)
+ {
+ case 0:
+ return 0;
+ case 4:
+ tree->berryYield = CalcBerryYield(tree);
+ case 1:
+ case 2:
+ case 3:
+ tree->stage++;
+ break;
+ case 5:
+ tree->watered1 = 0;
+ tree->watered2 = 0;
+ tree->watered3 = 0;
+ tree->watered4 = 0;
+ tree->berryYield = 0;
+ tree->stage = 2;
+ if (++tree->regrowthCount == 10)
+ *tree = gUnknown_083CD780;
+ break;
+ }
+ return 1;
+}
+
+void BerryTreeTimeUpdate(int time)
+{
+ int i;
+ struct BerryTree *tree;
+ int time2;
+ for (i = 0; i <= 0x7f; i++)
+ {
+ tree = &gSaveBlock1.berryTrees[i];
+
+ if (tree->berry == 0)
+ continue;
+ if (tree->stage == 0)
+ continue;
+ if (tree->growthSparkle)
+ continue;
+
+ if (time >= GetStageDurationByBerryType(tree->berry) * 71)
+ {
+ *tree = gUnknown_083CD780;
+ continue;
+ }
+
+ time2 = time;
+ if (!time2)
+ continue;
+
+ if (tree->secondsUntilNextStage > time2)
+ {
+ tree->secondsUntilNextStage -= time2;
+ time2 = tree->secondsUntilNextStage;
+ continue;
+ }
+
+ while (1)
+ {
+ time2 -= tree->secondsUntilNextStage;
+ tree->secondsUntilNextStage = GetStageDurationByBerryType(tree->berry);
+ if (BerryTreeGrow(tree))
+ {
+ if (tree->stage == 5)
+ {
+ tree->secondsUntilNextStage *= 4;
+ }
+ if (!time2)
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ if (tree->secondsUntilNextStage > time2)
+ {
+ tree->secondsUntilNextStage -= time2;
+ time2 = tree->secondsUntilNextStage;
+ break;
+ }
+ }
+ }
+}
+
+void PlantBerryTree(u8 id, u8 berry, u8 stage, u8 sparkle)
+{
+ struct BerryTree *tree;
+ tree = GetBerryTreeInfo(id);
+ *tree = gUnknown_083CD780;
+ tree->berry = berry;
+ tree->secondsUntilNextStage = GetStageDurationByBerryType(berry);
+ tree->stage = stage;
+ if (stage == 5)
+ {
+ tree->berryYield = CalcBerryYield(tree);
+ tree->secondsUntilNextStage *= 4;
+ }
+ if (sparkle == 0)
+ {
+ tree->growthSparkle = 1;
+ }
+}
+
+void RemoveBerryTree(u8 id)
+{
+ gSaveBlock1.berryTrees[id] = gUnknown_083CD780;
+}
+
+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;
+ if (berry > LAST_BERRY - FIRST_BERRY)
+ return 1;
+ return item - FIRST_BERRY + 1;
+}
+
+u16 BerryTypeToItemId(u16 berry)
+{
+ u16 item = berry;
+ item -= 1;
+ if (item > LAST_BERRY - FIRST_BERRY)
+ return FIRST_BERRY;
+ item = berry;
+ return item + FIRST_BERRY - 1;
+}
+
+void GetBerryNameByBerryType(u8 berry, u8 *string)
+{
+ struct Berry *info;
+ info = GetBerryInfo(berry);
+ memcpy(string, info->name, 6);
+ string[6] = 0xff;
+}
+
+void ResetBerryTreeSparkleFlag(u8 id)
+{
+ struct BerryTree *tree;
+ tree = GetBerryTreeInfo(id);
+ tree->growthSparkle = 0;
+}
+
+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;
+}
+
+u8 GetNumStagesWateredByBerryTreeId(u8 id)
+{
+ return BerryTreeGetNumStagesWatered(GetBerryTreeInfo(id));
+}
+
+u8 CalcBerryYieldInternal(u16 a1, u16 a2, u8 a3)
+{
+ u32 v6;
+ u32 v1;
+ u32 v5;
+ u32 v4;
+ u16 random;
+ u32 ret;
+ v6 = a2;
+ if (a3 == 0)
+ return v6;
+ v1 = a1 - v6;
+ v5 = v1 * (a3 - 1);
+ v4 = v1 * a3;
+ random = Random();
+ v4 -= v5;
+ v4 += 1;
+ v5 += random % v4;
+ if ((v5 & 3) <= 1)
+ {
+ ret = v5 / 4;
+ return ret + v6;
+ }
+ else
+ {
+ ret = v5 / 4 + 1;
+ return ret + v6;
+ }
+}
+
+u8 CalcBerryYield(struct BerryTree *tree)
+{
+ struct Berry *berry = GetBerryInfo(tree->berry);
+ u8 min = berry->minYield;
+ u8 max = berry->maxYield;
+ return CalcBerryYieldInternal(max, min, BerryTreeGetNumStagesWatered(tree));
+}
+
+u8 GetBerryCountByBerryTreeId(u8 id)
+{
+ return gSaveBlock1.berryTrees[id].berryYield;
+}
+
+u16 GetStageDurationByBerryType(u8 berry)
+{
+ return GetBerryInfo(berry)->stageDuration * 60;
+}
+
+void FieldObjectInteractionGetBerryTreeData(void)
+{
+ u8 id;
+ u8 berry;
+ u8 unk;
+ u8 group;
+ u8 num;
+ id = FieldObjectGetBerryTreeId(gSelectedMapObject);
+ berry = GetBerryTypeByBerryTreeId(id);
+ ResetBerryTreeSparkleFlag(id);
+ unk = gUnknown_0202E8DE;
+ num = gSaveBlock1.location.mapNum;
+ group = gSaveBlock1.location.mapGroup;
+
+ if (sub_8060234(unk, num, group))
+ gUnknown_0202E8CC = 0xff;
+ else
+ gUnknown_0202E8CC = (u8)GetStageByBerryTreeId(id);
+
+ gUnknown_0202E8CE = (u8)GetNumStagesWateredByBerryTreeId(id);
+ gUnknown_0202E8D0 = (u8)GetBerryCountByBerryTreeId(id);
+ GetBerryNameByBerryType(berry, gStringVar1);
+}
+
+void sub_80B4EE4(void)
+{
+ SetMainCallback2(sub_80A68CC);
+}
+
+void FieldObjectInteractionPlantBerryTree(void)
+{
+ extern u16 word_203855E;
+ u8 berry = ItemIdToBerryType(word_203855E);
+ PlantBerryTree(FieldObjectGetBerryTreeId(gSelectedMapObject), berry, 1, 1);
+ FieldObjectInteractionGetBerryTreeData();
+}
+
+void FieldObjectInteractionPickBerryTree(void)
+{
+ u8 id;
+ u8 berry;
+ id = FieldObjectGetBerryTreeId(gSelectedMapObject);
+ berry = GetBerryTypeByBerryTreeId(id);
+ gUnknown_0202E8CC = AddBagItem(BerryTypeToItemId(berry), GetBerryCountByBerryTreeId(id));
+}
+
+void FieldObjectInteractionRemoveBerryTree(void)
+{
+ u8 id;
+ u8 unk;
+ u8 group, num;
+ id = FieldObjectGetBerryTreeId(gSelectedMapObject);
+ RemoveBerryTree(id);
+ unk = gUnknown_0202E8DE;
+ num = gSaveBlock1.location.mapNum;
+ group = gSaveBlock1.location.mapGroup;
+ sub_8060288(unk, num, group);
+}
+
+u8 PlayerHasBerries(void)
+{
+ return IsBagPocketNonEmpty(4);
+}
+
+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 < 16; i++)
+ {
+ if (gMapObjects[i].active && gMapObjects[i].animPattern == 12)
+ {
+ cam_left = gMapObjects[i].coords2.x;
+ cam_top = gMapObjects[i].coords2.y;
+ if (left <= cam_left && cam_left <= right && top <= cam_top && cam_top <= bottom)
+ ResetBerryTreeSparkleFlag(gMapObjects[i].trainerRange_berryTreeId);
+ }
+ }
+}