summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authoremilybrooks <emilybrooksemilybrooks@gmail.com>2023-09-11 10:27:49 -0700
committerGitHub <noreply@github.com>2023-09-11 10:27:49 -0700
commit1b465cfe8b3f228faa08fba8d58a8d3be6e82d06 (patch)
tree52f985360d8ea448dc71ade81773f3db66c4825f /src/code
parent67934dfa87091278cad91df45e9b9577236e5742 (diff)
m_snowman OK (#94)
* moved everything from private fork * trying to figure out name stuff * matched mSN_check_life * fully matching * add season enum * forgot * fixed structs
Diffstat (limited to 'src/code')
-rw-r--r--src/code/m_snowman.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/code/m_snowman.c b/src/code/m_snowman.c
new file mode 100644
index 0000000..a60ac1f
--- /dev/null
+++ b/src/code/m_snowman.c
@@ -0,0 +1,143 @@
+/**
+ * @file m_snowman.c
+ *
+ * Manages data associated with snowmen.
+ *
+ * This data is stored in the SnowmanData struct in the save file.
+ * There can be three snowmen built at a single time. Each snowman has 3 variations depending on how melted they are.
+ * The first snowman uses the names SNOWMAN0, SNOWMAN1, and SNOWMAN2, the second snowman uses SNOWMAN3, SNOWMAN4, and
+ * SNOWMAN5, etc.
+ *
+ */
+
+#include "global.h"
+#include "m_snowman.h"
+#include "m_common_data.h"
+#include "m_field_info.h"
+#include "m_police_box.h"
+#include "m_lib.h"
+#include "libc64/qrand.h"
+#include "m_name_table.h"
+
+/**
+ * After advancing daysElapsed days, is the snowman completely melted?
+ *
+ * @return True if the snowman is alive, False if the snowman is dead.
+ */
+s32 mSN_check_life(u16* name, s32 daysElapsed) {
+ s32 ret = false;
+
+ // Snowmen outside of winter die regardless of daysElapsed.
+ if (common_data.time.season == WINTER) {
+ s32 snowmanAge = ((*name - SNOWMAN0) % SNOWMAN_SAVE_COUNT);
+
+ if (snowmanAge + daysElapsed < 3) {
+ ret = true;
+ }
+ }
+
+ return ret;
+}
+
+void mSN_ClearSnowmanData(u16* name, s32 snowmanIndex) {
+ bzero(&common_data.snowmanData[snowmanIndex], sizeof(SnowmanData));
+ *name = 0;
+}
+
+s32 mSN_ClearSnowman(u16* name) {
+ s32 ret = 0;
+
+ if ((*name >= SNOWMAN0) && (*name <= SNOWMAN8)) {
+ s32 snowmanIndex = (*name - SNOWMAN0) / SNOWMAN_SAVE_COUNT;
+
+ mSN_ClearSnowmanData(name, snowmanIndex);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/**
+ * Modify a snowman according to how many days have passed.
+ *
+ * @return 0 if the actor isn't a snowman. 1 if the actor is a snowman.
+ */
+s32 mSN_MeltSnowman(u16* name, s32 daysElapsed) {
+ s32 ret = 0;
+
+ if ((*name >= SNOWMAN0) && (*name <= SNOWMAN8)) {
+ s32 snowmanIndex = (*name - SNOWMAN0) / SNOWMAN_SAVE_COUNT;
+
+ if (daysElapsed < 0) {
+ daysElapsed = 1;
+ common_data.snowmanYear = 0;
+ common_data.snowmanMonth = 0;
+ common_data.snowmanDay = 0;
+ common_data.snowmanHour = 0;
+ }
+
+ if (!mSN_check_life(name, daysElapsed)) {
+ mSN_ClearSnowmanData(name, snowmanIndex);
+
+ } else {
+ SnowmanData* snowmanData = &common_data.snowmanData[snowmanIndex];
+
+ *name += daysElapsed;
+
+ while (daysElapsed) {
+ snowmanData->headSize = (u8)(s32)(snowmanData->headSize * 0.8f);
+ snowmanData->bodySize = (u8)(s32)(snowmanData->bodySize * 0.8f);
+ daysElapsed--;
+ }
+ }
+
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/**
+ * Find a slot in SnowmanData that isn't occupied by a snowman.
+ *
+ * @return the index of the first empty slot. If there are no empty slots, return -1.
+ */
+s32 mSN_get_free_space(void) {
+ SnowmanData* snowmanData = common_data.snowmanData;
+ s32 snowmanIndex;
+
+ for (snowmanIndex = 0; snowmanIndex < SNOWMAN_SAVE_COUNT; snowmanIndex++) {
+ if (!snowmanData[snowmanIndex].exists) {
+ return snowmanIndex;
+ }
+ }
+
+ return -1;
+}
+
+void mSN_regist_snowman_society(SnowmanInfo* snowmanInfo) {
+ u16 sp2E = *mFI_GetUnitFG(snowmanInfo->position);
+ s32 snowmanIndex = mSN_get_free_space();
+ u16 name;
+
+ if (snowmanIndex != -1) {
+ mem_copy(&common_data.snowmanData[snowmanIndex], snowmanInfo, sizeof(SnowmanData));
+
+ if (sp2E) {
+ mPB_keep_item(sp2E);
+ mFI_Wpos2DepositOFF(snowmanInfo->position);
+ }
+
+ name = snowmanIndex * SNOWMAN_SAVE_COUNT + SNOWMAN0;
+ mFI_SetFG_common(name, snowmanInfo->position, 1);
+ }
+}
+
+void mSN_decide_msg(void) {
+ common_data.unk_1074C = fqrand() * 3.0f;
+}
+
+void mSN_snowman_init(void) {
+ bzero(common_data.snowmanData, sizeof(SnowmanData[SNOWMAN_SAVE_COUNT]));
+ mSN_decide_msg();
+}