From 60a426c0742b3e7d8c5b557c7578df6eeeea377b Mon Sep 17 00:00:00 2001 From: brianluau Date: Wed, 5 Dec 2012 02:53:33 +0000 Subject: - Undid r16968: SVN Replaced with source:/trunk/src/@16966 (tid:74924). [16969:16991/trunk/src/] will be re-committed in the next 24 hours. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16992 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/searchstore.c | 593 ++++++++++++++++++++++++++------------------------ 1 file changed, 305 insertions(+), 288 deletions(-) (limited to 'src/map/searchstore.c') diff --git a/src/map/searchstore.c b/src/map/searchstore.c index 041376260..c59c13bed 100644 --- a/src/map/searchstore.c +++ b/src/map/searchstore.c @@ -12,377 +12,394 @@ /// failure constants for clif functions -enum e_searchstore_failure { - SSI_FAILED_NOTHING_SEARCH_ITEM = 0, // "No matching stores were found." - SSI_FAILED_OVER_MAXCOUNT = 1, // "There are too many results. Please enter more detailed search term." - SSI_FAILED_SEARCH_CNT = 2, // "You cannot search anymore." - SSI_FAILED_LIMIT_SEARCH_TIME = 3, // "You cannot search yet." - SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE = 4, // "No sale (purchase) information available." +enum e_searchstore_failure +{ + SSI_FAILED_NOTHING_SEARCH_ITEM = 0, // "No matching stores were found." + SSI_FAILED_OVER_MAXCOUNT = 1, // "There are too many results. Please enter more detailed search term." + SSI_FAILED_SEARCH_CNT = 2, // "You cannot search anymore." + SSI_FAILED_LIMIT_SEARCH_TIME = 3, // "You cannot search yet." + SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE = 4, // "No sale (purchase) information available." }; -enum e_searchstore_searchtype { - SEARCHTYPE_VENDING = 0, - SEARCHTYPE_BUYING_STORE = 1, +enum e_searchstore_searchtype +{ + SEARCHTYPE_VENDING = 0, + SEARCHTYPE_BUYING_STORE = 1, }; -enum e_searchstore_effecttype { - EFFECTTYPE_NORMAL = 0, - EFFECTTYPE_CASH = 1, - EFFECTTYPE_MAX +enum e_searchstore_effecttype +{ + EFFECTTYPE_NORMAL = 0, + EFFECTTYPE_CASH = 1, + EFFECTTYPE_MAX }; /// type for shop search function -typedef bool (*searchstore_search_t)(struct map_session_data *sd, unsigned short nameid); -typedef bool (*searchstore_searchall_t)(struct map_session_data *sd, const struct s_search_store_search *s); +typedef bool (*searchstore_search_t)(struct map_session_data* sd, unsigned short nameid); +typedef bool (*searchstore_searchall_t)(struct map_session_data* sd, const struct s_search_store_search* s); /// retrieves search function by type static searchstore_search_t searchstore_getsearchfunc(unsigned char type) { - switch (type) { - case SEARCHTYPE_VENDING: - return &vending_search; - case SEARCHTYPE_BUYING_STORE: - return &buyingstore_search; - } - return NULL; + switch( type ) + { + case SEARCHTYPE_VENDING: return &vending_search; + case SEARCHTYPE_BUYING_STORE: return &buyingstore_search; + } + return NULL; } /// retrieves search-all function by type static searchstore_searchall_t searchstore_getsearchallfunc(unsigned char type) { - switch (type) { - case SEARCHTYPE_VENDING: - return &vending_searchall; - case SEARCHTYPE_BUYING_STORE: - return &buyingstore_searchall; - } - return NULL; + switch( type ) + { + case SEARCHTYPE_VENDING: return &vending_searchall; + case SEARCHTYPE_BUYING_STORE: return &buyingstore_searchall; + } + return NULL; } /// checks if the player has a store by type -static bool searchstore_hasstore(struct map_session_data *sd, unsigned char type) +static bool searchstore_hasstore(struct map_session_data* sd, unsigned char type) { - switch (type) { - case SEARCHTYPE_VENDING: - return sd->state.vending; - case SEARCHTYPE_BUYING_STORE: - return sd->state.buyingstore; - } - return false; + switch( type ) + { + case SEARCHTYPE_VENDING: return sd->state.vending; + case SEARCHTYPE_BUYING_STORE: return sd->state.buyingstore; + } + return false; } /// returns player's store id by type -static int searchstore_getstoreid(struct map_session_data *sd, unsigned char type) +static int searchstore_getstoreid(struct map_session_data* sd, unsigned char type) { - switch (type) { - case SEARCHTYPE_VENDING: - return sd->vender_id; - case SEARCHTYPE_BUYING_STORE: - return sd->buyer_id; - } - return 0; + switch( type ) + { + case SEARCHTYPE_VENDING: return sd->vender_id; + case SEARCHTYPE_BUYING_STORE: return sd->buyer_id; + } + return 0; } -bool searchstore_open(struct map_session_data *sd, unsigned int uses, unsigned short effect) +bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned short effect) { - if (!battle_config.feature_search_stores || sd->searchstore.open) { - return false; - } + if( !battle_config.feature_search_stores || sd->searchstore.open ) + { + return false; + } - if (!uses || effect >= EFFECTTYPE_MAX) { - // invalid input - return false; - } + if( !uses || effect >= EFFECTTYPE_MAX ) + {// invalid input + return false; + } - sd->searchstore.open = true; - sd->searchstore.uses = uses; - sd->searchstore.effect = effect; + sd->searchstore.open = true; + sd->searchstore.uses = uses; + sd->searchstore.effect = effect; - clif_open_search_store_info(sd); + clif_open_search_store_info(sd); - return true; + return true; } -void searchstore_query(struct map_session_data *sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short *itemlist, unsigned int item_count, const unsigned short *cardlist, unsigned int card_count) +void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count) { - unsigned int i; - struct map_session_data *pl_sd; - struct s_mapiterator *iter; - struct s_search_store_search s; - searchstore_searchall_t store_searchall; - time_t querytime; - - if (!battle_config.feature_search_stores) { - return; - } - - if (!sd->searchstore.open) { - return; - } - - if ((store_searchall = searchstore_getsearchallfunc(type)) == NULL) { - ShowError("searchstore_query: Unknown search type %u (account_id=%d).\n", (unsigned int)type, sd->bl.id); - return; - } - - time(&querytime); - - if (sd->searchstore.nextquerytime > querytime) { - clif_search_store_info_failed(sd, SSI_FAILED_LIMIT_SEARCH_TIME); - return; - } - - if (!sd->searchstore.uses) { - clif_search_store_info_failed(sd, SSI_FAILED_SEARCH_CNT); - return; - } - - // validate lists - for (i = 0; i < item_count; i++) { - if (!itemdb_exists(itemlist[i])) { - ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i]); - clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM); - return; - } - } - for (i = 0; i < card_count; i++) { - if (!itemdb_exists(cardlist[i])) { - ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i]); - clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM); - return; - } - } - - if (max_price < min_price) { - swap(min_price, max_price); - } - - sd->searchstore.uses--; - sd->searchstore.type = type; - sd->searchstore.nextquerytime = querytime+battle_config.searchstore_querydelay; - - // drop previous results - searchstore_clear(sd); - - // allocate max. amount of results - sd->searchstore.items = (struct s_search_store_info_item *)aMalloc(sizeof(struct s_search_store_info_item)*battle_config.searchstore_maxresults); - - // search - s.search_sd = sd; - s.itemlist = itemlist; - s.cardlist = cardlist; - s.item_count = item_count; - s.card_count = card_count; - s.min_price = min_price; - s.max_price = max_price; - iter = mapit_geteachpc(); - - for (pl_sd = (struct map_session_data *)mapit_first(iter); mapit_exists(iter); pl_sd = (struct map_session_data *)mapit_next(iter)) { - if (sd == pl_sd) { - // skip own shop, if any - continue; - } - - if (!store_searchall(pl_sd, &s)) { - // exceeded result size - clif_search_store_info_failed(sd, SSI_FAILED_OVER_MAXCOUNT); - break; - } - } - - mapit_free(iter); - - if (sd->searchstore.count) { - // reclaim unused memory - sd->searchstore.items = (struct s_search_store_info_item *)aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count); - - // present results - clif_search_store_info_ack(sd); - - // one page displayed - sd->searchstore.pages++; - } else { - // cleanup - searchstore_clear(sd); - - // update uses - clif_search_store_info_ack(sd); - - // notify of failure - clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM); - } + unsigned int i; + struct map_session_data* pl_sd; + struct s_mapiterator* iter; + struct s_search_store_search s; + searchstore_searchall_t store_searchall; + time_t querytime; + + if( !battle_config.feature_search_stores ) + { + return; + } + + if( !sd->searchstore.open ) + { + return; + } + + if( ( store_searchall = searchstore_getsearchallfunc(type) ) == NULL ) + { + ShowError("searchstore_query: Unknown search type %u (account_id=%d).\n", (unsigned int)type, sd->bl.id); + return; + } + + time(&querytime); + + if( sd->searchstore.nextquerytime > querytime ) + { + clif_search_store_info_failed(sd, SSI_FAILED_LIMIT_SEARCH_TIME); + return; + } + + if( !sd->searchstore.uses ) + { + clif_search_store_info_failed(sd, SSI_FAILED_SEARCH_CNT); + return; + } + + // validate lists + for( i = 0; i < item_count; i++ ) + { + if( !itemdb_exists(itemlist[i]) ) + { + ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i]); + clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM); + return; + } + } + for( i = 0; i < card_count; i++ ) + { + if( !itemdb_exists(cardlist[i]) ) + { + ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i]); + clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM); + return; + } + } + + if( max_price < min_price ) + { + swap(min_price, max_price); + } + + sd->searchstore.uses--; + sd->searchstore.type = type; + sd->searchstore.nextquerytime = querytime+battle_config.searchstore_querydelay; + + // drop previous results + searchstore_clear(sd); + + // allocate max. amount of results + sd->searchstore.items = (struct s_search_store_info_item*)aMalloc(sizeof(struct s_search_store_info_item)*battle_config.searchstore_maxresults); + + // search + s.search_sd = sd; + s.itemlist = itemlist; + s.cardlist = cardlist; + s.item_count = item_count; + s.card_count = card_count; + s.min_price = min_price; + s.max_price = max_price; + iter = mapit_geteachpc(); + + for( pl_sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); pl_sd = (struct map_session_data*)mapit_next(iter) ) + { + if( sd == pl_sd ) + {// skip own shop, if any + continue; + } + + if( !store_searchall(pl_sd, &s) ) + {// exceeded result size + clif_search_store_info_failed(sd, SSI_FAILED_OVER_MAXCOUNT); + break; + } + } + + mapit_free(iter); + + if( sd->searchstore.count ) + { + // reclaim unused memory + sd->searchstore.items = (struct s_search_store_info_item*)aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count); + + // present results + clif_search_store_info_ack(sd); + + // one page displayed + sd->searchstore.pages++; + } + else + { + // cleanup + searchstore_clear(sd); + + // update uses + clif_search_store_info_ack(sd); + + // notify of failure + clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM); + } } /// checks whether or not more results are available for the client -bool searchstore_querynext(struct map_session_data *sd) +bool searchstore_querynext(struct map_session_data* sd) { - if (sd->searchstore.count && (sd->searchstore.count-1)/SEARCHSTORE_RESULTS_PER_PAGE < sd->searchstore.pages) { - return true; - } + if( sd->searchstore.count && ( sd->searchstore.count-1 )/SEARCHSTORE_RESULTS_PER_PAGE < sd->searchstore.pages ) + { + return true; + } - return false; + return false; } -void searchstore_next(struct map_session_data *sd) +void searchstore_next(struct map_session_data* sd) { - if (!battle_config.feature_search_stores || !sd->searchstore.open || sd->searchstore.count <= sd->searchstore.pages*SEARCHSTORE_RESULTS_PER_PAGE) { - // nothing (more) to display - return; - } + if( !battle_config.feature_search_stores || !sd->searchstore.open || sd->searchstore.count <= sd->searchstore.pages*SEARCHSTORE_RESULTS_PER_PAGE ) + {// nothing (more) to display + return; + } - // present results - clif_search_store_info_ack(sd); + // present results + clif_search_store_info_ack(sd); - // one more page displayed - sd->searchstore.pages++; + // one more page displayed + sd->searchstore.pages++; } -void searchstore_clear(struct map_session_data *sd) +void searchstore_clear(struct map_session_data* sd) { - searchstore_clearremote(sd); + searchstore_clearremote(sd); - if (sd->searchstore.items) { - // release results - aFree(sd->searchstore.items); - sd->searchstore.items = NULL; - } + if( sd->searchstore.items ) + {// release results + aFree(sd->searchstore.items); + sd->searchstore.items = NULL; + } - sd->searchstore.count = 0; - sd->searchstore.pages = 0; + sd->searchstore.count = 0; + sd->searchstore.pages = 0; } -void searchstore_close(struct map_session_data *sd) +void searchstore_close(struct map_session_data* sd) { - if (sd->searchstore.open) { - searchstore_clear(sd); + if( sd->searchstore.open ) + { + searchstore_clear(sd); - sd->searchstore.uses = 0; - sd->searchstore.open = false; - } + sd->searchstore.uses = 0; + sd->searchstore.open = false; + } } -void searchstore_click(struct map_session_data *sd, int account_id, int store_id, unsigned short nameid) +void searchstore_click(struct map_session_data* sd, int account_id, int store_id, unsigned short nameid) { - unsigned int i; - struct map_session_data *pl_sd; - searchstore_search_t store_search; - - if (!battle_config.feature_search_stores || !sd->searchstore.open || !sd->searchstore.count) { - return; - } - - searchstore_clearremote(sd); - - ARR_FIND(0, sd->searchstore.count, i, sd->searchstore.items[i].store_id == store_id && sd->searchstore.items[i].account_id == account_id && sd->searchstore.items[i].nameid == nameid); - if (i == sd->searchstore.count) { - // no such result, crafted - ShowWarning("searchstore_click: Received request with item %hu of account %d, which is not part of current result set (account_id=%d, char_id=%d).\n", nameid, account_id, sd->bl.id, sd->status.char_id); - clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE); - return; - } - - if ((pl_sd = map_id2sd(account_id)) == NULL) { - // no longer online - clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE); - return; - } - - if (!searchstore_hasstore(pl_sd, sd->searchstore.type) || searchstore_getstoreid(pl_sd, sd->searchstore.type) != store_id) { - // no longer vending/buying or not same shop - clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE); - return; - } - - store_search = searchstore_getsearchfunc(sd->searchstore.type); - - if (!store_search(pl_sd, nameid)) { - // item no longer being sold/bought - clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE); - return; - } - - switch (sd->searchstore.effect) { - case EFFECTTYPE_NORMAL: - // display coords - - if (sd->bl.m != pl_sd->bl.m) { - // not on same map, wipe previous marker - clif_search_store_info_click_ack(sd, -1, -1); - } else { - clif_search_store_info_click_ack(sd, pl_sd->bl.x, pl_sd->bl.y); - } - - break; - case EFFECTTYPE_CASH: - // open remotely - - // to bypass range checks - sd->searchstore.remote_id = account_id; - - switch (sd->searchstore.type) { - case SEARCHTYPE_VENDING: - vending_vendinglistreq(sd, account_id); - break; - case SEARCHTYPE_BUYING_STORE: - buyingstore_open(sd, account_id); - break; - } - - break; - default: - // unknown - ShowError("searchstore_click: Unknown search store effect %u (account_id=%d).\n", (unsigned int)sd->searchstore.effect, sd->bl.id); - } + unsigned int i; + struct map_session_data* pl_sd; + searchstore_search_t store_search; + + if( !battle_config.feature_search_stores || !sd->searchstore.open || !sd->searchstore.count ) + { + return; + } + + searchstore_clearremote(sd); + + ARR_FIND( 0, sd->searchstore.count, i, sd->searchstore.items[i].store_id == store_id && sd->searchstore.items[i].account_id == account_id && sd->searchstore.items[i].nameid == nameid ); + if( i == sd->searchstore.count ) + {// no such result, crafted + ShowWarning("searchstore_click: Received request with item %hu of account %d, which is not part of current result set (account_id=%d, char_id=%d).\n", nameid, account_id, sd->bl.id, sd->status.char_id); + clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE); + return; + } + + if( ( pl_sd = map_id2sd(account_id) ) == NULL ) + {// no longer online + clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE); + return; + } + + if( !searchstore_hasstore(pl_sd, sd->searchstore.type) || searchstore_getstoreid(pl_sd, sd->searchstore.type) != store_id ) + {// no longer vending/buying or not same shop + clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE); + return; + } + + store_search = searchstore_getsearchfunc(sd->searchstore.type); + + if( !store_search(pl_sd, nameid) ) + {// item no longer being sold/bought + clif_search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE); + return; + } + + switch( sd->searchstore.effect ) + { + case EFFECTTYPE_NORMAL: + // display coords + + if( sd->bl.m != pl_sd->bl.m ) + {// not on same map, wipe previous marker + clif_search_store_info_click_ack(sd, -1, -1); + } + else + { + clif_search_store_info_click_ack(sd, pl_sd->bl.x, pl_sd->bl.y); + } + + break; + case EFFECTTYPE_CASH: + // open remotely + + // to bypass range checks + sd->searchstore.remote_id = account_id; + + switch( sd->searchstore.type ) + { + case SEARCHTYPE_VENDING: vending_vendinglistreq(sd, account_id); break; + case SEARCHTYPE_BUYING_STORE: buyingstore_open(sd, account_id); break; + } + + break; + default: + // unknown + ShowError("searchstore_click: Unknown search store effect %u (account_id=%d).\n", (unsigned int)sd->searchstore.effect, sd->bl.id); + } } /// checks whether or not sd has opened account_id's shop remotely -bool searchstore_queryremote(struct map_session_data *sd, int account_id) +bool searchstore_queryremote(struct map_session_data* sd, int account_id) { - return (bool)(sd->searchstore.open && sd->searchstore.count && sd->searchstore.remote_id == account_id); + return (bool)( sd->searchstore.open && sd->searchstore.count && sd->searchstore.remote_id == account_id ); } /// removes range-check bypassing for remotely opened stores -void searchstore_clearremote(struct map_session_data *sd) +void searchstore_clearremote(struct map_session_data* sd) { - sd->searchstore.remote_id = 0; + sd->searchstore.remote_id = 0; } /// receives results from a store-specific callback -bool searchstore_result(struct map_session_data *sd, int store_id, int account_id, const char *store_name, unsigned short nameid, unsigned short amount, unsigned int price, const short *card, unsigned char refine) +bool searchstore_result(struct map_session_data* sd, int store_id, int account_id, const char* store_name, unsigned short nameid, unsigned short amount, unsigned int price, const short* card, unsigned char refine) { - struct s_search_store_info_item *ssitem; - - if (sd->searchstore.count >= (unsigned int)battle_config.searchstore_maxresults) { - // no more - return false; - } - - ssitem = &sd->searchstore.items[sd->searchstore.count++]; - ssitem->store_id = store_id; - ssitem->account_id = account_id; - safestrncpy(ssitem->store_name, store_name, sizeof(ssitem->store_name)); - ssitem->nameid = nameid; - ssitem->amount = amount; - ssitem->price = price; - memcpy(ssitem->card, card, sizeof(ssitem->card)); - ssitem->refine = refine; - - return true; + struct s_search_store_info_item* ssitem; + + if( sd->searchstore.count >= (unsigned int)battle_config.searchstore_maxresults ) + {// no more + return false; + } + + ssitem = &sd->searchstore.items[sd->searchstore.count++]; + ssitem->store_id = store_id; + ssitem->account_id = account_id; + safestrncpy(ssitem->store_name, store_name, sizeof(ssitem->store_name)); + ssitem->nameid = nameid; + ssitem->amount = amount; + ssitem->price = price; + memcpy(ssitem->card, card, sizeof(ssitem->card)); + ssitem->refine = refine; + + return true; } -- cgit v1.2.3-60-g2f50