summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2013-09-28 18:15:23 +0200
committerHaru <haru@dotalux.com>2013-09-29 01:45:34 +0200
commit5697031dce0f02a55044504077775b909a42982d (patch)
treeaef805d4d5f4eb9bc4da0282e84322369c26ed3b
parentfe624087b2495fb258afd9177c6299139a1f914d (diff)
downloadhercules-5697031dce0f02a55044504077775b909a42982d.tar.gz
hercules-5697031dce0f02a55044504077775b909a42982d.tar.bz2
hercules-5697031dce0f02a55044504077775b909a42982d.tar.xz
hercules-5697031dce0f02a55044504077775b909a42982d.zip
Provided argument-list equivalent for several variadic functions
This is necessary for the upcoming HPM hooking system
-rw-r--r--src/char/inter.c101
-rw-r--r--src/char/inter.h1
-rw-r--r--src/common/db.c18
-rw-r--r--src/common/db.h13
-rw-r--r--src/map/map.c474
-rw-r--r--src/map/map.h15
-rw-r--r--src/map/party.c34
-rw-r--r--src/map/party.h1
8 files changed, 509 insertions, 148 deletions
diff --git a/src/char/inter.c b/src/char/inter.c
index 353d3e009..2dc15933b 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -414,16 +414,19 @@ const char* geoip_getcountry(uint32 ipnum){
}
return geoip_countryname[0];
}
-/* sends a mesasge to map server (fd) to a user (u_fd) although we use fd we keep aid for safe-check */
-/* extremely handy I believe it will serve other uses in the near future */
-void inter_to_fd(int fd, int u_fd, int aid, char* msg, ...) {
+
+/**
+ * Argument-list version of inter_msg_to_fd
+ * @see inter_msg_to_fd
+ */
+void inter_vmsg_to_fd(int fd, int u_fd, int aid, char* msg, va_list ap) {
char msg_out[512];
- va_list ap;
+ va_list apcopy;
int len = 1;/* yes we start at 1 */
- va_start(ap,msg);
- len += vsnprintf(msg_out, 512, msg, ap);
- va_end(ap);
+ va_copy(apcopy, ap);
+ len += vsnprintf(msg_out, 512, msg, apcopy);
+ va_end(apcopy);
WFIFOHEAD(fd,12 + len);
@@ -437,6 +440,23 @@ void inter_to_fd(int fd, int u_fd, int aid, char* msg, ...) {
return;
}
+
+/**
+ * Sends a message to map server (fd) to a user (u_fd) although we use fd we
+ * keep aid for safe-check.
+ * @param fd Mapserver's fd
+ * @param u_fd Recipient's fd
+ * @param aid Recipient's expected for sanity checks on the mapserver
+ * @param msg Message format string
+ * @param ... Additional parameters for (v)sprinf
+ */
+void inter_msg_to_fd(int fd, int u_fd, int aid, char* msg, ...) {
+ va_list ap;
+ va_start(ap,msg);
+ inter_vmsg_to_fd(fd, u_fd, aid, msg, ap);
+ va_end(ap);
+}
+
/* [Dekamaster/Nightroad] */
void mapif_parse_accinfo(int fd) {
int u_fd = RFIFOL(fd,2), aid = RFIFOL(fd,6), castergroup = RFIFOL(fd,10);
@@ -454,10 +474,10 @@ void mapif_parse_accinfo(int fd) {
if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `%s` WHERE `name` LIKE '%s' LIMIT 10", char_db, query_esq)
|| SQL->NumRows(sql_handle) == 0 ) {
if( SQL->NumRows(sql_handle) == 0 ) {
- inter_to_fd(fd, u_fd, aid, "No matches were found for your criteria, '%s'",query);
+ inter_msg_to_fd(fd, u_fd, aid, "No matches were found for your criteria, '%s'",query);
} else {
Sql_ShowDebug(sql_handle);
- inter_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it.");
+ inter_msg_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it.");
}
SQL->FreeResult(sql_handle);
return;
@@ -467,7 +487,7 @@ void mapif_parse_accinfo(int fd) {
SQL->GetData(sql_handle, 0, &data, NULL); account_id = atoi(data);
SQL->FreeResult(sql_handle);
} else {// more than one, listing... [Dekamaster/Nightroad]
- inter_to_fd(fd, u_fd, aid, "Your query returned the following %d results, please be more specific...",(int)SQL->NumRows(sql_handle));
+ inter_msg_to_fd(fd, u_fd, aid, "Your query returned the following %d results, please be more specific...",(int)SQL->NumRows(sql_handle));
while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) {
int class_;
short base_level, job_level, online;
@@ -480,7 +500,7 @@ void mapif_parse_accinfo(int fd) {
SQL->GetData(sql_handle, 4, &data, NULL); job_level = atoi(data);
SQL->GetData(sql_handle, 5, &data, NULL); online = atoi(data);
- inter_to_fd(fd, u_fd, aid, "[AID: %d] %s | %s | Level: %d/%d | %s", account_id, name, job_name(class_), base_level, job_level, online?"Online":"Offline");
+ inter_msg_to_fd(fd, u_fd, aid, "[AID: %d] %s | %s | Level: %d/%d | %s", account_id, name, job_name(class_), base_level, job_level, online?"Online":"Offline");
}
SQL->FreeResult(sql_handle);
return;
@@ -497,9 +517,9 @@ void mapif_parse_accinfo(int fd) {
if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `userid`, `user_pass`, `email`, `last_ip`, `group_id`, `lastlogin`, `logincount`, `state`,`pincode`,`birthdate` FROM `login` WHERE `account_id` = '%d' LIMIT 1", account_id)
|| SQL->NumRows(sql_handle) == 0 ) {
if( SQL->NumRows(sql_handle) == 0 ) {
- inter_to_fd(fd, u_fd, aid, "No account with ID '%d' was found.", account_id );
+ inter_msg_to_fd(fd, u_fd, aid, "No account with ID '%d' was found.", account_id );
} else {
- inter_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it.");
+ inter_msg_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it.");
Sql_ShowDebug(sql_handle);
}
} else {
@@ -521,29 +541,29 @@ void mapif_parse_accinfo(int fd) {
if (level == -1)
return;
- inter_to_fd(fd, u_fd, aid, "-- Account %d --", account_id );
- inter_to_fd(fd, u_fd, aid, "User: %s | GM Group: %d | State: %d", userid, level, state );
+ inter_msg_to_fd(fd, u_fd, aid, "-- Account %d --", account_id );
+ inter_msg_to_fd(fd, u_fd, aid, "User: %s | GM Group: %d | State: %d", userid, level, state );
if (level < castergroup) { /* only show pass if your gm level is greater than the one you're searching for */
if( strlen(pin_code) )
- inter_to_fd(fd, u_fd, aid, "Password: %s (PIN:%s)", user_pass, pin_code );
+ inter_msg_to_fd(fd, u_fd, aid, "Password: %s (PIN:%s)", user_pass, pin_code );
else
- inter_to_fd(fd, u_fd, aid, "Password: %s", user_pass );
+ inter_msg_to_fd(fd, u_fd, aid, "Password: %s", user_pass );
}
- inter_to_fd(fd, u_fd, aid, "Account e-mail: %s | Birthdate: %s", email, birthdate);
- inter_to_fd(fd, u_fd, aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip)) );
- inter_to_fd(fd, u_fd, aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin );
- inter_to_fd(fd, u_fd, aid, "-- Character Details --" );
+ inter_msg_to_fd(fd, u_fd, aid, "Account e-mail: %s | Birthdate: %s", email, birthdate);
+ inter_msg_to_fd(fd, u_fd, aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip)) );
+ inter_msg_to_fd(fd, u_fd, aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin );
+ inter_msg_to_fd(fd, u_fd, aid, "-- Character Details --" );
if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` FROM `%s` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", char_db, account_id, MAX_CHARS)
|| SQL->NumRows(sql_handle) == 0 ) {
if( SQL->NumRows(sql_handle) == 0 )
- inter_to_fd(fd, u_fd, aid,"This account doesn't have characters.");
+ inter_msg_to_fd(fd, u_fd, aid,"This account doesn't have characters.");
else {
- inter_to_fd(fd, u_fd, aid,"An error occured, bother your admin about it.");
+ inter_msg_to_fd(fd, u_fd, aid,"An error occured, bother your admin about it.");
Sql_ShowDebug(sql_handle);
}
@@ -561,7 +581,7 @@ void mapif_parse_accinfo(int fd) {
SQL->GetData(sql_handle, 5, &data, NULL); job_level = atoi(data);
SQL->GetData(sql_handle, 6, &data, NULL); online = atoi(data);
- inter_to_fd(fd, u_fd, aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off");
+ inter_msg_to_fd(fd, u_fd, aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off");
}
}
SQL->FreeResult(sql_handle);
@@ -743,16 +763,18 @@ static int inter_config_read(const char* cfgName)
return 0;
}
-// Save interlog into sql
-int inter_log(char* fmt, ...)
-{
+/**
+ * Save interlog into sql (arglist version)
+ * @see inter_log
+ */
+int inter_vlog(char* fmt, va_list ap) {
char str[255];
char esc_str[sizeof(str)*2+1];// escaped str
- va_list ap;
+ va_list apcopy;
- va_start(ap,fmt);
- vsnprintf(str, sizeof(str), fmt, ap);
- va_end(ap);
+ va_copy(apcopy, ap);
+ vsnprintf(str, sizeof(str), fmt, apcopy);
+ va_end(apcopy);
SQL->EscapeStringLen(sql_handle, esc_str, str, strnlen(str, sizeof(str)));
if( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s` (`time`, `log`) VALUES (NOW(), '%s')", interlog_db, esc_str) )
@@ -761,6 +783,23 @@ int inter_log(char* fmt, ...)
return 0;
}
+/**
+ * Save interlog into sql
+ * @param fmt Message's format string
+ * @param ... Additional (printf-like) arguments
+ * @return Always 0 // FIXME
+ */
+int inter_log(char* fmt, ...) {
+ va_list ap;
+ int ret;
+
+ va_start(ap,fmt);
+ ret = inter_vlog(fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
// initialize
int inter_init_sql(const char *file)
{
diff --git a/src/char/inter.h b/src/char/inter.h
index f6663813a..88501c9a0 100644
--- a/src/char/inter.h
+++ b/src/char/inter.h
@@ -17,6 +17,7 @@ int mapif_send_gmaccounts(void);
int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason);
int inter_log(char *fmt,...);
+int inter_vlog(char *fmt, va_list ap);
#define inter_cfgName "conf/inter-server.conf"
diff --git a/src/common/db.c b/src/common/db.c
index bd2bea424..b3a58e0a4 100644
--- a/src/common/db.c
+++ b/src/common/db.c
@@ -2730,20 +2730,26 @@ void linkdb_insert( struct linkdb_node** head, void *key, void* data)
node->data = data;
}
-void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... )
-{
+void linkdb_vforeach( struct linkdb_node** head, LinkDBFunc func, va_list ap) {
struct linkdb_node *node;
if( head == NULL ) return;
node = *head;
while ( node ) {
- va_list args;
- va_start(args, func);
- func( node->key, node->data, args );
- va_end(args);
+ va_list argscopy;
+ va_copy(argscopy, ap);
+ func(node->key, node->data, argscopy);
+ va_end(argscopy);
node = node->next;
}
}
+void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ...) {
+ va_list ap;
+ va_start(ap, func);
+ linkdb_vforeach(head, func, ap);
+ va_end(ap);
+}
+
void* linkdb_search( struct linkdb_node** head, void *key)
{
int n = 0;
diff --git a/src/common/db.h b/src/common/db.h
index aa4bfb054..dffd2356d 100644
--- a/src/common/db.h
+++ b/src/common/db.h
@@ -882,12 +882,13 @@ struct linkdb_node {
typedef void (*LinkDBFunc)(void* key, void* data, va_list args);
-void linkdb_insert ( struct linkdb_node** head, void *key, void* data); // 重複を考慮しない
-void linkdb_replace( struct linkdb_node** head, void *key, void* data); // 重複を考慮する
-void* linkdb_search ( struct linkdb_node** head, void *key);
-void* linkdb_erase ( struct linkdb_node** head, void *key);
-void linkdb_final ( struct linkdb_node** head );
-void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... );
+void linkdb_insert (struct linkdb_node** head, void *key, void* data); // 重複を考慮しない
+void linkdb_replace (struct linkdb_node** head, void *key, void* data); // 重複を考慮する
+void* linkdb_search (struct linkdb_node** head, void *key);
+void* linkdb_erase (struct linkdb_node** head, void *key);
+void linkdb_final (struct linkdb_node** head);
+void linkdb_vforeach(struct linkdb_node** head, LinkDBFunc func, va_list ap);
+void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...);
diff --git a/src/map/map.c b/src/map/map.c
index 899f6b963..ea40d9979 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -596,13 +596,12 @@ static int map_vforeachinmap(int (*func)(struct block_list*, va_list), int16 m,
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, int type, ...)
-{
- int returnCount = 0;
+int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, int type, ...) {
+ int returnCount;
va_list ap;
va_start(ap, type);
- returnCount = map_vforeachinmap(func, m, type, ap);
+ returnCount = map->vforeachinmap(func, m, type, ap);
va_end(ap);
return returnCount;
@@ -616,26 +615,47 @@ int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, int type
* @param func Function to be applied
* @param m Map id
* @param type enum bl_type
- * @param ... Extra arguments for func
+ * @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachininstance(int (*func)(struct block_list*, va_list), int16 instance_id, int type, ...)
-{
+int map_vforeachininstance(int (*func)(struct block_list*, va_list), int16 instance_id, int type, va_list ap) {
int i;
int returnCount = 0;
for (i = 0; i < instance->list[instance_id].num_map; i++) {
int m = instance->list[instance_id].map[i];
- va_list ap;
- va_start(ap, type);
- returnCount += map_vforeachinmap(func, m, type, ap);
- va_end(ap);
+ va_list apcopy;
+ va_copy(apcopy, ap);
+ returnCount += map->vforeachinmap(func, m, type, apcopy);
+ va_end(apcopy);
}
return returnCount;
}
/**
+ * Applies func to every block_list object of bl_type type on all maps
+ * of instance instance_id.
+ * Returns the sum of values returned by func.
+ * @see map_vforeachininstance.
+ * @param func Function to be applied
+ * @param m Map id
+ * @param type enum bl_type
+ * @param ... Extra arguments for func
+ * @return Sum of the values returned by func
+ */
+int map_foreachininstance(int (*func)(struct block_list*, va_list), int16 instance_id, int type, ...) {
+ int returnCount;
+ va_list ap;
+
+ va_start(ap, type);
+ returnCount = map->vforeachininstance(func, instance_id, type, ap);
+ va_end(ap);
+
+ return returnCount;
+}
+
+/**
* Retrieves all map objects in area that are matched by the type
* and func. Appends them at the end of global bl_list array.
* @param type Matching enum bl_type
@@ -740,21 +760,43 @@ static int bl_vgetall_inrange(struct block_list *bl, va_list args)
* @param center Center of the selection area
* @param range Range in cells from center
* @param type enum bl_type
- * @param ... Extra arguments for func
+ * @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, ...)
-{
+int map_vforeachinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, va_list ap) {
int returnCount = 0;
int blockcount = bl_list_count;
- va_list ap;
+ va_list apcopy;
if (range < 0) range *= -1;
bl_getall_area(type, center->m, center->x - range, center->y - range, center->x + range, center->y + range, bl_vgetall_inrange, center, range);
+ va_copy(apcopy, ap);
+ returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy);
+ va_end(ap);
+
+ return returnCount;
+}
+
+/**
+ * Applies func to every block_list object of bl_type type within range cells from center.
+ * Area is rectangular, unless CIRCULAR_AREA is defined.
+ * Returns the sum of values returned by func.
+ * @see map_vforeachinrange
+ * @param func Function to be applied
+ * @param center Center of the selection area
+ * @param range Range in cells from center
+ * @param type enum bl_type
+ * @param ... Extra arguments for func
+ * @return Sum of the values returned by func
+ */
+int map_foreachinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, ...) {
+ int returnCount;
+ va_list ap;
+
va_start(ap, type);
- returnCount = bl_vforeach(func, blockcount, INT_MAX, ap);
+ returnCount = map->vforeachinrange(func, center, range, type, ap);
va_end(ap);
return returnCount;
@@ -770,21 +812,45 @@ int map_foreachinrange(int (*func)(struct block_list*, va_list), struct block_li
* @param range Range in cells from center
* @param count Maximum sum of values returned by func (usually max number of func calls)
* @param type enum bl_type
- * @param ... Extra arguments for func
+ * @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_forcountinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int count, int type, ...)
-{
+int map_vforcountinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int count, int type, va_list ap) {
int returnCount = 0;
int blockcount = bl_list_count;
- va_list ap;
+ va_list apcopy;
if (range < 0) range *= -1;
bl_getall_area(type, center->m, center->x - range, center->y - range, center->x + range, center->y + range, bl_vgetall_inrange, center, range);
+ va_copy(apcopy, ap);
+ returnCount = bl_vforeach(func, blockcount, count, apcopy);
+ va_end(apcopy);
+
+ return returnCount;
+}
+
+/**
+ * Applies func to some block_list objects of bl_type type within range cells from center.
+ * Limit is set by count parameter.
+ * Area is rectangular, unless CIRCULAR_AREA is defined.
+ * Returns the sum of values returned by func.
+ * @see map_vforcountinrange
+ * @param func Function to be applied
+ * @param center Center of the selection area
+ * @param range Range in cells from center
+ * @param count Maximum sum of values returned by func (usually max number of func calls)
+ * @param type enum bl_type
+ * @param ... Extra arguments for func
+ * @return Sum of the values returned by func
+ */
+int map_forcountinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int count, int type, ...) {
+ int returnCount;
+ va_list ap;
+
va_start(ap, type);
- returnCount = bl_vforeach(func, blockcount, count, ap);
+ returnCount = map->vforcountinrange(func, center, range, count, type, ap);
va_end(ap);
return returnCount;
@@ -819,21 +885,43 @@ static int bl_vgetall_inshootrange(struct block_list *bl, va_list args)
* @param center Center of the selection area
* @param range Range in cells from center
* @param type enum bl_type
- * @param ... Extra arguments for func
+ * @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinshootrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, ...)
-{
+int map_vforeachinshootrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, va_list ap) {
int returnCount = 0;
int blockcount = bl_list_count;
- va_list ap;
+ va_list apcopy;
if (range < 0) range *= -1;
bl_getall_area(type, center->m, center->x - range, center->y - range, center->x + range, center->y + range, bl_vgetall_inshootrange, center, range);
- va_start(ap, type);
+ va_copy(apcopy, ap);
returnCount = bl_vforeach(func, blockcount, INT_MAX, ap);
+ va_end(apcopy);
+
+ return returnCount;
+}
+
+/**
+ * Applies func to every block_list object of bl_type type within shootable range from center.
+ * There must be a shootable path between bl and center.
+ * Area is rectangular, unless CIRCULAR_AREA is defined.
+ * Returns the sum of values returned by func.
+ * @param func Function to be applied
+ * @param center Center of the selection area
+ * @param range Range in cells from center
+ * @param type enum bl_type
+ * @param ... Extra arguments for func
+ * @return Sum of the values returned by func
+ */
+int map_foreachinshootrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, ...) {
+ int returnCount;
+ va_list ap;
+
+ va_start(ap, type);
+ returnCount = map->vforeachinshootrange(func, center, range, type, ap);
va_end(ap);
return returnCount;
@@ -850,19 +938,44 @@ int map_foreachinshootrange(int (*func)(struct block_list*, va_list), struct blo
* @param x1 Ending X-coordinate
* @param y1 Ending Y-coordinate
* @param type enum bl_type
- * @param ... Extra arguments for func
+ * @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...)
-{
+int map_vforeachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, va_list ap) {
int returnCount = 0;
int blockcount = bl_list_count;
- va_list ap;
+ va_list apcopy;
bl_getall_area(type, m, x0, y0, x1, y1, NULL);
+ va_copy(apcopy, ap);
+ returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy);
+ va_end(apcopy);
+
+ return returnCount;
+}
+
+/**
+ * Applies func to every block_list object of bl_type type in
+ * rectangular area (x0,y0)~(x1,y1) on map m.
+ * Returns the sum of values returned by func.
+ * @see map_vforeachinarea
+ * @param func Function to be applied
+ * @param m Map id
+ * @param x0 Starting X-coordinate
+ * @param y0 Starting Y-coordinate
+ * @param x1 Ending X-coordinate
+ * @param y1 Ending Y-coordinate
+ * @param type enum bl_type
+ * @param ... Extra arguments for func
+ * @return Sum of the values returned by func
+ */
+int map_foreachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...) {
+ int returnCount;
+ va_list ap;
+
va_start(ap, type);
- returnCount = bl_vforeach(func, blockcount, INT_MAX, ap);
+ returnCount = map->vforeachinarea(func, m, x0, y0, x1, y1, type, ap);
va_end(ap);
return returnCount;
@@ -881,19 +994,46 @@ int map_foreachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x
* @param y1 Ending Y-coordinate
* @param count Maximum sum of values returned by func (usually max number of func calls)
* @param type enum bl_type
- * @param ... Extra arguments for func
+ * @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_forcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, ...)
-{
+int map_vforcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, va_list ap) {
int returnCount = 0;
int blockcount = bl_list_count;
- va_list ap;
+ va_list apcopy;
bl_getall_area(type, m, x0, y0, x1, y1, NULL);
+ va_copy(apcopy, ap);
+ returnCount = bl_vforeach(func, blockcount, count, apcopy);
+ va_end(apcopy);
+
+ return returnCount;
+}
+
+/**
+ * Applies func to some block_list objects of bl_type type in
+ * rectangular area (x0,y0)~(x1,y1) on map m.
+ * Limit is set by @count parameter.
+ * Returns the sum of values returned by func.
+ * @see map_vforcountinarea
+ * @param func Function to be applied
+ * @param m Map id
+ * @param x0 Starting X-coordinate
+ * @param y0 Starting Y-coordinate
+ * @param x1 Ending X-coordinate
+ * @param y1 Ending Y-coordinate
+ * @param count Maximum sum of values returned by func (usually max number of func calls)
+ * @param type enum bl_type
+ * @param ... Extra arguments for func
+ * @return Sum of the values returned by func
+ */
+int map_forcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, ...) {
+ int returnCount;
+ va_list ap;
+
va_start(ap, type);
- returnCount = bl_vforeach(func, blockcount, count, ap);
+ returnCount = map->vforcountinarea(func, m, x0, y0, x1, y1, count, type, ap);
va_end(ap);
return returnCount;
@@ -939,15 +1079,14 @@ static int bl_vgetall_inmovearea(struct block_list *bl, va_list args)
* @param dx Center's movement on X-axis
* @param dy Center's movement on Y-axis
* @param type enum bl_type
- * @param ... Extra arguments for func
+ * @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, ...)
-{
+int map_vforeachinmovearea(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, va_list ap) {
int returnCount = 0;
int blockcount = bl_list_count;
- va_list ap;
int m, x0, x1, y0, y1;
+ va_list apcopy;
if (!range) return 0;
if (!dx && !dy) return 0; // No movement.
@@ -974,8 +1113,39 @@ int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block
bl_getall_area(type, m, x0, y0, x1, y1, bl_vgetall_inmovearea, dx, dy, center, range);
}
+ va_copy(apcopy, ap);
+ returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy);
+ va_end(apcopy);
+
+ return returnCount;
+}
+
+/**
+ * Applies func to every block_list object of bl_type type in
+ * area that was covered by range cells from center, but is no
+ * longer after center is moved by (dx,dy) cells (i.e. area that
+ * center has lost sight of).
+ * If used after center has reached its destination and with
+ * opposed movement vector (-dx,-dy), selection corresponds
+ * to new area in center's view).
+ * Uses rectangular area.
+ * Returns the sum of values returned by func.
+ * @see map_vforeachinmovearea
+ * @param func Function to be applied
+ * @param center Center of the selection area
+ * @param range Range in cells from center
+ * @param dx Center's movement on X-axis
+ * @param dy Center's movement on Y-axis
+ * @param type enum bl_type
+ * @param ... Extra arguments for func
+ * @return Sum of the values returned by func
+ */
+int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, ...) {
+ int returnCount;
+ va_list ap;
+
va_start(ap, type);
- returnCount = bl_vforeach(func, blockcount, INT_MAX, ap);
+ returnCount = map->vforeachinmovearea(func, center, range, dx, dy, type, ap);
va_end(ap);
return returnCount;
@@ -990,19 +1160,41 @@ int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block
* @param x Target cell X-coordinate
* @param y Target cell Y-coordinate
* @param type enum bl_type
- * @param ... Extra arguments for func
+ * @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachincell(int (*func)(struct block_list*, va_list), int16 m, int16 x, int16 y, int type, ...)
-{
+int map_vforeachincell(int (*func)(struct block_list*, va_list), int16 m, int16 x, int16 y, int type, va_list ap) {
int returnCount = 0;
int blockcount = bl_list_count;
- va_list ap;
+ va_list apcopy;
bl_getall_area(type, m, x, y, x, y, NULL);
+ va_copy(apcopy, ap);
+ returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy);
+ va_end(apcopy);
+
+ return returnCount;
+}
+
+/**
+ * Applies func to every block_list object of bl_type type in
+ * cell (x,y) on map m.
+ * Returns the sum of values returned by func.
+ * @param func Function to be applied
+ * @param m Map id
+ * @param x Target cell X-coordinate
+ * @param y Target cell Y-coordinate
+ * @param type enum bl_type
+ * @param ... Extra arguments for func
+ * @return Sum of the values returned by func
+ */
+int map_foreachincell(int (*func)(struct block_list*, va_list), int16 m, int16 x, int16 y, int type, ...) {
+ int returnCount;
+ va_list ap;
+
va_start(ap, type);
- returnCount = bl_vforeach(func, blockcount, INT_MAX, ap);
+ returnCount = map->vforeachincell(func, m, x, y, type, ap);
va_end(ap);
return returnCount;
@@ -1069,11 +1261,10 @@ static int bl_vgetall_inpath(struct block_list *bl, va_list args)
* @param x Target cell X-coordinate
* @param y Target cell Y-coordinate
* @param type enum bl_type
- * @param ... Extra arguments for func
+ * @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, ...)
-{
+int map_vforeachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, va_list ap) {
// [Skotlex]
// check for all targets in the square that
// contains the initial and final positions (area range increased to match the
@@ -1090,7 +1281,7 @@ int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x
int returnCount = 0;
int blockcount = bl_list_count;
- va_list ap;
+ va_list apcopy;
//method specific variables
int magnitude2, len_limit; //The square of the magnitude
@@ -1127,13 +1318,40 @@ int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x
bl_getall_area(type, m, mx0, my0, mx1, my1, bl_vgetall_inpath, m, x0, y0, x1, y1, range, len_limit, magnitude2);
+ va_copy(apcopy, ap);
+ returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy);
+ va_end(apcopy);
+
+ return returnCount;
+}
+#undef MAGNITUDE2
+
+/**
+ * Applies func to every block_list object of bl_type type in
+ * path on a line between (x0,y0) and (x1,y1) on map m.
+ * Path starts at (x0,y0) and is \a length cells long and \a range cells wide.
+ * Objects beyond the initial (x1,y1) ending point are checked
+ * for walls in the path.
+ * Returns the sum of values returned by func.
+ * @see map_vforeachinpath
+ * @param func Function to be applied
+ * @param m Map id
+ * @param x Target cell X-coordinate
+ * @param y Target cell Y-coordinate
+ * @param type enum bl_type
+ * @param ... Extra arguments for func
+ * @return Sum of the values returned by func
+ */
+int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, ...) {
+ int returnCount;
+ va_list ap;
+
va_start(ap, type);
- returnCount = bl_vforeach(func, blockcount, INT_MAX, ap);
+ returnCount = map->vforeachinpath(func, m, x0, y0, x1, y1, range, length, type, ap);
va_end(ap);
return returnCount;
}
-#undef MAGNITUDE2
/** @} */
@@ -1304,11 +1522,10 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1
continue;
if(flag&4) {
if (spawn >= 100) return 0; //Limit of retries reached.
- if (spawn++ < battle_config.no_spawn_on_player &&
- map_foreachinarea(map_count_sub, m,
- *x-AREA_SIZE, *y-AREA_SIZE,
- *x+AREA_SIZE, *y+AREA_SIZE, BL_PC)
- )
+ if (spawn++ < battle_config.no_spawn_on_player
+ && map->foreachinarea(map_count_sub, m, *x-AREA_SIZE, *y-AREA_SIZE,
+ *x+AREA_SIZE, *y+AREA_SIZE, BL_PC)
+ )
continue;
}
return 1;
@@ -1784,66 +2001,83 @@ struct mob_data * map_id2boss(int id)
/// Applies func to all the players in the db.
/// Stops iterating if func returns -1.
-void map_map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...) {
+void map_vmap_foreachpc(int (*func)(struct map_session_data* sd, va_list args), va_list args) {
DBIterator* iter;
struct map_session_data* sd;
iter = db_iterator(pc_db);
for( sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter) )
{
- va_list args;
+ va_list argscopy;
int ret;
- va_start(args, func);
- ret = func(sd, args);
- va_end(args);
+ va_copy(argscopy, args);
+ ret = func(sd, argscopy);
+ va_end(argscopy);
if( ret == -1 )
break;// stop iterating
}
dbi_destroy(iter);
}
+/// Applies func to all the players in the db.
+/// Stops iterating if func returns -1.
+/// @see map_vmap_foreachpc
+void map_map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...) {
+ va_list args;
+
+ va_start(args, func);
+ map->vmap_foreachpc(func, args);
+ va_end(args);
+}
+
/// Applies func to all the mobs in the db.
/// Stops iterating if func returns -1.
-void map_map_foreachmob(int (*func)(struct mob_data* md, va_list args), ...)
-{
+void map_vmap_foreachmob(int (*func)(struct mob_data* md, va_list args), va_list args) {
DBIterator* iter;
struct mob_data* md;
iter = db_iterator(mobid_db);
- for( md = (struct mob_data*)dbi_first(iter); dbi_exists(iter); md = (struct mob_data*)dbi_next(iter) )
- {
- va_list args;
+ for( md = (struct mob_data*)dbi_first(iter); dbi_exists(iter); md = (struct mob_data*)dbi_next(iter) ) {
+ va_list argscopy;
int ret;
- va_start(args, func);
- ret = func(md, args);
- va_end(args);
+ va_copy(argscopy, args);
+ ret = func(md, argscopy);
+ va_end(argscopy);
if( ret == -1 )
break;// stop iterating
}
dbi_destroy(iter);
}
+/// Applies func to all the mobs in the db.
+/// Stops iterating if func returns -1.
+/// @see map_vmap_foreachmob
+void map_map_foreachmob(int (*func)(struct mob_data* md, va_list args), ...) {
+ va_list args;
+
+ va_start(args, func);
+ map->vmap_foreachmob(func, args);
+ va_end(args);
+}
+
/// Applies func to all the npcs in the db.
/// Stops iterating if func returns -1.
-void map_map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...)
-{
+void map_vmap_foreachnpc(int (*func)(struct npc_data* nd, va_list args), va_list args) {
DBIterator* iter;
struct block_list* bl;
iter = db_iterator(id_db);
- for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) )
- {
- if( bl->type == BL_NPC )
- {
+ for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) {
+ if( bl->type == BL_NPC ) {
struct npc_data* nd = (struct npc_data*)bl;
- va_list args;
+ va_list argscopy;
int ret;
- va_start(args, func);
- ret = func(nd, args);
- va_end(args);
+ va_copy(argscopy, args);
+ ret = func(nd, argscopy);
+ va_end(argscopy);
if( ret == -1 )
break;// stop iterating
}
@@ -1851,22 +2085,31 @@ void map_map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...)
dbi_destroy(iter);
}
+/// Applies func to all the npcs in the db.
+/// Stops iterating if func returns -1.
+/// @see map_vmap_foreachnpc
+void map_map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) {
+ va_list args;
+
+ va_start(args, func);
+ map->vmap_foreachnpc(func, args);
+ va_end(args);
+}
+
/// Applies func to everything in the db.
/// Stops iteratin gif func returns -1.
-void map_map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...)
-{
+void map_vmap_foreachregen(int (*func)(struct block_list* bl, va_list args), va_list args) {
DBIterator* iter;
struct block_list* bl;
iter = db_iterator(regen_db);
- for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) )
- {
- va_list args;
+ for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) {
+ va_list argscopy;
int ret;
- va_start(args, func);
- ret = func(bl, args);
- va_end(args);
+ va_copy(argscopy, args);
+ ret = func(bl, argscopy);
+ va_end(argscopy);
if( ret == -1 )
break;// stop iterating
}
@@ -1874,27 +2117,47 @@ void map_map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...)
}
/// Applies func to everything in the db.
+/// Stops iteratin gif func returns -1.
+/// @see map_vmap_foreachregen
+void map_map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...) {
+ va_list args;
+
+ va_start(args, func);
+ map->vmap_foreachregen(func, args);
+ va_end(args);
+}
+
+/// Applies func to everything in the db.
/// Stops iterating if func returns -1.
-void map_map_foreachiddb(int (*func)(struct block_list* bl, va_list args), ...)
-{
+void map_vmap_foreachiddb(int (*func)(struct block_list* bl, va_list args), va_list args) {
DBIterator* iter;
struct block_list* bl;
iter = db_iterator(id_db);
- for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) )
- {
- va_list args;
+ for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) {
+ va_list argscopy;
int ret;
- va_start(args, func);
- ret = func(bl, args);
- va_end(args);
+ va_copy(argscopy, args);
+ ret = func(bl, argscopy);
+ va_end(argscopy);
if( ret == -1 )
break;// stop iterating
}
dbi_destroy(iter);
}
+/// Applies func to everything in the db.
+/// Stops iterating if func returns -1.
+/// @see map_vmap_foreachiddb
+void map_map_foreachiddb(int (*func)(struct block_list* bl, va_list args), ...) {
+ va_list args;
+
+ va_start(args, func);
+ map->vmap_foreachiddb(func, args);
+ va_end(args);
+}
+
/// Iterator.
/// Can filter by bl type.
struct s_mapiterator
@@ -2128,7 +2391,7 @@ int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data)
if (maplist[m].users > 0) //Map not empty!
return 1;
- count = map_foreachinmap(map_removemobs_sub, m, BL_MOB);
+ count = map->foreachinmap(map_removemobs_sub, m, BL_MOB);
if (battle_config.etc_log && count > 0)
ShowStatus("Map %s: Removed '"CL_WHITE"%d"CL_RESET"' mobs.\n",maplist[m].name, count);
@@ -4888,7 +5151,7 @@ void do_final(void)
for (i = 0; i < map->map_num; i++) {
ShowStatus("Cleaning up maps [%d/%d]: %s..."CL_CLL"\r", i+1, map->map_num, maplist[i].name);
if (maplist[i].m >= 0)
- map_foreachinmap(map->cleanup_sub, i, BL_ALL);
+ map->foreachinmap(map->cleanup_sub, i, BL_ALL);
}
ShowStatus("Cleaned up %d maps."CL_CLL"\n", map->map_num);
@@ -5479,21 +5742,36 @@ void map_defaults(void) {
map->charid2nick = map_charid2nick;
map->charid2sd = map_charid2sd;
+ map->vmap_foreachpc = map_vmap_foreachpc;
map->map_foreachpc = map_map_foreachpc;
+ map->vmap_foreachmob = map_vmap_foreachmob;
map->map_foreachmob = map_map_foreachmob;
+ map->vmap_foreachnpc = map_vmap_foreachnpc;
map->map_foreachnpc = map_map_foreachnpc;
+ map->vmap_foreachregen = map_vmap_foreachregen;
map->map_foreachregen = map_map_foreachregen;
+ map->vmap_foreachiddb = map_vmap_foreachiddb;
map->map_foreachiddb = map_map_foreachiddb;
+ map->vforeachinrange = map_vforeachinrange;
map->foreachinrange = map_foreachinrange;
+ map->vforeachinshootrange = map_vforeachinshootrange;
map->foreachinshootrange = map_foreachinshootrange;
+ map->vforeachinarea = map_vforeachinarea;
map->foreachinarea = map_foreachinarea;
+ map->vforcountinrange = map_vforcountinrange;
map->forcountinrange = map_forcountinrange;
+ map->vforcountinarea = map_vforcountinarea;
map->forcountinarea = map_forcountinarea;
+ map->vforeachinmovearea = map_vforeachinmovearea;
map->foreachinmovearea = map_foreachinmovearea;
+ map->vforeachincell = map_vforeachincell;
map->foreachincell = map_foreachincell;
+ map->vforeachinpath = map_vforeachinpath;
map->foreachinpath = map_foreachinpath;
+ map->vforeachinmap = map_vforeachinmap;
map->foreachinmap = map_foreachinmap;
+ map->vforeachininstance = map_vforeachininstance;
map->foreachininstance = map_foreachininstance;
map->id2sd = map_id2sd;
diff --git a/src/map/map.h b/src/map/map.h
index f3a74ed2e..69152ec57 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -841,21 +841,36 @@ struct map_interface {
const char* (*charid2nick) (int charid);
struct map_session_data* (*charid2sd) (int charid);
+ void (*vmap_foreachpc) (int (*func)(struct map_session_data* sd, va_list args), va_list args);
void (*map_foreachpc) (int (*func)(struct map_session_data* sd, va_list args), ...);
+ void (*vmap_foreachmob) (int (*func)(struct mob_data* md, va_list args), va_list args);
void (*map_foreachmob) (int (*func)(struct mob_data* md, va_list args), ...);
+ void (*vmap_foreachnpc) (int (*func)(struct npc_data* nd, va_list args), va_list args);
void (*map_foreachnpc) (int (*func)(struct npc_data* nd, va_list args), ...);
+ void (*vmap_foreachregen) (int (*func)(struct block_list* bl, va_list args), va_list args);
void (*map_foreachregen) (int (*func)(struct block_list* bl, va_list args), ...);
+ void (*vmap_foreachiddb) (int (*func)(struct block_list* bl, va_list args), va_list args);
void (*map_foreachiddb) (int (*func)(struct block_list* bl, va_list args), ...);
+ int (*vforeachinrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, va_list ap);
int (*foreachinrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, ...);
+ int (*vforeachinshootrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, va_list ap);
int (*foreachinshootrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, ...);
+ int (*vforeachinarea) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, va_list ap);
int (*foreachinarea) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...);
+ int (*vforcountinrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int count, int type, va_list ap);
int (*forcountinrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int count, int type, ...);
+ int (*vforcountinarea) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, va_list ap);
int (*forcountinarea) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, ...);
+ int (*vforeachinmovearea) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, va_list ap);
int (*foreachinmovearea) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, ...);
+ int (*vforeachincell) (int (*func)(struct block_list*,va_list), int16 m, int16 x, int16 y, int type, va_list ap);
int (*foreachincell) (int (*func)(struct block_list*,va_list), int16 m, int16 x, int16 y, int type, ...);
+ int (*vforeachinpath) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, va_list ap);
int (*foreachinpath) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, ...);
+ int (*vforeachinmap) (int (*func)(struct block_list*,va_list), int16 m, int type, va_list args);
int (*foreachinmap) (int (*func)(struct block_list*,va_list), int16 m, int type, ...);
+ int (*vforeachininstance)(int (*func)(struct block_list*,va_list), int16 instance_id, int type, va_list ap);
int (*foreachininstance)(int (*func)(struct block_list*,va_list), int16 instance_id, int type,...);
struct map_session_data * (*id2sd) (int id);
diff --git a/src/map/party.c b/src/map/party.c
index 29ab5044c..a3fd5019f 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -1031,9 +1031,11 @@ int party_sub_count(struct block_list *bl, va_list ap)
return 1;
}
-/// Executes 'func' for each party member on the same map and in range (0:whole map)
-int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...)
-{
+/**
+ * Arglist-based version of party_foreachsamemap
+ * @see party_foreachsamemap
+ */
+int party_vforeachsamemap(int (*func)(struct block_list*,va_list), struct map_session_data *sd, int range, va_list ap) {
struct party_data *p;
int i;
int x0,y0,x1,y1;
@@ -1067,10 +1069,10 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess
map->freeblock_lock();
for(i=0;i<blockcount;i++) {
- va_list ap;
- va_start(ap, range);
- total += func(list[i], ap);
- va_end(ap);
+ va_list ap_copy;
+ va_copy(ap_copy, ap);
+ total += func(list[i], ap_copy);
+ va_end(ap_copy);
}
map->freeblock_unlock();
@@ -1078,6 +1080,23 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess
return total;
}
+/**
+ * Executes 'func' for each party member on the same map and within a 'range' cells area
+ * @param func Function to execute
+ * @param sd Reference character for party, map, area center
+ * @param range Area size (0 = whole map)
+ * @param ... Adidtional parameters to pass to func()
+ * @return Sum of the return values from func()
+ */
+int party_foreachsamemap(int (*func)(struct block_list*,va_list), struct map_session_data *sd, int range, ...) {
+ va_list ap;
+ int ret;
+ va_start(ap, range);
+ ret = party->vforeachsamemap(func, sd, range, ap);
+ va_end(ap);
+ return ret;
+}
+
/*==========================================
* Party Booking in KRO [Spiria]
*------------------------------------------*/
@@ -1291,6 +1310,7 @@ void party_defaults(void) {
party->booking_update = party_booking_update;
party->booking_search = party_booking_search;
party->booking_delete = party_booking_delete;
+ party->vforeachsamemap = party_vforeachsamemap;
party->foreachsamemap = party_foreachsamemap;
party->send_xy_timer = party_send_xy_timer;
party->fill_member = party_fill_member;
diff --git a/src/map/party.h b/src/map/party.h
index c2c13cc4f..570c7bd11 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -122,6 +122,7 @@ struct party_interface {
#endif
bool (*booking_delete) (struct map_session_data *sd);
/* */
+ int (*vforeachsamemap) (int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range, va_list ap);
int (*foreachsamemap) (int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range,...);
int (*send_xy_timer) (int tid, unsigned int tick, int id, intptr_t data);
void (*fill_member) (struct party_member* member, struct map_session_data* sd, unsigned int leader);