mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-07-28 15:07:07 -04:00
Implement and link m_cockroach, m_police_box
This commit is contained in:
@@ -0,0 +1,310 @@
|
||||
#include "m_cockroach.h"
|
||||
|
||||
#include "m_home.h"
|
||||
#include "m_house.h"
|
||||
#include "m_private.h"
|
||||
#include "m_field_info.h"
|
||||
#include "m_scene_table.h"
|
||||
#include "m_common_data.h"
|
||||
|
||||
/**
|
||||
* @brief Clamps the input cockroach count between [0, mCkRh_MAX_NUM].
|
||||
*
|
||||
* @param count The new cockroach count
|
||||
* @return The clamped cockroach count
|
||||
**/
|
||||
static int mCkRh_GokiFamilyCount2Good(int count) {
|
||||
if (count < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (count <= mCkRh_MAX_NUM ? count : mCkRh_MAX_NUM);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes all house cockroach save data for unclaimed houses
|
||||
* when a new Player is created.
|
||||
**/
|
||||
extern void mCkRh_InitGokiSaveData_InitNewPlayer() {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PLAYER_NUM; i++) {
|
||||
if (mHS_get_pl_no_detail(i) == -1) {
|
||||
mCkRh_InitGokiSaveData_1Room(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes a single house's cockroach data by house index.
|
||||
*
|
||||
* @param home_no The house index whose cockroach data will be initialized
|
||||
**/
|
||||
extern void mCkRh_InitGokiSaveData_1Room(int home_no) {
|
||||
mCkRh_InitGokiSaveData_1Room_ByHomeData(Save_GetPointer(homes[home_no]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes a single house's cockroach data.
|
||||
*
|
||||
* @param home The mHm_hs_c house whose cockroach data wil be initialized.
|
||||
**/
|
||||
extern void mCkRh_InitGokiSaveData_1Room_ByHomeData(mHm_hs_c* home) {
|
||||
home->goki.num = 0;
|
||||
home->goki.pad = 0;
|
||||
|
||||
home->goki.time = Common_Get(time.rtc_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes island cottage cockroach data.
|
||||
**/
|
||||
extern void mCkRh_InitGokiSaveData_IslandPlayerRoom() {
|
||||
const lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time);
|
||||
|
||||
Save_Set(island.cottage.goki.num, 0);
|
||||
Save_Set(island.cottage.goki.pad, 0);
|
||||
Save_Set(island.cottage.goki.time.year, rtc_time->year);
|
||||
Save_Set(island.cottage.goki.time.month, rtc_time->month);
|
||||
Save_Set(island.cottage.goki.time.day, rtc_time->day);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes all houses' cockroach data even if a player owns it.
|
||||
**/
|
||||
extern void mCkRh_InitGokiSaveData_AllRoom() {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PLAYER_NUM; i++) {
|
||||
mCkRh_InitGokiSaveData_1Room(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the cockroach 'last entered' time for the island cottage.
|
||||
*
|
||||
* @param scene_id The current scene id
|
||||
**/
|
||||
extern void mCkRh_SetGoingOutCottageTime(int scene_id) {
|
||||
if (scene_id == SCENE_ISLAND_COTTAGE) {
|
||||
Save_Set(island.cottage.goki.time.year, Common_Get(time.rtc_time.year));
|
||||
Save_Set(island.cottage.goki.time.month, Common_Get(time.rtc_time.month));
|
||||
Save_Set(island.cottage.goki.time.day, Common_Get(time.rtc_time.day));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the cockroach 'last entered' time for a player's house.
|
||||
*
|
||||
* @param player_no The index of the player whose cockroach data will be updated
|
||||
**/
|
||||
extern void mCkRh_SavePlayTime(int player_no) {
|
||||
if (player_no < PLAYER_NUM) {
|
||||
int home_no = mHS_get_arrange_idx(player_no);
|
||||
Save_Set(homes[home_no & 3].goki.time, Common_Get(time.rtc_time));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the inverval in days between the current time and
|
||||
* the last time that the player's cockroach 'last enter time'.
|
||||
*
|
||||
* @param player_no The index of the player whose 'days gap' will be calculated
|
||||
* @return When a foriegner, 0, otherwise day interval
|
||||
**/
|
||||
static int mCkRh_DaysGapCompareWithSaveTime(int player_no) {
|
||||
int homeid;
|
||||
lbRTC_time_c goki_time;
|
||||
int interval;
|
||||
|
||||
if (player_no < PLAYER_NUM) {
|
||||
homeid = mHS_get_arrange_idx(player_no) & 3;
|
||||
goki_time.year = Save_Get(homes[homeid].goki.time.year);
|
||||
goki_time.month = Save_Get(homes[homeid].goki.time.month);
|
||||
goki_time.day = Save_Get(homes[homeid].goki.time.day);
|
||||
goki_time.weekday = lbRTC_Week(goki_time.year, goki_time.month, goki_time.day);
|
||||
goki_time.hour = 1;
|
||||
goki_time.min = 1;
|
||||
goki_time.sec = 1;
|
||||
|
||||
interval = lbRTC_GetIntervalDays(&goki_time, Common_GetPointer(time.rtc_time));
|
||||
}
|
||||
else {
|
||||
interval = 0;
|
||||
}
|
||||
|
||||
return interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the day interval between current time and the island cottage
|
||||
* cockroach last enter time.
|
||||
*
|
||||
* @return days between current time and last island cottage enter time
|
||||
**/
|
||||
static int mCkRh_DaysGapCompareWithCottageSaveTime() {
|
||||
lbRTC_time_c goki_time;
|
||||
|
||||
goki_time.year = Save_Get(island.cottage.goki.time.year);
|
||||
goki_time.month = Save_Get(island.cottage.goki.time.month);
|
||||
goki_time.day = Save_Get(island.cottage.goki.time.day);
|
||||
goki_time.weekday = lbRTC_Week(goki_time.year, goki_time.month, goki_time.day);
|
||||
goki_time.hour = 1;
|
||||
goki_time.min = 1;
|
||||
goki_time.sec = 1;
|
||||
|
||||
return lbRTC_GetIntervalDays(&goki_time, Common_GetPointer(time.rtc_time));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determines and updates the saved cockroach number for a player.
|
||||
*
|
||||
* The minimum day interval between the current time and the cockroach's
|
||||
* 'last entered time' is 7 days. The amount you get scales linearly,
|
||||
* starting with 1 new cockroach on day 7, 2 new on day 8, ...
|
||||
*
|
||||
* The maximum number of cockroaches is clamped to mCkRh_MAX_NUM which stock
|
||||
* is 10 cockroaches.
|
||||
*
|
||||
* @param player_no The inex of the player whose cockroach data will be updated
|
||||
**/
|
||||
extern void mCkRh_DecideNowGokiFamilyCount(int player_no) {
|
||||
int count;
|
||||
int day_gap;
|
||||
int home_no;
|
||||
int goki_num;
|
||||
|
||||
/* player must live in town */
|
||||
if (player_no < PLAYER_NUM) {
|
||||
day_gap = mCkRh_DaysGapCompareWithSaveTime(player_no);
|
||||
home_no = mHS_get_arrange_idx(player_no) & 3;
|
||||
if (day_gap > mCkRh_INTERVAL_DAYS) {
|
||||
goki_num = Save_Get(homes[home_no].goki.num);
|
||||
count = goki_num > 0 ? day_gap : day_gap - mCkRh_INTERVAL_DAYS;
|
||||
Save_Set(homes[home_no].goki.num, mCkRh_GokiFamilyCount2Good(count + goki_num));
|
||||
}
|
||||
}
|
||||
|
||||
day_gap = mCkRh_DaysGapCompareWithCottageSaveTime();
|
||||
if (day_gap > mCkRh_INTERVAL_DAYS) {
|
||||
u8* goki_num = Save_GetPointer(island.cottage.goki.num);
|
||||
count = (int)*goki_num > 0 ? day_gap : day_gap - mCkRh_INTERVAL_DAYS;
|
||||
*goki_num = mCkRh_GokiFamilyCount2Good(count + (int)*goki_num);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Adds a specific amount of cockroaches to the current player's house.
|
||||
*
|
||||
* @param count The number of cockroaches to add (total clamped to mCkRh_MAX_NUM)
|
||||
* @return TRUE/FALSE cockroach data was updated
|
||||
**/
|
||||
extern int mCkRh_PlussGokiN_NowRoom(int count, int scene_no) {
|
||||
mActor_name_t fieldid = mFI_GetFieldId();
|
||||
|
||||
if (mFI_IS_PLAYER_ROOM(fieldid)) {
|
||||
int player_no = Common_Get(player_no);
|
||||
int house_field_id = mFI_GET_PLAYER_ROOM_NO(fieldid);
|
||||
int home_id = mHS_get_arrange_idx(player_no) & 3;
|
||||
if ((player_no < PLAYER_NUM) && (house_field_id == home_id)) {
|
||||
Save_Set(homes[home_id].goki.num, mCkRh_GokiFamilyCount2Good(count + Save_Get(homes[home_id].goki.num)));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (scene_no == SCENE_ISLAND_COTTAGE) {
|
||||
u8* goki_num = Save_GetPointer(island.cottage.goki.num);
|
||||
*goki_num = mCkRh_GokiFamilyCount2Good(count + *goki_num);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes a specific amount of cockroaches to the current player's house.
|
||||
*
|
||||
* @param count The number of cockroaches to remove (minimum clamped to 0)
|
||||
* @return TRUE/FALSE cockroach data was updated
|
||||
**/
|
||||
extern int mCkRh_MinusGokiN_NowRoom(int count, int scene_id) {
|
||||
mActor_name_t field_id = mFI_GetFieldId();
|
||||
if (mFI_IS_PLAYER_ROOM(field_id)) {
|
||||
int player_no = Common_Get(player_no);
|
||||
int house_field_id = mFI_GET_PLAYER_ROOM_NO(field_id);
|
||||
int home_no = mHS_get_arrange_idx(player_no) & 3;
|
||||
if (player_no < PLAYER_NUM && house_field_id == home_no) {
|
||||
Save_Set(homes[home_no].goki.num, mCkRh_GokiFamilyCount2Good(Save_Get(homes[home_no].goki.num) - count));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (scene_id == SCENE_ISLAND_COTTAGE) {
|
||||
u8* goki_num = Save_GetPointer(island.cottage.goki.num);
|
||||
*goki_num = mCkRh_GokiFamilyCount2Good(*goki_num - count);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the cockroach count for the current scene id.
|
||||
*
|
||||
* @return
|
||||
* - in player house: house cockroach count
|
||||
* - in island octtage: island cottage cockroach count
|
||||
* - elsewhere: 0
|
||||
**/
|
||||
extern int mCkRh_NowSceneGokiFamilyCount() {
|
||||
mActor_name_t fieldid = mFI_GetFieldId();
|
||||
if (mFI_IS_PLAYER_ROOM(fieldid)) {
|
||||
return Save_Get(homes[mFI_GET_PLAYER_ROOM_NO(fieldid)].goki.num);
|
||||
}
|
||||
else if (Save_Get(scene_no) == SCENE_ISLAND_COTTAGE) {
|
||||
return Save_Get(island.cottage.goki.num);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the 'can_look_goki_count' variable to 0.
|
||||
*
|
||||
* This variable controls how many cockroaches are currently
|
||||
* visible to the player in a room.
|
||||
**/
|
||||
extern void mCkRh_InitCanLookGokiCount() {
|
||||
Common_Set(can_look_goki_count, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Changes the 'can_look_goki_count' variable by 'count'.
|
||||
*
|
||||
* 'can_look_goki_count' is clamped between
|
||||
*
|
||||
* @param count The number of visible cockroaches to add/remove
|
||||
* @return TRUE/FALSE were number of visible cockroaches updated?
|
||||
**/
|
||||
extern int mCkRh_CalcCanLookGokiCount(int count) {
|
||||
count += Common_Get(can_look_goki_count);
|
||||
|
||||
if (count < 0) {
|
||||
Common_Set(can_look_goki_count, 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (count > mCkRh_CAN_LOOK_GOKI_NUM) {
|
||||
Common_Set(can_look_goki_count, mCkRh_CAN_LOOK_GOKI_NUM);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Common_Set(can_look_goki_count, count);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the 'can_look_gooki_count' value.
|
||||
*
|
||||
* @return number of cockroaches currently visible to the player
|
||||
**/
|
||||
extern int mCkRh_GetCanLookGokiCount() {
|
||||
return Common_Get(can_look_goki_count);
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
#include "m_police_box.h"
|
||||
|
||||
#include "game.h"
|
||||
#include "m_actor_type.h"
|
||||
#include "libc64/qrand.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_name_table.h"
|
||||
#include "m_field_info.h"
|
||||
#include "m_field_make.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "m_lib.h"
|
||||
#include "m_shop.h"
|
||||
|
||||
/**
|
||||
* @brief Copies an array of items to the lost and found.
|
||||
*
|
||||
* item_buf must have a length of at least mPB_POLICE_BOX_ITEM_STORAGE_COUNT.
|
||||
*
|
||||
* @param item_buf The array of items to copy
|
||||
**/
|
||||
extern void mPB_copy_itemBuf(mActor_name_t* item_buf) {
|
||||
mActor_name_t* keep_item;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
keep_item = Save_Get(police_box.keep_items);
|
||||
count = 0;
|
||||
|
||||
/* copy over the items */
|
||||
for (i = 0; i < mPB_POLICE_BOX_ITEM_STORAGE_COUNT; i++) {
|
||||
if (*item_buf != EMPTY_NO) {
|
||||
*keep_item = *item_buf;
|
||||
count++;
|
||||
keep_item++;
|
||||
}
|
||||
|
||||
item_buf++;
|
||||
}
|
||||
|
||||
/* clear out any unset items if necessary */
|
||||
for (i = count; i < mPB_POLICE_BOX_ITEM_STORAGE_COUNT; i++) {
|
||||
*keep_item++ = EMPTY_NO;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the number of used slots in the lost and found.
|
||||
*
|
||||
* @return count of used slots
|
||||
**/
|
||||
extern int mPB_get_keep_item_sum() {
|
||||
int i;
|
||||
mActor_name_t* keep_item = Save_Get(police_box.keep_items);
|
||||
int sum = 0;
|
||||
|
||||
for (i = 0; i < mPB_POLICE_BOX_ITEM_STORAGE_COUNT; i++) {
|
||||
if (*keep_item != EMPTY_NO) {
|
||||
sum++;
|
||||
}
|
||||
keep_item++;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds an item to the lost and found.
|
||||
*
|
||||
* The item must be of type 'ITEM1' or 'FTR0/FTR1'.
|
||||
* If the lost and found is full, the first item in it
|
||||
* will be deleted and all subsequent items will be shifted
|
||||
* over by one.
|
||||
*
|
||||
* @param item_no The item to add
|
||||
**/
|
||||
extern void mPB_keep_item(mActor_name_t item_no) {
|
||||
if (ITEM_IS_ITEM1(item_no) || ITEM_IS_FTR(item_no)) {
|
||||
int keep_item_sum = mPB_get_keep_item_sum();
|
||||
if (keep_item_sum >= mPB_POLICE_BOX_ITEM_STORAGE_COUNT) {
|
||||
/* delete the first item and move the rest down one slot */
|
||||
mActor_name_t* keep_item = Save_Get(police_box.keep_items);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mPB_POLICE_BOX_ITEM_STORAGE_COUNT - 1; i++) {
|
||||
keep_item[0] = keep_item[1];
|
||||
keep_item++;
|
||||
}
|
||||
|
||||
keep_item_sum = mPB_POLICE_BOX_ITEM_STORAGE_COUNT - 1;
|
||||
}
|
||||
|
||||
Save_Set(police_box.keep_items[keep_item_sum], item_no);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transfers all items of type 'ITEM1' and 'FTR0/FTR1' to the lost and found.
|
||||
*
|
||||
* If the number of items to add exceeds the size of the lost and found,
|
||||
* the items kept will be randomly selected by using rng to overwrite
|
||||
* previously saved items from the acre.
|
||||
*
|
||||
* Additionally, items already in the lost in found will be deleted to
|
||||
* make space for the new items if necessary.
|
||||
*
|
||||
* @param blk_x The x acre (column)
|
||||
* @param blk_z The z acre (row)
|
||||
**/
|
||||
extern void mPB_keep_all_item_in_block(int blk_x, int blk_z) {
|
||||
int count;
|
||||
mActor_name_t new_items[mPB_POLICE_BOX_ITEM_STORAGE_COUNT];
|
||||
int keep_item_sum;
|
||||
mActor_name_t item;
|
||||
mActor_name_t* block_items;
|
||||
int i;
|
||||
|
||||
keep_item_sum = mPB_get_keep_item_sum();
|
||||
block_items = mFI_BkNumtoUtFGTop(blk_x, blk_z);
|
||||
count = 0;
|
||||
|
||||
bzero(new_items, mPB_POLICE_BOX_ITEM_STORAGE_COUNT * sizeof(mActor_name_t));
|
||||
|
||||
for (i = 0; i < UT_X_NUM * UT_Z_NUM; i++) {
|
||||
int item_type;
|
||||
item = *block_items;
|
||||
|
||||
/* only accept items in the 0x1XXX, 2XXX, and 3XXX range */
|
||||
item_type = ITEM_NAME_GET_TYPE(item);
|
||||
if (item_type == NAME_TYPE_FTR0 || item_type == NAME_TYPE_ITEM1 || item_type == NAME_TYPE_FTR1) {
|
||||
if (count < mPB_POLICE_BOX_ITEM_STORAGE_COUNT) {
|
||||
/* space is still available, so directly add it */
|
||||
new_items[count++] = item;
|
||||
}
|
||||
else {
|
||||
/* randomly overwrite one of the items in the lost and found */
|
||||
new_items[(int)(fqrand() * mPB_POLICE_BOX_ITEM_STORAGE_COUNT)] = item;
|
||||
}
|
||||
|
||||
*block_items = EMPTY_NO;
|
||||
}
|
||||
block_items++;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
int total_sum = count + keep_item_sum;
|
||||
|
||||
if (total_sum <= mPB_POLICE_BOX_ITEM_STORAGE_COUNT) {
|
||||
mem_copy((u8*)(Save_Get(police_box.keep_items) + keep_item_sum), (u8*)new_items, count * sizeof(mActor_name_t));
|
||||
}
|
||||
else {
|
||||
mActor_name_t* dst = Save_Get(police_box.keep_items);
|
||||
int save_count = total_sum - mPB_POLICE_BOX_ITEM_STORAGE_COUNT;
|
||||
int keep_sum = keep_item_sum - save_count;
|
||||
|
||||
/* move over saved items already in lost and found */
|
||||
for (i = 0; i < keep_sum; i++) {
|
||||
dst[i] = dst[i + save_count];
|
||||
}
|
||||
|
||||
/* copy newly added items */
|
||||
mem_copy((u8*)(Save_Get(police_box.keep_items) + keep_sum), (u8*)new_items, count * sizeof(mActor_name_t));
|
||||
}
|
||||
}
|
||||
|
||||
/* clear buried item flags in the cleared acre */
|
||||
mFI_ClearDeposit(blk_x, blk_z);
|
||||
}
|
||||
|
||||
/* select random item function definition */
|
||||
typedef mActor_name_t (*mPB_get_force_set_proc)();
|
||||
|
||||
/**
|
||||
* @brief Selects a random 'goods' item to add to the lost and found/
|
||||
*
|
||||
* @return The randomly selected item
|
||||
**/
|
||||
static mActor_name_t mPB_get_force_set_item_goods() {
|
||||
static int category_table[mSP_KIND_MAX] = {
|
||||
mSP_KIND_FURNITURE,
|
||||
mSP_KIND_PAPER,
|
||||
mSP_KIND_CLOTH,
|
||||
mSP_KIND_CARPET,
|
||||
mSP_KIND_WALLPAPER
|
||||
};
|
||||
|
||||
static int prob_table[mSP_KIND_MAX] = {
|
||||
35, /* furniture 0-35 (36%) */
|
||||
58, /* stationery 36-58 (23%) */
|
||||
88, /* clothing 59-88 (30%) */
|
||||
94, /* carpets 89-94 (6%) */
|
||||
100 /* wallpaper 95-99 (5%) (fqrand is [min, max) so 100 is not possible) */
|
||||
};
|
||||
|
||||
|
||||
int category = mSP_KIND_MAX;
|
||||
mActor_name_t item = EMPTY_NO;
|
||||
int roll = (int)(fqrand() * 100.0f);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mSP_KIND_MAX; i++) {
|
||||
if (roll <= prob_table[i]) {
|
||||
category = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mSP_SelectRandomItem_New(NULL, &item, 1, NULL, 0, category_table[category], mSP_LISTTYPE_COMMON, FALSE);
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects a random tool or sapling to add to the lost and found.
|
||||
*
|
||||
* @return The randomly selected item
|
||||
**/
|
||||
static mActor_name_t mPB_get_force_set_item_item() {
|
||||
static mActor_name_t category_table[6] = {
|
||||
ITM_NET, ITM_AXE, ITM_SHOVEL, ITM_ROD, ITM_SAPLING, ITM_CEDAR_SAPLING
|
||||
};
|
||||
|
||||
return category_table[(int)(fqrand() * 6.0f)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects a random flower bag to add to the lost and found.
|
||||
*
|
||||
* @return The randomly selected flower bag
|
||||
**/
|
||||
static mActor_name_t mPB_get_force_set_item_flower() {
|
||||
return ITM_WHITE_PANSY_BAG + (int)(fqrand() * 8.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects a random umbrella to add to the lost and found.
|
||||
*
|
||||
* @return The randomly selected umbrella
|
||||
**/
|
||||
static mActor_name_t mPB_get_force_set_item_umbrella() {
|
||||
mActor_name_t umbrella;
|
||||
mSP_RandomUmbSelect(&umbrella, 1);
|
||||
|
||||
return umbrella;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects a random item from a random category to add to the lost and found.
|
||||
*
|
||||
* @return The randomly selected item
|
||||
**/
|
||||
static mActor_name_t mPB_get_force_set_item() {
|
||||
static mPB_get_force_set_proc force_proc[mPB_CATEGORY_NUM] = {
|
||||
&mPB_get_force_set_item_goods,
|
||||
&mPB_get_force_set_item_item,
|
||||
&mPB_get_force_set_item_flower,
|
||||
&mPB_get_force_set_item_umbrella
|
||||
};
|
||||
|
||||
static int prob_table[mPB_CATEGORY_NUM] = {
|
||||
85, /* 0-85 (86%) 'goods' */
|
||||
90, /* 86-90 (5%) 'item' */
|
||||
95, /* 91-95 (5%) 'flower' */
|
||||
100 /* 96-100 (4%) 'umbrella' (again, fqrand is [min, max) therefore 100 is never possible) */
|
||||
};
|
||||
|
||||
int proc = mPB_CATEGORY_NUM;
|
||||
int roll = (int)(fqrand() * 100.0f);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mPB_CATEGORY_NUM; i++) {
|
||||
if (roll <= prob_table[i]) {
|
||||
proc = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (*force_proc[proc])();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a random item to the lost and found if grow space is available.
|
||||
**/
|
||||
extern void mPB_force_set_keep_item() {
|
||||
/* if lost and found item count is less-than-equal-to max grow size & 50-50 roll */
|
||||
if (mPB_get_keep_item_sum() <= mPB_MAX_GROW_SIZE && (int)qrand() >= 0) {
|
||||
mPB_keep_item(mPB_get_force_set_item());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the police station lost and found.
|
||||
*
|
||||
* The lost and found will always start with one random common
|
||||
* priority list furniture and two random common priority list
|
||||
* shirts.
|
||||
*
|
||||
* @param game The GAME pointer to pass to mSP_SelectRandomItem_New, goes unused
|
||||
**/
|
||||
extern void mPB_police_box_init(GAME* game) {
|
||||
mActor_name_t* keep_items = Save_Get(police_box.keep_items);
|
||||
int i;
|
||||
|
||||
/* generate one random ABC prio furniture and two random ABC prio shirts */
|
||||
mSP_SelectRandomItem_New(game, keep_items + 0, 1, NULL, 0, mSP_KIND_FURNITURE, mSP_LISTTYPE_ABC, FALSE);
|
||||
mSP_SelectRandomItem_New(game, keep_items + 1, 2, NULL, 0, mSP_KIND_CLOTH, mSP_LISTTYPE_ABC, FALSE);
|
||||
|
||||
/* clear the rest of the lost and found */
|
||||
keep_items += 3;
|
||||
for (i = 0; i < mPB_POLICE_BOX_ITEM_STORAGE_COUNT - 3; i++) {
|
||||
*keep_items++ = EMPTY_NO;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user