summaryrefslogtreecommitdiff
path: root/src/map/searchstore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/searchstore.c')
-rw-r--r--src/map/searchstore.c593
1 files changed, 288 insertions, 305 deletions
diff --git a/src/map/searchstore.c b/src/map/searchstore.c
index c59c13bed..041376260 100644
--- a/src/map/searchstore.c
+++ b/src/map/searchstore.c
@@ -12,394 +12,377 @@
/// 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;
}