#ifndef M_EVENT_H #define M_EVENT_H #include "types.h" #include "libu64/gfxprint.h" #include "m_personal_id.h" #include "m_private.h" #include "m_time.h" #include "m_olib.h" #ifdef __cplusplus extern "C" { #endif #define mEv_TODAY_EVENT_NUM 16 #define mEv_SCHEDULE_LAST_WEEKDAY_OF_MONTH 6 /* day of last weekday of the month */ #define mEv_SCHEDULE_EVERY_WEEK 7 /* scheduled for the desired day this week (e.g. this saturday) */ /* Month flags */ #define mEv_SCHEDULE_HARVEST_MOON_DATE 0x40 /* Use this year's lunisolar harvest moon date */ #define mEv_SCHEDULE_NOW_MONTH 0x20 #define mEv_SCHEDULE_USE_SAVE_MONTH 0x10 #define mEv_SCHEDULE_SAVE_MONTH(m) (mEv_SCHEDULE_USE_SAVE_MONTH | ((m) & 0xF)) #define mEv_SCHEDULE_LUNAR(m) (mEv_SCHEDULE_HARVEST_MOON_DATE | ((m) & 0xF)) /* Day flags */ #define mEv_SCHEDULE_WEEKLY 0x80 /* Event happens on a given weekday and week of the month */ #define mEv_SCHEDULE_TOWN_DAY 0x40 /* Use save data 'town day' day */ #define mEv_SCHEDULE_DAY_AFTER 0x40 /* When used in conjunction with the 'weekly' flag, it schedules on the day after the Nth weekday */ #define mEv_SCHEDULE_LAST_DAY_OF_MONTH 0x20 #define mEv_SCHEDULE_MAKE_WEEKLY_DATA(week, weekday) (mEv_SCHEDULE_WEEKLY | ((((week) & 0b111) << 3) | ((weekday) & 0b111))) #define mEv_SCHEDULE_1ST_WEEKDAY(weekday) mEv_SCHEDULE_MAKE_WEEKLY_DATA(1, weekday) #define mEv_SCHEDULE_2ND_WEEKDAY(weekday) mEv_SCHEDULE_MAKE_WEEKLY_DATA(2, weekday) #define mEv_SCHEDULE_3RD_WEEKDAY(weekday) mEv_SCHEDULE_MAKE_WEEKLY_DATA(3, weekday) #define mEv_SCHEDULE_4TH_WEEKDAY(weekday) mEv_SCHEDULE_MAKE_WEEKLY_DATA(4, weekday) #define mEv_SCHEDULE_5TH_WEEKDAY(weekday) mEv_SCHEDULE_MAKE_WEEKLY_DATA(5, weekday) #define mEv_SCHEDULE_LAST_WEEKDAY(weekday) mEv_SCHEDULE_MAKE_WEEKLY_DATA(mEv_SCHEDULE_LAST_WEEKDAY_OF_MONTH, weekday) #define mEv_SCHEDULE_EVERY_WEEKDAY(weekday) mEv_SCHEDULE_MAKE_WEEKLY_DATA(mEv_SCHEDULE_EVERY_WEEK, weekday) /* Hour flags */ #define mEv_SCHEDULE_TODAY 0x80 /* event will be active on the day loaded */ #define mEv_SCHEDULE_MULTIDAY 0x40 /* event scheduled over more than a single day */ #define mEv_SCHEDULE_USE_SAVE_SLOT_VALUE 0x20 #define mEv_SCHEDULE_HOUR_SLOT(h) (mEv_SCHEDULE_USE_SAVE_SLOT_VALUE | (h & 0xF)) #define mEv_TO_DAY(month_day) ((lbRTC_day_t)(month_day)) #define mEv_TO_MONTH(month_day) ((lbRTC_month_t)((month_day) >> 8)) typedef union event_monthday_s { struct { u8 month; u8 day; }; u16 raw; } mEv_MonthDay_u; typedef struct event_today_s { int type; u32 active_hours; /* bitfield (24 bits) */ mEv_MonthDay_u begin_date; mEv_MonthDay_u end_date; s16 status; u16 pad; } mEv_event_today_c; typedef struct event_date_s { u8 month; u8 day; u8 _2; u8 hour; } mEv_schedule_date_c; typedef union { mEv_schedule_date_c d; u16 md, _h; u32 raw; } mEv_schedule_date_u; typedef struct event_schedule_s { mEv_schedule_date_u date[2]; /* 0 = begin, 1 = end */ s16 _8; s16 type; /* event type */ } mEv_schedule_c; #define mEv_EVENT_HOUR_START_EVENT (1 << 28) #define mEv_EVENT_HOUR_CLEAR_EVENT (1 << 29) #define mEv_EVENT_HOUR_TOO_SHORT_EVENT (1 << 30) /** * Event type definition * xxxyyyyy yyyyyyyy yyyyyyyy yyyyyyyy * * x: event type (e.g. special event, 'first job' (chores) event, holidays, ...) (0-7) * y: sub-type (specific event) **/ #define mEv_SUBTYPE_BITS 29 #define mEv_TYPE_BITMASK (0b111 << mEv_SUBTYPE_BITS) #define mEv_SUBTYPE_BITMASK ((1 << mEv_SUBTYPE_BITS) - 1) #define mEv_GET_TYPE(event) (((event) & mEv_TYPE_BITMASK) >> mEv_SUBTYPE_BITS) #define mEv_SET_TYPE(t) (((t) << mEv_SUBTYPE_BITS) & mEv_TYPE_BITMASK) #define mEv_GET_SUBTYPE(event) ((event) & mEv_SUBTYPE_BITMASK) #define mEv_SET_SUBTYPE(s) ((s) & mEv_SUBTYPE_BITMASK) #define mEv_SET(type, subtype) (mEv_SET_TYPE(type) | mEv_SET_TYPE(subtype)) enum event_type { mEv_SPNPC_EVENT, /* special NPC events */ mEv_SAVED_EVENT, /* events saved to data */ mEv_TYPE2_EVENT, /* unused? */ mEv_TYPE3_EVENT, /* unused? */ mEv_TYPE4_EVENT, /* unused? */ mEv_DAILY_EVENT, /* checked daily always? aSL_ReportShopOpen2Event has event 3 */ mEv_SPECL_EVENT, /* ??? secondary special npc event data? */ mEv_EVENT_TYPE_NUM }; enum events { mEv_SPNPC_SHOP = (int)mEv_SET(mEv_SPNPC_EVENT, 0), mEv_SPNPC_DESIGNER, mEv_SPNPC_BROKER, mEv_SPNPC_ARTIST, mEv_SPNPC_ARABIAN, mEv_SPNPC_GYPSY, mEv_SPNPC_END, mEv_SAVED_RENEWSHOP = (int)mEv_SET(mEv_SAVED_EVENT, 0), /* renew shop */ mEv_SAVED_UNK1, /* unused */ /* intro through chores */ mEv_SAVED_FIRSTJOB_PLR0, mEv_SAVED_FIRSTJOB_PLR1, mEv_SAVED_FIRSTJOB_PLR2, mEv_SAVED_FIRSTJOB_PLR3, /* selecting house */ mEv_SAVED_FIRSTINTRO_PLR0, mEv_SAVED_FIRSTINTRO_PLR1, mEv_SAVED_FIRSTINTRO_PLR2, mEv_SAVED_FIRSTINTRO_PLR3, /* wait for next day to talk about HRA */ mEv_SAVED_HRAWAIT_PLR0, mEv_SAVED_HRAWAIT_PLR1, mEv_SAVED_HRAWAIT_PLR2, mEv_SAVED_HRAWAIT_PLR3, /* Nook will talk about HRA when entering the shop */ mEv_SAVED_HRATALK_PLR0, mEv_SAVED_HRATALK_PLR1, mEv_SAVED_HRATALK_PLR2, mEv_SAVED_HRATALK_PLR3, /* Do a 'favor' for a villager during chores */ mEv_SAVED_FJOPENQUEST_PLR0, mEv_SAVED_FJOPENQUEST_PLR1, mEv_SAVED_FJOPENQUEST_PLR2, mEv_SAVED_FJOPENQUEST_PLR3, /* Player going to another town, set at train station */ mEv_SAVED_GATEWAY_PLR0, mEv_SAVED_GATEWAY_PLR1, mEv_SAVED_GATEWAY_PLR2, mEv_SAVED_GATEWAY_PLR3, mEv_SAVED_GATEWAY_FRGN, /* Foreigner */ mEv_DAILY_0 = (int)mEv_SET(mEv_DAILY_EVENT, 0), /* unused */ mEv_DAILY_1, /* unused */ mEv_DAILY_2, /* unused */ mEv_DAILY_OPEN_SHOP, /* shop opened */ mEv_SPECL_DESIGNER_COMPLETE = (int)mEv_SET(mEv_SPECL_EVENT, 0) }; enum week_type { mEv_WEEKTYPE_NONE, mEv_WEEKTYPE_1ST, mEv_WEEKTYPE_2ND, mEv_WEEKTYPE_3RD, mEv_WEEKTYPE_4TH, mEv_WEEKTYPE_5TH, mEv_WEEKTYPE_LAST, mEv_WEEKTYPE_SPECIAL }; enum event_table { mEv_EVENT_RUMOR_NEW_YEARS_DAY, mEv_EVENT_NEW_YEARS_DAY, mEv_EVENT_RUMOR_KAMAKURA, mEv_EVENT_KAMAKURA, mEv_EVENT_SONCHO_VACATION_JANUARY, mEv_EVENT_SONCHO_VACATION_FEBRUARY, mEv_EVENT_RUMOR_GROUNDHOG_DAY, mEv_EVENT_GROUNDHOG_DAY, mEv_EVENT_RUMOR_VALENTINES_DAY, mEv_EVENT_VALENTINES_DAY, mEv_EVENT_RUMOR_SPRING_SPORTS_FAIR, mEv_EVENT_SPRING_EQUINOX, mEv_EVENT_SPORTS_FAIR_BALL_TOSS, mEv_EVENT_SPORTS_FAIR_AEROBICS, mEv_EVENT_SPORTS_FAIR_TUG_OF_WAR, mEv_EVENT_SPORTS_FAIR_FOOT_RACE, mEv_EVENT_SPORTS_FAIR, mEv_EVENT_APRILFOOLS_DAY, mEv_EVENT_RUMOR_APRILFOOLS_DAY, mEv_EVENT_RUMOR_CHERRY_BLOSSOM_FESTIVAL, mEv_EVENT_CHERRY_BLOSSOM_FESTIVAL, mEv_EVENT_NATURE_DAY, mEv_EVENT_SPRING_CLEANING, mEv_EVENT_MOTHERS_DAY, mEv_EVENT_SUMMER_CAMPER, mEv_EVENT_GRADUATION_DAY, mEv_EVENT_FATHERS_DAY, mEv_EVENT_RUMOR_FISHING_TOURNEY_1, mEv_EVENT_TALK_FISHING_TOURNEY_1, // for dialog? mEv_EVENT_FISHING_TOURNEY_1, mEv_EVENT_TOWN_DAY, mEv_EVENT_RUMOR_FIREWORKS_SHOW, mEv_EVENT_FIREWORKS_SHOW, mEv_EVENT_RUMOR_MORNING_AEROBICS, mEv_EVENT_TALK_MORNING_AEROBICS, mEv_EVENT_MORNING_AEROBICS, mEv_EVENT_RUMOR_METEOR_SHOWER, mEv_EVENT_METEOR_SHOWER, mEv_EVENT_FOUNDERS_DAY, mEv_EVENT_LABOR_DAY, mEv_EVENT_RUMOR_FALL_SPORTS_FAIR, mEv_EVENT_AUTUMN_EQUINOX, mEv_EVENT_RUMOR_HARVEST_MOON_DAY, mEv_EVENT_HARVEST_MOON_FESTIVAL, mEv_EVENT_EXPLORERS_DAY, mEv_EVENT_RUMOR_MUSHROOM_SEASON, mEv_EVENT_TALK_MUSHROOM_SEASON, mEv_EVENT_MUSHROOM_SEASON, mEv_EVENT_RUMOR_HALLOWEEN, mEv_EVENT_HALLOWEEN, mEv_EVENT_MAYORS_DAY, mEv_EVENT_OFFICERS_DAY, mEv_EVENT_RUMOR_FISHING_TOURNEY_2, mEv_EVENT_TALK_FISHING_TOURNEY_2, mEv_EVENT_FISHING_TOURNEY_2, mEv_EVENT_RUMOR_HARVEST_FESTIVAL, mEv_EVENT_HARVEST_FESTIVAL, mEv_EVENT_SALE_DAY, mEv_EVENT_SNOW_DAY, mEv_EVENT_TOY_DAY_SONCHO, mEv_EVENT_RUMOR_TOY_DAY, mEv_EVENT_TOY_DAY_JINGLE, mEv_EVENT_SNOWMAN_SEASON, mEv_EVENT_RUMOR_NEW_YEARS_EVE_COUNTDOWN, mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_EVENT_CHERRY_BLOSSOM_PETALS, mEv_EVENT_TALK_TOY_DAY, mEv_EVENT_PLAYER_BIRTHDAY, mEv_EVENT_DOZAEMON, mEv_EVENT_KABU_PEDDLER, mEv_EVENT_LOTTERY, mEv_EVENT_KK_SLIDER, mEv_EVENT_HANDBILL_BROKER, mEv_EVENT_HANDBILL_SHOP_SALE, mEv_EVENT_ARTIST, mEv_EVENT_BROKER_SALE, mEv_EVENT_DESIGNER, mEv_EVENT_GYPSY, mEv_EVENT_SHOP_SALE, mEv_EVENT_CARPET_PEDDLER, mEv_EVENT_SONCHO_NEW_YEARS_DAY, mEv_EVENT_SONCHO_GROUNDHOG_DAY, mEv_EVENT_SONCHO_SPRING_SPORTS_FAIR, mEv_EVENT_SONCHO_APRILFOOLS_DAY, mEv_EVENT_SONCHO_CHERRY_BLOSSOM_FESTIVAL, mEv_EVENT_SONCHO_NATURE_DAY, mEv_EVENT_SONCHO_SPRING_CLEANING, mEv_EVENT_SONCHO_MOTHERS_DAY, mEv_EVENT_SONCHO_GRADUATION_DAY, mEv_EVENT_SONCHO_FATHERS_DAY, mEv_EVENT_SONCHO_FISHING_TOURNEY_1, mEv_EVENT_SONCHO_TOWN_DAY, mEv_EVENT_SONCHO_FIREWORKS_SHOW, mEv_EVENT_SONCHO_METEOR_SHOWER, mEv_EVENT_SONCHO_FOUNDERS_DAY, mEv_EVENT_SONCHO_LABOR_DAY, mEv_EVENT_SONCHO_FALL_SPORTS_FAIR, mEv_EVENT_SONCHO_HARVEST_MOON_FESTIVAL, mEv_EVENT_SONCHO_EXPLORERS_DAY, mEv_EVENT_SONCHO_HALLOWEEN, mEv_EVENT_SONCHO_MAYORS_DAY, mEv_EVENT_SONCHO_OFFICERS_DAY, mEv_EVENT_SONCHO_FISHING_TOURNEY_2, mEv_EVENT_SONCHO_HARVEST_FESTIVAL, mEv_EVENT_SONCHO_SALE_DAY, mEv_EVENT_SONCHO_SNOW_DAY, mEv_EVENT_SONCHO_TOY_DAY, mEv_EVENT_TALK_NEW_YEARS_COUNTDOWN, mEv_EVENT_HARVEST_FESTIVAL_FRANKLIN, mEv_EVENT_WEATHER_CLEAR, mEv_EVENT_WEATHER_SNOW, mEv_EVENT_WEATHER_SPORTS_FAIR, mEv_EVENT_BRIDGE_MAKE, mEv_EVENT_SONCHO_BRIDGE_MAKE, mEv_EVENT_GHOST, mEv_EVENT_MASK_NPC, // "Go Home Npc" & "Blanca" events mEv_EVENT_74, // unused? mEv_EVENT_KOINOBORI, mEv_EVENT_76, // unused? mEv_EVENT_NUM }; enum { mEv_SAVE_DATE_TODAY, mEv_SAVE_DATE_LAST_PLAY_DATE, mEv_SAVE_DATE_BIRTHDAY, mEv_SAVE_DATE_SPECIAL0, /* Initialized to rtc month-day in init_special_event */ mEv_SAVE_DATE_SPECIAL1, /* Initialized to beginning month-day of special event in init_special_event */ mEv_SAVE_DATE_SPECIAL2, /* Initialized to ending month-day of special event in init_special_event */ mEv_SAVE_DATE_WEEKLY, mEv_SAVE_DATE_SPECIAL3, /* Initialized to opening hours for shop sale in init_special_event */ mEv_SAVE_DATE_NUM }; enum { mEv_SPECIAL_STATE_UNSCHEDULED, mEv_SPECIAL_STATE_SCHEDULED_LATER, mEv_SPECIAL_STATE_SCHEDULED_TODAY, mEv_SPECIAL_STATE_ACTIVE, mEv_SPECIAL_STATE_NUM }; #define mEv_STATUS_ACTIVE (1 << 0) /* event is active */ #define mEv_STATUS_STOP (1 << 1) /* event is stopped */ #define mEv_STATUS_SHOW (1 << 2) /* event is shown */ #define mEv_STATUS_PLAYSOUND (1 << 3) /* event should play sound */ #define mEv_STATUS_RUN (1 << 4) /* event should run */ #define mEv_STATUS_ERROR (1 << 5) /* event is in error state */ #define mEv_STATUS_TALK (1 << 6) /* event requires talking to player */ #define mEv_STATUS_EXIST (1 << 7) /* event is scheduled */ #define mEv_GHOST_HITODAMA_NUM 5 typedef struct ghost_spirit_block_data_s { u8 block_x[mEv_GHOST_HITODAMA_NUM]; u8 block_z[mEv_GHOST_HITODAMA_NUM]; } mEv_gst_hitodama_block_c; #define mEv_GHOST_FLAG_ACTIVE 0x4000 // TODO: do these live in the ghost actor itself? typedef struct ghost_common_s { mEv_gst_hitodama_block_c hitodama_block_data; u16 flags; u8 _0C[0x2C - 0x0C]; } mEv_gst_common_c; #define mEv_DESGINER_NUM 3 typedef struct kabu_peddler_event_s { PersonalID_c spoken_pids[TOTAL_PLAYER_NUM]; } mEv_kabu_peddler_c; typedef struct dozaemon_event_s { u16 flags; } mEv_dozaemon_c; typedef union { mEv_kabu_peddler_c kabu_peddler; mEv_dozaemon_c dozaemon; } mEv_weekly_u; typedef struct bargin_event_s { lbRTC_time_c start_time; lbRTC_time_c end_time; mActor_name_t items[5]; int kind; } mEv_bargin_c; typedef struct designer_event_s { PersonalID_c pids[mEv_DESGINER_NUM]; int used; mActor_name_t gifted_cloths[mEv_DESGINER_NUM]; } mEv_designer_c; typedef struct broker_event_s { PersonalID_c pid[2]; lbRTC_time_c end_time; int used; mActor_name_t sold_items[2]; mActor_name_t items[3]; } mEv_broker_c; typedef struct artist_event_s { PersonalID_c pids[2]; int used; mActor_name_t walls[2]; } mEv_artist_c; typedef struct arabian_event_s { int used; mActor_name_t carpet; } mEv_arabian_c; typedef struct gypsy_event_s { int _00; int block_z; int block_x; int ut_z; int ut_x; } mEv_gypsy_c; typedef union { mEv_bargin_c bargin; mEv_designer_c designer; mEv_broker_c broker; mEv_artist_c artist; mEv_arabian_c arabian; mEv_gypsy_c gypsy; } mEv_special_u; typedef struct special_event_s { lbRTC_time_c scheduled; u32 type; mEv_special_u event; } mEv_special_c; typedef struct save_event_data_s { mEv_special_c special; mEv_weekly_u weekly; u32 flags; } mEv_event_save_c; typedef struct broker_event_common_s { PersonalID_c entered_pid; int hide_npc; } mEv_broker_common_c; typedef struct santa_event_common_s { u8 present; u8 talk_counter; s8 bx; s8 bz; mActor_name_t last_talk_cloth; } mEv_santa_event_common_c; #define mEv_SANTA_CLOTH_NUM_MAX 10 /* How many different shirts can the player trick Jingle with */ typedef struct santa_event_s { PersonalID_c pid; u8 present_count; mActor_name_t cloth[mEv_SANTA_CLOTH_NUM_MAX]; } mEv_santa_event_c; typedef union { mEv_broker_common_c broker; mEv_santa_event_common_c santa; } mEv_event_common_u; typedef struct event_s { u8 day; u8 hour; u8 _02; u8 state; u8 month; u8 year; s16 changed_num; int block_z; int block_x; int unused[5]; } Event_c; typedef struct event_info_s { u8 type; u8 id; u16 year; mEv_MonthDay_u start_date; mEv_MonthDay_u end_date; } mEv_info_c; typedef struct event_place_data_s { BlockOrUnit_c block; BlockOrUnit_c unit; mActor_name_t actor_name; s16 flag; } mEv_place_data_c; typedef struct event_place_s { mEv_info_c info; mEv_place_data_c data; } mEv_place_c; typedef struct event_area_s { mEv_info_c info; int data[11]; } mEv_area_c; #define mEv_AREA_NUM 5 #define mEv_PLACE_NUM 10 typedef struct event_common_s { s16 _00; s16 area_use_bitfield; mEv_area_c area[mEv_AREA_NUM]; s16 too_short; s16 place_use_bitfield; mEv_place_c place[mEv_PLACE_NUM]; s16 fieldday_event_id; s16 fieldday_event_over_status; u32 unused[2]; } mEv_common_data_c; typedef struct event_save_event_info_s { u8 type; u8 flags; } mEv_event_save_info_c; typedef struct event_common_save_data { mEv_event_save_info_c special_event; mEv_event_save_info_c weekly_event; u16 dates[mEv_SAVE_DATE_NUM]; int area_use_bitfield; mEv_area_c area[mEv_AREA_NUM]; int last_date; int delete_event_id; u32 valentines_day_date; u32 white_day_date; /* unused in AC */ u16 ghost_day; u16 bridge_day; // last date suspension bridge event was active union { struct { u8 used_all_locations:1; // set to true when tortimer has cycled through all possible bridge locations? u8 locations_used:7; // index of river acre w/ possible bridge location currently at }; u8 raw; } bridge_flags; u8 ghost_event_type; // 0x72 will spawn wisp, 0x77 won't? u8 soncho_event_type; // checked not equal to 0xFF for summer & fall fishing tournies u8 dozaemon_completed; // used to signal when you've received an item from gulliver } mEv_save_common_data_c; extern int mEv_CheckFirstJob(); extern int mEv_CheckFirstIntro(); extern int mEv_CheckArbeit(); extern int mEv_CheckTitleDemo(); extern int mEv_check_status(int event, s16 status); extern int mEv_check_status_edge(s16 status); extern u8* mEv_get_common_area(int type, u8 id); extern u8* mEv_reserve_common_area(int type, u8 id); extern u8* mEv_get_save_area(int type, u8 id); extern u8* mEv_reserve_save_area(int type, u8 id); extern void mEv_actor_dying_message(int type, ACTOR* actor); extern int mEv_ArbeitPlayer(u32 player_no); extern u16 mEv_get_special_event_type(); extern void mEv_ClearEventSaveInfo(mEv_event_save_c* event_save_data); extern void mEv_EventON(u32 event_kind); extern int mEv_CheckGateway(); extern int mEv_check_schedule(int event); extern mEv_place_data_c* mEv_get_common_place(int type, u8 id); extern void mEv_set_status(int event, s16 status); extern void mEv_GetEventWeather(s16* weather, s16* intensity); extern int mEv_CheckRealArbeit(); extern int mEv_CheckEvent(u32 event); extern u16 mEv_get_bargain_day(); extern int mEv_weekday2day(lbRTC_month_t month, int week_type, int weekday); extern void mEv_ClearEventInfo(); extern void mEv_init(Event_c* event); extern void mEv_2nd_init(Event_c* event); extern void mEv_run(Event_c* event); extern void mEv_finish(Event_c* event); extern int mEv_CheckTitleDemo(); extern void mEv_SetTitleDemo(int titledemo_no); extern int mGH_check_birth2(); extern int mMC_check_birth(); extern void mEv_debug_print4f(gfxprint_t* gfxprint); extern void mEv_sp_debug_print4f(gfxprint_t* gfxprint); #ifdef __cplusplus } #endif #endif