From 7c787e8adde6a56bc32ab65e5d2cd5eb1e3deeaf Mon Sep 17 00:00:00 2001 From: Haru Date: Fri, 11 Sep 2015 17:29:07 +0200 Subject: Corrected an issue causing queue iterators not to return their last value - Follow-up to 918b1123963ac2f91a4d074b092ceef1db71b4e8, a9042bf0bee2d2453058b22973bea8f335c5a201 - Thanks to Dastgir Signed-off-by: Haru --- src/map/script.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/map/script.c b/src/map/script.c index 54d8d338d..61ee7e49f 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -19090,28 +19090,40 @@ BUILDIN(queueiterator) { /* returns next/first member in the iterator, 0 if none */ BUILDIN(qiget) { int idx = script_getnum(st, 2); + struct hQueueIterator *it = NULL; - if( idx < 0 || idx >= script->hqis ) { + if (idx < 0 || idx >= script->hqis) { ShowWarning("buildin_qiget: unknown queue iterator id %d\n",idx); script_pushint(st, 0); - } else if (script->hqi[idx].pos >= script->hqi[idx].items) { - script_pushint(st, 0); - } else { - struct hQueueIterator *it = &script->hqi[idx]; - script_pushint(st, it->item[it->pos++]); + return true; } + it = &script->hqi[idx]; + + if (it->pos >= it->items) { + if (it->pos == it->items) + ++it->pos; // Move beyond the last position to invalidate qicheck + script_pushint(st, 0); + return true; + } + script_pushint(st, it->item[it->pos++]); return true; } /* Queue Iterator Check */ -/* returns 1:0 if there is a next member in the iterator */ +/* returns 1:0 if there is the current member in the iterator exists */ BUILDIN(qicheck) { int idx = script_getnum(st, 2); + struct hQueueIterator *it = NULL; - if( idx < 0 || idx >= script->hqis ) { + if (idx < 0 || idx >= script->hqis) { ShowWarning("buildin_qicheck: unknown queue iterator id %d\n",idx); script_pushint(st, 0); - } else if (script->hqi[idx].pos >= script->hqi[idx].items) { + return true; + } + + it = &script->hqi[idx]; + + if (it->pos <= 0 || it->pos > it->items) { script_pushint(st, 0); } else { script_pushint(st, 1); -- cgit v1.2.3-70-g09d2 From 71e868683b766633952e501a9cecf705bdc3e334 Mon Sep 17 00:00:00 2001 From: Haru Date: Mon, 14 Sep 2015 17:18:03 +0200 Subject: Fixed some direct accesses to script->hq[] from other modules. - script->hq[] should only be accessed through the provided interface, script->queue(). Signed-off-by: Haru --- src/map/battleground.c | 28 +++++++++++++++------------- src/map/clif.c | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/map/battleground.c b/src/map/battleground.c index cc5384d21..cbf859b80 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -496,7 +496,7 @@ void bg_queue_ready_ack (struct bg_arena *arena, struct map_session_data *sd, bo if( !response ) bg->queue_pc_cleanup(sd); else { - struct hQueue *queue = &script->hq[arena->queue_id]; + struct hQueue *queue = script->queue(arena->queue_id); int i, count = 0; sd->bg_queue.ready = 1; @@ -531,7 +531,7 @@ void bg_queue_player_cleanup(struct map_session_data *sd) { sd->bg_queue.type = 0; } void bg_match_over(struct bg_arena *arena, bool canceled) { - struct hQueue *queue = &script->hq[arena->queue_id]; + struct hQueue *queue = script->queue(arena->queue_id); int i; nullpo_retv(arena); @@ -560,7 +560,7 @@ void bg_match_over(struct bg_arena *arena, bool canceled) { script->queue_clear(arena->queue_id); } void bg_begin(struct bg_arena *arena) { - struct hQueue *queue = &script->hq[arena->queue_id]; + struct hQueue *queue = script->queue(arena->queue_id); int i, count = 0; nullpo_retv(arena); @@ -647,9 +647,9 @@ int bg_afk_timer(int tid, int64 tick, int id, intptr_t data) { void bg_queue_pregame(struct bg_arena *arena) { struct hQueue *queue; int i; - nullpo_retv(arena); - queue = &script->hq[arena->queue_id]; + + queue = script->queue(arena->queue_id); for( i = 0; i < queue->size; i++ ) { struct map_session_data * sd = NULL; @@ -667,9 +667,11 @@ int bg_fillup_timer(int tid, int64 tick, int id, intptr_t data) { void bg_queue_check(struct bg_arena *arena) { int count; - + struct hQueue *queue; nullpo_retv(arena); - count = script->hq[arena->queue_id].items; + + queue = script->queue(arena->queue_id); + count = queue->items; if( count == arena->max_players ) { if( arena->fillup_timer != INVALID_TIMER ) { timer->delete(arena->fillup_timer,bg->fillup_timer); @@ -729,8 +731,8 @@ void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_q sd->bg_queue.arena = arena; sd->bg_queue.ready = 0; script->queue_add(arena->queue_id,sd->status.account_id); - clif->bgqueue_joined(sd,script->hq[arena->queue_id].items); - clif->bgqueue_update_info(sd,arena->id,script->hq[arena->queue_id].items); + clif->bgqueue_joined(sd, queue->items); + clif->bgqueue_update_info(sd,arena->id, queue->items); break; case BGQT_PARTY: { struct party_data *p = party->search(sd->status.party_id); @@ -740,8 +742,8 @@ void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_q p->data[i].sd->bg_queue.arena = arena; p->data[i].sd->bg_queue.ready = 0; script->queue_add(arena->queue_id,p->data[i].sd->status.account_id); - clif->bgqueue_joined(p->data[i].sd,script->hq[arena->queue_id].items); - clif->bgqueue_update_info(p->data[i].sd,arena->id,script->hq[arena->queue_id].items); + clif->bgqueue_joined(p->data[i].sd, queue->items); + clif->bgqueue_update_info(p->data[i].sd,arena->id, queue->items); } } break; @@ -753,8 +755,8 @@ void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_q sd->guild->member[i].sd->bg_queue.arena = arena; sd->guild->member[i].sd->bg_queue.ready = 0; script->queue_add(arena->queue_id,sd->guild->member[i].sd->status.account_id); - clif->bgqueue_joined(sd->guild->member[i].sd,script->hq[arena->queue_id].items); - clif->bgqueue_update_info(sd->guild->member[i].sd,arena->id,script->hq[arena->queue_id].items); + clif->bgqueue_joined(sd->guild->member[i].sd, queue->items); + clif->bgqueue_update_info(sd->guild->member[i].sd,arena->id, queue->items); } break; } diff --git a/src/map/clif.c b/src/map/clif.c index 80703fa12..bc4313f46 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -610,7 +610,7 @@ bool clif_send(const void* buf, int len, struct block_list* bl, enum send_target case BG_QUEUE: if( sd && sd->bg_queue.arena ) { - struct hQueue *queue = &script->hq[sd->bg_queue.arena->queue_id]; + struct hQueue *queue = script->queue(sd->bg_queue.arena->queue_id); for( i = 0; i < queue->size; i++ ) { struct map_session_data *qsd = NULL; -- cgit v1.2.3-70-g09d2 From 1c9e25d58901e9c5bcea6bcbe885bd9c3eb5c72b Mon Sep 17 00:00:00 2001 From: Haru Date: Mon, 14 Sep 2015 14:44:52 +0200 Subject: Changed script->hq and script->hqi into VECTOR type Signed-off-by: Haru --- src/map/script.c | 176 +++++++++++++++++++++++++++---------------------------- src/map/script.h | 5 +- 2 files changed, 87 insertions(+), 94 deletions(-) (limited to 'src') diff --git a/src/map/script.c b/src/map/script.c index 61ee7e49f..de52dd9ea 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -4627,22 +4627,20 @@ void do_final_script(void) { aFree(script->buildin); - if( script->hqs ) { - for( i = 0; i < script->hqs; i++ ) { - if( script->hq[i].item != NULL ) - aFree(script->hq[i].item); + for (i = 0; i < VECTOR_LENGTH(script->hq); i++) { + if (VECTOR_INDEX(script->hq, i).item != NULL) { + aFree(VECTOR_INDEX(script->hq, i).item); } } - if (script->hqis && script->hqi) { - for( i = 0; i < script->hqis; i++ ) { - if( script->hqi[i].item != NULL ) - aFree(script->hqi[i].item); + VECTOR_CLEAR(script->hq); + + for (i = 0; i < VECTOR_LENGTH(script->hqi); i++) { + if (VECTOR_INDEX(script->hqi, i).item != NULL) { + aFree(VECTOR_INDEX(script->hqi, i).item); } } - if( script->hq != NULL ) - aFree(script->hq); - if( script->hqi != NULL ) - aFree(script->hqi); + VECTOR_CLEAR(script->hqi); + if( script->word_buf != NULL ) aFree(script->word_buf); @@ -5020,6 +5018,9 @@ void do_init_script(bool minimal) { ers_chunk_size(script->st_ers, 10); ers_chunk_size(script->stack_ers, 10); + VECTOR_INIT(script->hq); + VECTOR_INIT(script->hqi); + script->parse_builtin(); script->read_constdb(); script->hardcoded_constants(); @@ -18789,33 +18790,31 @@ BUILDIN(montransform) { return true; } -struct hQueue *script_hqueue_get(int idx) { - if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) +struct hQueue *script_hqueue_get(int idx) +{ + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) return NULL; - return &script->hq[idx]; + return &VECTOR_INDEX(script->hq, idx); } -int script_hqueue_create(void) { - int idx = script->hqs; +int script_hqueue_create(void) +{ + int idx = VECTOR_LENGTH(script->hq); int i; - for(i = 0; i < script->hqs; i++) { - if( script->hq[i].size == -1 ) { - break; - } - } + ARR_FIND(0, VECTOR_LENGTH(script->hq), i, VECTOR_INDEX(script->hq, i).size == -1); - if( i == script->hqs ) { - RECREATE(script->hq, struct hQueue, ++script->hqs); - script->hq[ idx ].item = NULL; + if (i == VECTOR_LENGTH(script->hq)) { + VECTOR_ENSURE(script->hq, 1, 1); + VECTOR_PUSHZEROED(script->hq); } else idx = i; - script->hq[ idx ].id = idx; - script->hq[ idx ].size = 0; - script->hq[ idx ].items = 0; - script->hq[ idx ].onDeath[0] = '\0'; - script->hq[ idx ].onLogOut[0] = '\0'; - script->hq[ idx ].onMapChange[0] = '\0'; + VECTOR_INDEX(script->hq, idx).id = i; + VECTOR_INDEX(script->hq, idx).size = 0; + VECTOR_INDEX(script->hq, idx).items = 0; + VECTOR_INDEX(script->hq, idx).onDeath[0] = '\0'; + VECTOR_INDEX(script->hq, idx).onLogOut[0] = '\0'; + VECTOR_INDEX(script->hq, idx).onMapChange[0] = '\0'; return idx; } /* set .@id,queue(); */ @@ -18829,42 +18828,42 @@ BUILDIN(queue) { BUILDIN(queuesize) { int idx = script_getnum(st, 2); - if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("buildin_queuesize: unknown queue id %d\n",idx); script_pushint(st, 0); } else { - script_pushint(st, script->hq[ idx ].items); + script_pushint(st, VECTOR_INDEX(script->hq, idx).items); } return true; } bool script_hqueue_add(int idx, int var) { - if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("script_hqueue_add: unknown queue id %d\n",idx); return true; } else { int i; - for (i = 0; i < script->hq[idx].size; i++) { - if (script->hq[idx].item[i] == var) { + for (i = 0; i < VECTOR_INDEX(script->hq, idx).size; i++) { + if (VECTOR_INDEX(script->hq, idx).item[i] == var) { return true; } } - if (i == script->hq[idx].size) { + if (i == VECTOR_INDEX(script->hq, idx).size) { struct map_session_data *sd; - for (i = 0; i < script->hq[idx].size; i++) { - if( script->hq[idx].item[i] == 0 ) { + for (i = 0; i < VECTOR_INDEX(script->hq, idx).size; i++) { + if (VECTOR_INDEX(script->hq, idx).item[i] == 0) { break; } } - if (i == script->hq[idx].size) - RECREATE(script->hq[idx].item, int, ++script->hq[idx].size); + if (i == VECTOR_INDEX(script->hq, idx).size) + RECREATE(VECTOR_INDEX(script->hq, idx).item, int, ++VECTOR_INDEX(script->hq, idx).size); - script->hq[idx].item[i] = var; - script->hq[idx].items++; + VECTOR_INDEX(script->hq, idx).item[i] = var; + VECTOR_INDEX(script->hq, idx).items++; if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) != NULL) { for (i = 0; i < sd->queues_count; i++) { if (sd->queues[i] == -1) { @@ -18893,23 +18892,23 @@ BUILDIN(queueadd) { return true; } bool script_hqueue_remove(int idx, int var) { - if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("script_hqueue_remove: unknown queue id %d (used with var %d)\n",idx,var); return true; } else { int i; - for(i = 0; i < script->hq[idx].size; i++) { - if( script->hq[idx].item[i] == var ) { + for (i = 0; i < VECTOR_INDEX(script->hq, idx).size; i++) { + if (VECTOR_INDEX(script->hq, idx).item[i] == var) { break; } } - if( i != script->hq[idx].size ) { + if (i != VECTOR_INDEX(script->hq, idx).size) { struct map_session_data *sd; - script->hq[idx].item[i] = -1; - script->hq[idx].items--; + VECTOR_INDEX(script->hq, idx).item[i] = -1; + VECTOR_INDEX(script->hq, idx).items--; if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) != NULL) { for(i = 0; i < sd->queues_count; i++) { @@ -18945,7 +18944,7 @@ BUILDIN(queueopt) { int idx = script_getnum(st, 2); int var = script_getnum(st, 3); - if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("buildin_queueopt: unknown queue id %d\n",idx); script_pushint(st, 1); } else if( var <= HQO_NONE || var >= HQO_MAX ) { @@ -18955,21 +18954,21 @@ BUILDIN(queueopt) { switch( (enum hQueueOpt)var ) { case HQO_OnDeath: if( script_hasdata(st, 4) ) - safestrncpy(script->hq[idx].onDeath, script_getstr(st, 4), EVENT_NAME_LENGTH); + safestrncpy(VECTOR_INDEX(script->hq, idx).onDeath, script_getstr(st, 4), EVENT_NAME_LENGTH); else - script->hq[idx].onDeath[0] = '\0'; + VECTOR_INDEX(script->hq, idx).onDeath[0] = '\0'; break; case HQO_onLogOut: if( script_hasdata(st, 4) ) - safestrncpy(script->hq[idx].onLogOut, script_getstr(st, 4), EVENT_NAME_LENGTH); + safestrncpy(VECTOR_INDEX(script->hq, idx).onLogOut, script_getstr(st, 4), EVENT_NAME_LENGTH); else - script->hq[idx].onLogOut[0] = '\0'; + VECTOR_INDEX(script->hq, idx).onLogOut[0] = '\0'; break; case HQO_OnMapChange: if( script_hasdata(st, 4) ) - safestrncpy(script->hq[idx].onMapChange, script_getstr(st, 4), EVENT_NAME_LENGTH); + safestrncpy(VECTOR_INDEX(script->hq, idx).onMapChange, script_getstr(st, 4), EVENT_NAME_LENGTH); else - script->hq[idx].onMapChange[0] = '\0'; + VECTOR_INDEX(script->hq, idx).onMapChange[0] = '\0'; break; default: ShowWarning("buildin_queueopt: unsupported optionType %d\n",var); @@ -18982,17 +18981,17 @@ BUILDIN(queueopt) { } bool script_hqueue_del(int idx) { - if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("script_queue_del: unknown queue id %d\n",idx); return true; } else { int i; - for (i = 0; i < script->hq[idx].size; i++) { + for (i = 0; i < VECTOR_INDEX(script->hq, idx).size; i++) { struct map_session_data *sd; - if (script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(script->hq[idx].item[i])) != NULL) { + if (VECTOR_INDEX(script->hq, idx).item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(VECTOR_INDEX(script->hq, idx).item[i])) != NULL) { int j; for(j = 0; j < sd->queues_count; j++) { - if( sd->queues[j] == script->hq[idx].item[i] ) { + if (sd->queues[j] == VECTOR_INDEX(script->hq, idx).item[i]) { break; } } @@ -19000,11 +18999,10 @@ bool script_hqueue_del(int idx) if( j != sd->queues_count ) sd->queues[j] = -1; } - script->hq[idx].item[i] = 0; + VECTOR_INDEX(script->hq, idx).item[i] = 0; } - - script->hq[idx].size = -1; - script->hq[idx].items = 0; + VECTOR_INDEX(script->hq, idx).size = -1; + VECTOR_INDEX(script->hq, idx).items = 0; } return false; } @@ -19018,17 +19016,17 @@ BUILDIN(queuedel) { return true; } void script_hqueue_clear(int idx) { - if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("script_hqueue_clear: unknown queue id %d\n",idx); return; } else { struct map_session_data *sd; int i, j; - for(i = 0; i < script->hq[idx].size; i++) { - if( script->hq[idx].item[i] > 0 ) { + for(i = 0; i < VECTOR_INDEX(script->hq, idx).size; i++) { + if (VECTOR_INDEX(script->hq, idx).item[i] > 0) { - if (script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(script->hq[idx].item[i])) != NULL) { + if (VECTOR_INDEX(script->hq, idx).item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(VECTOR_INDEX(script->hq, idx).item[i])) != NULL) { for(j = 0; j < sd->queues_count; j++) { if( sd->queues[j] == idx ) { break; @@ -19038,10 +19036,10 @@ void script_hqueue_clear(int idx) { if( j != sd->queues_count ) sd->queues[j] = -1; } - script->hq[idx].item[i] = 0; + VECTOR_INDEX(script->hq, idx).item[i] = 0; } } - script->hq[idx].items = 0; + VECTOR_INDEX(script->hq, idx).items = 0; } return; } @@ -19050,10 +19048,10 @@ void script_hqueue_clear(int idx) { BUILDIN(queueiterator) { int qid = script_getnum(st, 2); struct hQueue *queue = NULL; - int idx = script->hqis; + int idx = VECTOR_LENGTH(script->hqi); int i; - if( qid < 0 || qid >= script->hqs || script->hq[qid].size == -1 || !(queue = script->queue(qid)) ) { + if( qid < 0 || qid >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, qid).size == -1 || !(queue = script->queue(qid)) ) { ShowWarning("queueiterator: invalid queue id %d\n",qid); return true; } @@ -19064,24 +19062,24 @@ BUILDIN(queueiterator) { return true; } - for(i = 0; i < script->hqis; i++) { - if( script->hqi[i].items == -1 ) { + for (i = 0; i < VECTOR_LENGTH(script->hqi); i++) { + if (VECTOR_INDEX(script->hqi, idx).items == -1) { break; } } - if( i == script->hqis ) { - RECREATE(script->hqi, struct hQueueIterator, ++script->hqis); - script->hqi[ idx ].item = NULL; + if (i == VECTOR_LENGTH(script->hqi)) { + VECTOR_ENSURE(script->hqi, 1, 1); + VECTOR_PUSHZEROED(script->hqi); } else idx = i; - RECREATE(script->hqi[ idx ].item, int, queue->size); + RECREATE(VECTOR_INDEX(script->hqi, idx).item, int, queue->size); - memcpy(script->hqi[idx].item, queue->item, sizeof(int)*queue->size); + memcpy(VECTOR_INDEX(script->hqi, idx).item, queue->item, sizeof(int)*queue->size); - script->hqi[ idx ].items = queue->size; - script->hqi[ idx ].pos = 0; + VECTOR_INDEX(script->hqi, idx).items = queue->size; + VECTOR_INDEX(script->hqi, idx).pos = 0; script_pushint(st,idx); return true; @@ -19092,13 +19090,13 @@ BUILDIN(qiget) { int idx = script_getnum(st, 2); struct hQueueIterator *it = NULL; - if (idx < 0 || idx >= script->hqis) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hqi)) { ShowWarning("buildin_qiget: unknown queue iterator id %d\n",idx); script_pushint(st, 0); return true; } - it = &script->hqi[idx]; + it = &VECTOR_INDEX(script->hqi, idx); if (it->pos >= it->items) { if (it->pos == it->items) @@ -19115,13 +19113,13 @@ BUILDIN(qicheck) { int idx = script_getnum(st, 2); struct hQueueIterator *it = NULL; - if (idx < 0 || idx >= script->hqis) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hqi)) { ShowWarning("buildin_qicheck: unknown queue iterator id %d\n",idx); script_pushint(st, 0); return true; } - it = &script->hqi[idx]; + it = &VECTOR_INDEX(script->hqi, idx); if (it->pos <= 0 || it->pos > it->items) { script_pushint(st, 0); @@ -19135,11 +19133,11 @@ BUILDIN(qicheck) { BUILDIN(qiclear) { int idx = script_getnum(st, 2); - if( idx < 0 || idx >= script->hqis ) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hqi)) { ShowWarning("buildin_qiclear: unknown queue iterator id %d\n",idx); script_pushint(st, 1); } else { - script->hqi[idx].items = -1; + VECTOR_INDEX(script->hqi, idx).items = -1; script_pushint(st, 0); } @@ -20585,10 +20583,6 @@ void script_defaults(void) { script->stack_ers = NULL; script->array_ers = NULL; - script->hq = NULL; - script->hqi = NULL; - script->hqs = script->hqis = 0; - script->buildin = NULL; script->buildin_count = 0; diff --git a/src/map/script.h b/src/map/script.h index ff660dec8..d3c64f401 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -515,9 +515,8 @@ struct script_interface { struct eri *st_ers; struct eri *stack_ers; /* */ - struct hQueue *hq; - struct hQueueIterator *hqi; - int hqs, hqis; + VECTOR_DECL(struct hQueue) hq; + VECTOR_DECL(struct hQueueIterator) hqi; /* */ char **buildin; unsigned int buildin_count; -- cgit v1.2.3-70-g09d2 From 778db38c4a584cbc3a8a9e56fcef54447e9bee47 Mon Sep 17 00:00:00 2001 From: Haru Date: Mon, 14 Sep 2015 15:00:02 +0200 Subject: Renamed hQueue/hQueueIterator/hQueueOpt to latest standards Signed-off-by: Haru --- src/map/battleground.c | 14 ++++++------- src/map/clif.c | 2 +- src/map/map.c | 6 +++--- src/map/pc.c | 12 ++++++------ src/map/script.c | 38 ++++++++++++++++++------------------ src/map/script.h | 53 ++++++++++++++++++++++++++++---------------------- 6 files changed, 66 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/map/battleground.c b/src/map/battleground.c index cbf859b80..2b7614761 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -472,7 +472,7 @@ struct bg_arena *bg_name2arena (char *name) { return NULL; } int bg_id2pos ( int queue_id, int account_id ) { - struct hQueue *queue = script->queue(queue_id); + struct script_queue *queue = script->queue(queue_id); if( queue ) { int i, pos = 1; for(i = 0; i < queue->size; i++ ) { @@ -496,7 +496,7 @@ void bg_queue_ready_ack (struct bg_arena *arena, struct map_session_data *sd, bo if( !response ) bg->queue_pc_cleanup(sd); else { - struct hQueue *queue = script->queue(arena->queue_id); + struct script_queue *queue = script->queue(arena->queue_id); int i, count = 0; sd->bg_queue.ready = 1; @@ -531,7 +531,7 @@ void bg_queue_player_cleanup(struct map_session_data *sd) { sd->bg_queue.type = 0; } void bg_match_over(struct bg_arena *arena, bool canceled) { - struct hQueue *queue = script->queue(arena->queue_id); + struct script_queue *queue = script->queue(arena->queue_id); int i; nullpo_retv(arena); @@ -560,7 +560,7 @@ void bg_match_over(struct bg_arena *arena, bool canceled) { script->queue_clear(arena->queue_id); } void bg_begin(struct bg_arena *arena) { - struct hQueue *queue = script->queue(arena->queue_id); + struct script_queue *queue = script->queue(arena->queue_id); int i, count = 0; nullpo_retv(arena); @@ -645,7 +645,7 @@ int bg_afk_timer(int tid, int64 tick, int id, intptr_t data) { } void bg_queue_pregame(struct bg_arena *arena) { - struct hQueue *queue; + struct script_queue *queue; int i; nullpo_retv(arena); @@ -667,7 +667,7 @@ int bg_fillup_timer(int tid, int64 tick, int id, intptr_t data) { void bg_queue_check(struct bg_arena *arena) { int count; - struct hQueue *queue; + struct script_queue *queue; nullpo_retv(arena); queue = script->queue(arena->queue_id); @@ -684,7 +684,7 @@ void bg_queue_check(struct bg_arena *arena) { } void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_queue_types type) { enum BATTLEGROUNDS_QUEUE_ACK result = bg->can_queue(sd,arena,type); - struct hQueue *queue; + struct script_queue *queue = NULL; int i, count = 0; nullpo_retv(sd); diff --git a/src/map/clif.c b/src/map/clif.c index bc4313f46..2b9ed43c6 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -610,7 +610,7 @@ bool clif_send(const void* buf, int len, struct block_list* bl, enum send_target case BG_QUEUE: if( sd && sd->bg_queue.arena ) { - struct hQueue *queue = script->queue(sd->bg_queue.arena->queue_id); + struct script_queue *queue = script->queue(sd->bg_queue.arena->queue_id); for( i = 0; i < queue->size; i++ ) { struct map_session_data *qsd = NULL; diff --git a/src/map/map.c b/src/map/map.c index cd2ba17c2..dd5baa626 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1803,9 +1803,9 @@ int map_quit(struct map_session_data *sd) { pc->itemcd_do(sd,false); for( i = 0; i < sd->queues_count; i++ ) { - struct hQueue *queue; - if( (queue = script->queue(sd->queues[i])) && queue->onLogOut[0] != '\0' ) { - npc->event(sd, queue->onLogOut, 0); + struct script_queue *queue = script->queue(sd->queues[i]); + if (queue && queue->event_logout[0] != '\0') { + npc->event(sd, queue->event_logout, 0); } } /* two times, the npc event above may assign a new one or delete others */ diff --git a/src/map/pc.c b/src/map/pc.c index 351d77b26..0671bfb5e 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5527,10 +5527,10 @@ int pc_setpos(struct map_session_data* sd, unsigned short map_index, int x, int sd->state.pmap = sd->bl.m; for( i = 0; i < sd->queues_count; i++ ) { - struct hQueue *queue; - if( (queue = script->queue(sd->queues[i])) && queue->onMapChange[0] != '\0' ) { + struct script_queue *queue = script->queue(sd->queues[i]); + if (queue && queue->event_mapchange[0] != '\0') { pc->setregstr(sd, script->add_str("QMapChangeTo"), map->list[m].name); - npc->event(sd, queue->onMapChange, 0); + npc->event(sd, queue->event_mapchange, 0); } } @@ -7635,9 +7635,9 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { } for( i = 0; i < sd->queues_count; i++ ) { - struct hQueue *queue; - if( (queue = script->queue(sd->queues[i])) && queue->onDeath[0] != '\0' ) - npc->event(sd, queue->onDeath, 0); + struct script_queue *queue = script->queue(sd->queues[i]); + if (queue && queue->event_death[0] != '\0') + npc->event(sd, queue->event_death, 0); } npc->script_event(sd,NPCE_DIE); diff --git a/src/map/script.c b/src/map/script.c index de52dd9ea..45f84ec18 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -18790,7 +18790,7 @@ BUILDIN(montransform) { return true; } -struct hQueue *script_hqueue_get(int idx) +struct script_queue *script_hqueue_get(int idx) { if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) return NULL; @@ -18812,9 +18812,9 @@ int script_hqueue_create(void) VECTOR_INDEX(script->hq, idx).id = i; VECTOR_INDEX(script->hq, idx).size = 0; VECTOR_INDEX(script->hq, idx).items = 0; - VECTOR_INDEX(script->hq, idx).onDeath[0] = '\0'; - VECTOR_INDEX(script->hq, idx).onLogOut[0] = '\0'; - VECTOR_INDEX(script->hq, idx).onMapChange[0] = '\0'; + VECTOR_INDEX(script->hq, idx).event_death[0] = '\0'; + VECTOR_INDEX(script->hq, idx).event_logout[0] = '\0'; + VECTOR_INDEX(script->hq, idx).event_mapchange[0] = '\0'; return idx; } /* set .@id,queue(); */ @@ -18947,28 +18947,28 @@ BUILDIN(queueopt) { if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("buildin_queueopt: unknown queue id %d\n",idx); script_pushint(st, 1); - } else if( var <= HQO_NONE || var >= HQO_MAX ) { + } else if( var <= SQO_NONE || var >= SQO_MAX ) { ShowWarning("buildin_queueopt: unknown optionType %d\n",var); script_pushint(st, 1); } else { - switch( (enum hQueueOpt)var ) { - case HQO_OnDeath: + switch ((enum ScriptQueueOptions)var) { + case SQO_ONDEATH: if( script_hasdata(st, 4) ) - safestrncpy(VECTOR_INDEX(script->hq, idx).onDeath, script_getstr(st, 4), EVENT_NAME_LENGTH); + safestrncpy(VECTOR_INDEX(script->hq, idx).event_death, script_getstr(st, 4), EVENT_NAME_LENGTH); else - VECTOR_INDEX(script->hq, idx).onDeath[0] = '\0'; + VECTOR_INDEX(script->hq, idx).event_death[0] = '\0'; break; - case HQO_onLogOut: + case SQO_ONLOGOUT: if( script_hasdata(st, 4) ) - safestrncpy(VECTOR_INDEX(script->hq, idx).onLogOut, script_getstr(st, 4), EVENT_NAME_LENGTH); + safestrncpy(VECTOR_INDEX(script->hq, idx).event_logout, script_getstr(st, 4), EVENT_NAME_LENGTH); else - VECTOR_INDEX(script->hq, idx).onLogOut[0] = '\0'; + VECTOR_INDEX(script->hq, idx).event_logout[0] = '\0'; break; - case HQO_OnMapChange: + case SQO_ONMAPCHANGE: if( script_hasdata(st, 4) ) - safestrncpy(VECTOR_INDEX(script->hq, idx).onMapChange, script_getstr(st, 4), EVENT_NAME_LENGTH); + safestrncpy(VECTOR_INDEX(script->hq, idx).event_mapchange, script_getstr(st, 4), EVENT_NAME_LENGTH); else - VECTOR_INDEX(script->hq, idx).onMapChange[0] = '\0'; + VECTOR_INDEX(script->hq, idx).event_mapchange[0] = '\0'; break; default: ShowWarning("buildin_queueopt: unsupported optionType %d\n",var); @@ -19047,7 +19047,7 @@ void script_hqueue_clear(int idx) { /* creates a new queue iterator, returns its id */ BUILDIN(queueiterator) { int qid = script_getnum(st, 2); - struct hQueue *queue = NULL; + struct script_queue *queue = NULL; int idx = VECTOR_LENGTH(script->hqi); int i; @@ -19088,7 +19088,7 @@ BUILDIN(queueiterator) { /* returns next/first member in the iterator, 0 if none */ BUILDIN(qiget) { int idx = script_getnum(st, 2); - struct hQueueIterator *it = NULL; + struct script_queue_iterator *it = NULL; if (idx < 0 || idx >= VECTOR_LENGTH(script->hqi)) { ShowWarning("buildin_qiget: unknown queue iterator id %d\n",idx); @@ -19111,7 +19111,7 @@ BUILDIN(qiget) { /* returns 1:0 if there is the current member in the iterator exists */ BUILDIN(qicheck) { int idx = script_getnum(st, 2); - struct hQueueIterator *it = NULL; + struct script_queue_iterator *it = NULL; if (idx < 0 || idx >= VECTOR_LENGTH(script->hqi)) { ShowWarning("buildin_qicheck: unknown queue iterator id %d\n",idx); @@ -20376,7 +20376,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(showevent, "i?"), /** - * hQueue [Ind/Hercules] + * script_queue [Ind/Hercules] **/ BUILDIN_DEF(queue,""), BUILDIN_DEF(queuesize,"i"), diff --git a/src/map/script.h b/src/map/script.h index d3c64f401..aa31389f6 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -223,12 +223,13 @@ typedef enum c_op { #endif // PCRE_SUPPORT } c_op; -enum hQueueOpt { - HQO_NONE, - HQO_onLogOut, - HQO_OnDeath, - HQO_OnMapChange, - HQO_MAX, +/// Script queue options +enum ScriptQueueOptions { + SQO_NONE, ///< No options set + SQO_ONLOGOUT, ///< Execute event on logout + SQO_ONDEATH, ///< Execute event on death + SQO_ONMAPCHANGE, ///< Execute event on map change + SQO_MAX, }; enum e_script_state { RUN,STOP,END,RERUNLINE,GOTO,RETFUNC,CLOSE }; @@ -391,22 +392,28 @@ struct script_stack { struct reg_db scope; ///< scope variables }; -/* [Ind/Hercules] */ -struct hQueue { - int id; - int *item; - int items;/* how many actual items are in the array */ - int size;/* size of the *item array, not the current amount of items in it since it can have empty slots */ - /* events */ - char onLogOut[EVENT_NAME_LENGTH]; - char onDeath[EVENT_NAME_LENGTH]; - char onMapChange[EVENT_NAME_LENGTH]; +/** + * Data structure to represent a script queue. + * @author Ind/Hercules + */ +struct script_queue { + int id; ///< Queue identifier + int *item; ///< Items in the queue (variable-size array) + int items; ///< Amount of elements in \c item + int size; ///< Capacity of the \c item array (not the current amount of items in it since it can have empty slots + /// Events + char event_logout[EVENT_NAME_LENGTH]; ///< Logout event + char event_death[EVENT_NAME_LENGTH]; ///< Death event + char event_mapchange[EVENT_NAME_LENGTH]; ///< Map change event }; -struct hQueueIterator { - int *item; - int items; - int pos; +/** + * Iterator for a struct script_queue. + */ +struct script_queue_iterator { + int *item; ///< Items in the queue (iterator's cached copy) + int items; ///< Amount of elements in \c item + int pos; ///< Iterator's cursor }; struct script_state { @@ -515,8 +522,8 @@ struct script_interface { struct eri *st_ers; struct eri *stack_ers; /* */ - VECTOR_DECL(struct hQueue) hq; - VECTOR_DECL(struct hQueueIterator) hqi; + VECTOR_DECL(struct script_queue) hq; + VECTOR_DECL(struct script_queue_iterator) hqi; /* */ char **buildin; unsigned int buildin_count; @@ -666,7 +673,7 @@ struct script_interface { void (*setd_sub) (struct script_state *st, struct map_session_data *sd, const char *varname, int elem, void *value, struct reg_db *ref); void (*attach_state) (struct script_state* st); /* */ - struct hQueue *(*queue) (int idx); + struct script_queue *(*queue) (int idx); bool (*queue_add) (int idx, int var); bool (*queue_del) (int idx); bool (*queue_remove) (int idx, int var); -- cgit v1.2.3-70-g09d2 From 12e05b756c4ecdd77ceb67966f7aafe62391bb56 Mon Sep 17 00:00:00 2001 From: Haru Date: Mon, 14 Sep 2015 17:28:57 +0200 Subject: HPM Hooks Update --- src/common/HPMDataCheck.h | 4 ++-- src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h index c60bec4c8..5b9158a6d 100644 --- a/src/common/HPMDataCheck.h +++ b/src/common/HPMDataCheck.h @@ -589,8 +589,6 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { #ifdef MAP_SCRIPT_H { "Script_Config", sizeof(struct Script_Config), SERVER_TYPE_MAP }, { "casecheck_data", sizeof(struct casecheck_data), SERVER_TYPE_MAP }, - { "hQueue", sizeof(struct hQueue), SERVER_TYPE_MAP }, - { "hQueueIterator", sizeof(struct hQueueIterator), SERVER_TYPE_MAP }, { "reg_db", sizeof(struct reg_db), SERVER_TYPE_MAP }, { "script_array", sizeof(struct script_array), SERVER_TYPE_MAP }, { "script_code", sizeof(struct script_code), SERVER_TYPE_MAP }, @@ -598,6 +596,8 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { { "script_function", sizeof(struct script_function), SERVER_TYPE_MAP }, { "script_interface", sizeof(struct script_interface), SERVER_TYPE_MAP }, { "script_label_entry", sizeof(struct script_label_entry), SERVER_TYPE_MAP }, + { "script_queue", sizeof(struct script_queue), SERVER_TYPE_MAP }, + { "script_queue_iterator", sizeof(struct script_queue_iterator), SERVER_TYPE_MAP }, { "script_retinfo", sizeof(struct script_retinfo), SERVER_TYPE_MAP }, { "script_stack", sizeof(struct script_stack), SERVER_TYPE_MAP }, { "script_state", sizeof(struct script_state), SERVER_TYPE_MAP }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index d6e4a85cc..f108b901d 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -59949,11 +59949,11 @@ void HP_script_attach_state(struct script_state *st) { } return; } -struct hQueue* HP_script_queue(int idx) { +struct script_queue* HP_script_queue(int idx) { int hIndex = 0; - struct hQueue* retVal___ = NULL; + struct script_queue* retVal___ = NULL; if( HPMHooks.count.HP_script_queue_pre ) { - struct hQueue* (*preHookFunc) (int *idx); + struct script_queue* (*preHookFunc) (int *idx); *HPMforce_return = false; for(hIndex = 0; hIndex < HPMHooks.count.HP_script_queue_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_script_queue_pre[hIndex].func; @@ -59968,7 +59968,7 @@ struct hQueue* HP_script_queue(int idx) { retVal___ = HPMHooks.source.script.queue(idx); } if( HPMHooks.count.HP_script_queue_post ) { - struct hQueue* (*postHookFunc) (struct hQueue* retVal___, int *idx); + struct script_queue* (*postHookFunc) (struct script_queue* retVal___, int *idx); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_queue_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_script_queue_post[hIndex].func; retVal___ = postHookFunc(retVal___, &idx); -- cgit v1.2.3-70-g09d2 From a3e041b4c425411ff38f4dfd6fd4aa1f6bca457c Mon Sep 17 00:00:00 2001 From: Haru Date: Mon, 14 Sep 2015 15:09:50 +0200 Subject: Refactored the script queue system - Corrected return value in bool functions (true always means success, false means failure, some were inverted). The script command return values are left unchanged for backwards compatibility. - Added some missing script_pushint to commands that are expected to return a value (on failure). - Cleaned up and optimized various functions. Signed-off-by: Haru --- src/map/script.c | 518 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 333 insertions(+), 185 deletions(-) (limited to 'src') diff --git a/src/map/script.c b/src/map/script.c index 45f84ec18..f6de7041d 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -18790,15 +18790,28 @@ BUILDIN(montransform) { return true; } +/** + * Returns the queue with he given index, if it exists. + * + * @param idx The queue index. + * + * @return The queue, or NULL if it doesn't exist. + */ struct script_queue *script_hqueue_get(int idx) { if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) return NULL; return &VECTOR_INDEX(script->hq, idx); } + +/** + * Creates a new queue. + * + * @return The index of the created queue. + */ int script_hqueue_create(void) { - int idx = VECTOR_LENGTH(script->hq); + struct script_queue *queue = NULL; int i; ARR_FIND(0, VECTOR_LENGTH(script->hq), i, VECTOR_INDEX(script->hq, i).size == -1); @@ -18806,287 +18819,400 @@ int script_hqueue_create(void) if (i == VECTOR_LENGTH(script->hq)) { VECTOR_ENSURE(script->hq, 1, 1); VECTOR_PUSHZEROED(script->hq); - } else - idx = i; - - VECTOR_INDEX(script->hq, idx).id = i; - VECTOR_INDEX(script->hq, idx).size = 0; - VECTOR_INDEX(script->hq, idx).items = 0; - VECTOR_INDEX(script->hq, idx).event_death[0] = '\0'; - VECTOR_INDEX(script->hq, idx).event_logout[0] = '\0'; - VECTOR_INDEX(script->hq, idx).event_mapchange[0] = '\0'; - return idx; -} -/* set .@id,queue(); */ -/* creates queue, returns created queue id */ -BUILDIN(queue) { + } + + queue = &VECTOR_INDEX(script->hq, i); + + queue->id = i; + queue->size = 0; + queue->items = 0; + queue->event_death[0] = '\0'; + queue->event_logout[0] = '\0'; + queue->event_mapchange[0] = '\0'; + return i; +} + +/** + * Script command queue: Creates a queue and returns its id. + * + * @code{.herc} + * .@queue_id = queue(); + * @endcode + */ +BUILDIN(queue) +{ script_pushint(st,script->queue_create()); return true; } -/* set .@length,queuesize(.@queue_id); */ -/* returns queue length */ -BUILDIN(queuesize) { + +/** + * Script command queuesize: Returns the length of the given queue. + * + * Returns 0 on error. + * + * \code{.herc} + * .@size = queuesize(); + * \endcode + */ +BUILDIN(queuesize) +{ int idx = script_getnum(st, 2); if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("buildin_queuesize: unknown queue id %d\n",idx); script_pushint(st, 0); - } else { - script_pushint(st, VECTOR_INDEX(script->hq, idx).items); + return true; } + script_pushint(st, VECTOR_INDEX(script->hq, idx).items); return true; } + +/** + * Adds an entry to the given queue. + * + * @param idx The queue index. + * @param var The entry to add. + * @retval false if the queue is invalid or the entry is already in the queue. + * @retval true in case of success. + */ bool script_hqueue_add(int idx, int var) { + int i, pos; + struct map_session_data *sd = NULL; + struct script_queue *queue = NULL; + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("script_hqueue_add: unknown queue id %d\n",idx); - return true; - } else { - int i; - for (i = 0; i < VECTOR_INDEX(script->hq, idx).size; i++) { - if (VECTOR_INDEX(script->hq, idx).item[i] == var) { - return true; - } - } - - if (i == VECTOR_INDEX(script->hq, idx).size) { - struct map_session_data *sd; + return false; + } - for (i = 0; i < VECTOR_INDEX(script->hq, idx).size; i++) { - if (VECTOR_INDEX(script->hq, idx).item[i] == 0) { - break; - } - } + queue = &VECTOR_INDEX(script->hq, idx); + pos = queue->size; + for (i = queue->size-1; i >= 0; i--) { + /* Looping backwards in order to scan the entire array for matches + * and at the same time, grab the first empty position. */ + if (queue->item[i] == var) + return false; + if (queue->item[i] == 0) + pos = i; + } - if (i == VECTOR_INDEX(script->hq, idx).size) - RECREATE(VECTOR_INDEX(script->hq, idx).item, int, ++VECTOR_INDEX(script->hq, idx).size); + if (pos == queue->size) + RECREATE(queue->item, int, ++queue->size); - VECTOR_INDEX(script->hq, idx).item[i] = var; - VECTOR_INDEX(script->hq, idx).items++; - if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) != NULL) { - for (i = 0; i < sd->queues_count; i++) { - if (sd->queues[i] == -1) { - break; - } - } + queue->item[i] = var; + queue->items++; - if (i == sd->queues_count) - RECREATE(sd->queues, int, ++sd->queues_count); + if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) != NULL) { + ARR_FIND(0, sd->queues_count, i, sd->queues[i] == -1); - sd->queues[i] = idx; - } + if (i == sd->queues_count) + RECREATE(sd->queues, int, ++sd->queues_count); - } + sd->queues[i] = idx; } - return false; + return true; } -/* queueadd(.@queue_id,.@var_id); */ -/* adds a new entry to the queue, returns 1 if already in queue, 0 otherwise */ -BUILDIN(queueadd) { + +/** + * Script command queueadd: Adds a new entry to the given queue. + * + * Returns 1 if already in queue or in case of error, 0 otherwise. + * + * @code{.herc} + * .@size = queuesize(.@queue_id); + * @endcode + */ +BUILDIN(queueadd) +{ int idx = script_getnum(st, 2); int var = script_getnum(st, 3); - script_pushint(st,script->queue_add(idx,var)?1:0); + if (script->queue_add(idx, var)) + script_pushint(st, 0); + else + script_pushint(st, 1); return true; } -bool script_hqueue_remove(int idx, int var) { + +/** + * Removes an entry from the given queue. + * + * @param idx The queue index. + * @param var The entry to remove. + * @retval true if the entry was removed. + * @retval false if the entry wasn't in queue. + */ +bool script_hqueue_remove(int idx, int var) +{ + int i; + struct map_session_data *sd = NULL; + struct script_queue *queue = NULL; + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("script_hqueue_remove: unknown queue id %d (used with var %d)\n",idx,var); - return true; - } else { - int i; + return false; + } - for (i = 0; i < VECTOR_INDEX(script->hq, idx).size; i++) { - if (VECTOR_INDEX(script->hq, idx).item[i] == var) { - break; - } - } + queue = &VECTOR_INDEX(script->hq, idx); - if (i != VECTOR_INDEX(script->hq, idx).size) { - struct map_session_data *sd; + ARR_FIND(0, queue->size, i, queue->item[i] == var); - VECTOR_INDEX(script->hq, idx).item[i] = -1; - VECTOR_INDEX(script->hq, idx).items--; + if (i == queue->size) + return false; - if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) != NULL) { - for(i = 0; i < sd->queues_count; i++) { - if( sd->queues[i] == idx ) { - break; - } - } + queue->item[i] = -1; + queue->items--; - if( i != sd->queues_count ) - sd->queues[i] = -1; - } + if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) != NULL) { + ARR_FIND(0, sd->queues_count, i, sd->queues[i] == -1); - } + if (i != sd->queues_count) + sd->queues[i] = -1; } - return false; + return true; } -/* queueremove(.@queue_id,.@var_id); */ -/* removes a entry from the queue, returns 1 if not in queue, 0 otherwise */ -BUILDIN(queueremove) { + +/** + * Script command queueremove: Removes an entry from a queue. + * + * Returns 0 on success, 1 if the item wasn't in queue. + * + * @code{.herc} + * queueremove(.@queue_id, .@value); + * @endcode + */ +BUILDIN(queueremove) +{ int idx = script_getnum(st, 2); int var = script_getnum(st, 3); - script_pushint(st, script->queue_remove(idx,var)?1:0); + if (script->queue_remove(idx,var)) + script_pushint(st, 0); + else + script_pushint(st, 1); return true; } -/* queueopt(.@queue_id,optionType,); */ -/* modifies the queue's options, when val is not provided the option is removed */ -/* when OnMapChange event is triggered, it sets a temp char var @QMapChangeTo$ with the destination map name */ -/* returns 1 when fails, 0 on success */ -BUILDIN(queueopt) { +/** + * Script command queueopt: Modifies the options of a queue. + * + * When the option value isn't provided, the option is removed. + * + * Returns 0 on success, 1 on failure. + * + * The optionType is one of: + * - HQO_OnDeath + * - HQO_OnLogOut + * - HQO_OnMapChange + * + * When the OnMapChange event is triggered, it sets a temporary character + * variable \c @QMapChangeTo with the destination map name. + * + * @code{.herc} + * queueopt(.@queue_id, optionType, ); + * @endcode + */ +BUILDIN(queueopt) +{ int idx = script_getnum(st, 2); int var = script_getnum(st, 3); + struct script_queue *queue = NULL; if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("buildin_queueopt: unknown queue id %d\n",idx); script_pushint(st, 1); - } else if( var <= SQO_NONE || var >= SQO_MAX ) { - ShowWarning("buildin_queueopt: unknown optionType %d\n",var); - script_pushint(st, 1); - } else { - switch ((enum ScriptQueueOptions)var) { - case SQO_ONDEATH: - if( script_hasdata(st, 4) ) - safestrncpy(VECTOR_INDEX(script->hq, idx).event_death, script_getstr(st, 4), EVENT_NAME_LENGTH); - else - VECTOR_INDEX(script->hq, idx).event_death[0] = '\0'; - break; - case SQO_ONLOGOUT: - if( script_hasdata(st, 4) ) - safestrncpy(VECTOR_INDEX(script->hq, idx).event_logout, script_getstr(st, 4), EVENT_NAME_LENGTH); - else - VECTOR_INDEX(script->hq, idx).event_logout[0] = '\0'; - break; - case SQO_ONMAPCHANGE: - if( script_hasdata(st, 4) ) - safestrncpy(VECTOR_INDEX(script->hq, idx).event_mapchange, script_getstr(st, 4), EVENT_NAME_LENGTH); - else - VECTOR_INDEX(script->hq, idx).event_mapchange[0] = '\0'; - break; - default: - ShowWarning("buildin_queueopt: unsupported optionType %d\n",var); - script_pushint(st, 1); - break; - } + return true; } + queue = &VECTOR_INDEX(script->hq, idx); + + switch (var) { + case SQO_ONDEATH: + if (script_hasdata(st, 4)) + safestrncpy(queue->event_death, script_getstr(st, 4), EVENT_NAME_LENGTH); + else + queue->event_death[0] = '\0'; + break; + case SQO_ONLOGOUT: + if (script_hasdata(st, 4)) + safestrncpy(queue->event_logout, script_getstr(st, 4), EVENT_NAME_LENGTH); + else + queue->event_logout[0] = '\0'; + break; + case SQO_ONMAPCHANGE: + if (script_hasdata(st, 4)) + safestrncpy(queue->event_mapchange, script_getstr(st, 4), EVENT_NAME_LENGTH); + else + queue->event_mapchange[0] = '\0'; + break; + default: + ShowWarning("buildin_queueopt: unsupported optionType %d\n",var); + script_pushint(st, 1); + return true; + } + script_pushint(st, 1); return true; } + +/** + * Deletes a queue. + * + * @param idx The queue index. + * + * @retval true if the queue was correctly deleted. + * @retval false if the queue didn't exist. + */ bool script_hqueue_del(int idx) { + int i; + struct script_queue *queue = NULL; + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("script_queue_del: unknown queue id %d\n",idx); - return true; - } else { - int i; - for (i = 0; i < VECTOR_INDEX(script->hq, idx).size; i++) { - struct map_session_data *sd; - if (VECTOR_INDEX(script->hq, idx).item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(VECTOR_INDEX(script->hq, idx).item[i])) != NULL) { - int j; - for(j = 0; j < sd->queues_count; j++) { - if (sd->queues[j] == VECTOR_INDEX(script->hq, idx).item[i]) { - break; - } - } + return false; + } - if( j != sd->queues_count ) - sd->queues[j] = -1; - } - VECTOR_INDEX(script->hq, idx).item[i] = 0; + queue = &VECTOR_INDEX(script->hq, idx); + + for (i = 0; i < queue->size; i++) { + struct map_session_data *sd = NULL; + if (queue->item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(queue->item[i])) != NULL) { + int j; + ARR_FIND(0, sd->queues_count, j, sd->queues[j] == queue->item[i]); + + if (j != sd->queues_count) + sd->queues[j] = -1; } - VECTOR_INDEX(script->hq, idx).size = -1; - VECTOR_INDEX(script->hq, idx).items = 0; + queue->item[i] = 0; } - return false; + queue->size = -1; + queue->items = 0; + + return true; } -/* queuedel(.@queue_id); */ -/* deletes queue of id .@queue_id, returns 1 if id not found, 0 otherwise */ -BUILDIN(queuedel) { + +/** + * Script command queuedel: Deletes a queue. + * + * Returns 0 on success, 1 if the queue doesn't exist. + * + * @code{.herc} + * queuedel(.@queue_id); + * @endcode + */ +BUILDIN(queuedel) +{ int idx = script_getnum(st, 2); - script_pushint(st,script->queue_del(idx)?1:0); + if (script->queue_del(idx)) + script_pushint(st, 0); + else + script_pushint(st, 1); return true; } -void script_hqueue_clear(int idx) { + +/** + * Clears a queue. + * + * @param idx The queue index. + */ +void script_hqueue_clear(int idx) +{ + int i; + struct script_queue *queue = NULL; + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { ShowWarning("script_hqueue_clear: unknown queue id %d\n",idx); return; - } else { - struct map_session_data *sd; - int i, j; + } - for(i = 0; i < VECTOR_INDEX(script->hq, idx).size; i++) { - if (VECTOR_INDEX(script->hq, idx).item[i] > 0) { + queue = &VECTOR_INDEX(script->hq, idx); - if (VECTOR_INDEX(script->hq, idx).item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(VECTOR_INDEX(script->hq, idx).item[i])) != NULL) { - for(j = 0; j < sd->queues_count; j++) { - if( sd->queues[j] == idx ) { - break; - } - } + for(i = 0; i < queue->size; i++) { + if (queue->item[i] > 0) { + struct map_session_data *sd = NULL; - if( j != sd->queues_count ) - sd->queues[j] = -1; - } - VECTOR_INDEX(script->hq, idx).item[i] = 0; + if (queue->item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(queue->item[i])) != NULL) { + int j; + ARR_FIND(0, sd->queues_count, j, sd->queues[j] == idx); + + if (j != sd->queues_count) + sd->queues[j] = -1; } + queue->item[i] = 0; } - VECTOR_INDEX(script->hq, idx).items = 0; } + queue->items = 0; + return; } -/* set .@id, queueiterator(.@queue_id); */ -/* creates a new queue iterator, returns its id */ -BUILDIN(queueiterator) { + +/** + * Script command queueiterator: Creates a new queue iterator. + * + * Returns the iterator's id or -1 in case of failure. + * + * @code{.herc} + * .@id = queueiterator(.@queue_id); + * @endcode + */ +BUILDIN(queueiterator) +{ int qid = script_getnum(st, 2); struct script_queue *queue = NULL; - int idx = VECTOR_LENGTH(script->hqi); + struct script_queue_iterator *iter = NULL; int i; if( qid < 0 || qid >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, qid).size == -1 || !(queue = script->queue(qid)) ) { ShowWarning("queueiterator: invalid queue id %d\n",qid); + script_pushint(st, -1); return true; } /* what if queue->size is 0? (iterating a empty queue?) */ - if( queue->size <= 0 ) { + if (queue->size <= 0) { ShowWarning("queueiterator: attempting to iterate on on empty queue id %d!\n",qid); + script_pushint(st, -1); return true; } - for (i = 0; i < VECTOR_LENGTH(script->hqi); i++) { - if (VECTOR_INDEX(script->hqi, idx).items == -1) { - break; - } - } + ARR_FIND(0, VECTOR_LENGTH(script->hqi), i, VECTOR_INDEX(script->hqi, i).items == -1); if (i == VECTOR_LENGTH(script->hqi)) { VECTOR_ENSURE(script->hqi, 1, 1); VECTOR_PUSHZEROED(script->hqi); - } else - idx = i; + } - RECREATE(VECTOR_INDEX(script->hqi, idx).item, int, queue->size); + iter = &VECTOR_INDEX(script->hqi, i); - memcpy(VECTOR_INDEX(script->hqi, idx).item, queue->item, sizeof(int)*queue->size); + RECREATE(iter->item, int, queue->size); + memcpy(iter->item, queue->item, sizeof(int)*queue->size); - VECTOR_INDEX(script->hqi, idx).items = queue->size; - VECTOR_INDEX(script->hqi, idx).pos = 0; + iter->items = queue->size; + iter->pos = 0; - script_pushint(st,idx); + script_pushint(st, i); return true; } -/* Queue Iterator Get Next */ -/* returns next/first member in the iterator, 0 if none */ -BUILDIN(qiget) { + +/** + * Script command qiget: returns the next/first member in the iterator. + * + * Returns 0 if there's no next item. + * + * @code{.herc} + * for (.@i = qiget(.@iter); qicheck(.@iter); .@i = qiget(.@iter)) { + * // ... + * } + * @endcode + */ +BUILDIN(qiget) +{ int idx = script_getnum(st, 2); struct script_queue_iterator *it = NULL; @@ -19107,9 +19233,20 @@ BUILDIN(qiget) { script_pushint(st, it->item[it->pos++]); return true; } -/* Queue Iterator Check */ -/* returns 1:0 if there is the current member in the iterator exists */ -BUILDIN(qicheck) { + +/** + * Script command qicheck: Checks if the current member in the given iterator exists. + * + * Returns 1 if it exists, 0 otherwise. + * + * @code{.herc} + * for (.@i = qiget(.@iter); qicheck(.@iter); .@i = qiget(.@iter)) { + * // ... + * } + * @endcode + */ +BUILDIN(qicheck) +{ int idx = script_getnum(st, 2); struct script_queue_iterator *it = NULL; @@ -19129,20 +19266,31 @@ BUILDIN(qicheck) { return true; } -/* Queue Iterator Check */ -BUILDIN(qiclear) { + +/** + * Script command qiclear: Destroys a queue iterator. + * + * Returns 0 on success, 1 on failure. + * + * @code{.herc} + * qiclear(.@iter); + * @endcode + */ +BUILDIN(qiclear) +{ int idx = script_getnum(st, 2); if (idx < 0 || idx >= VECTOR_LENGTH(script->hqi)) { ShowWarning("buildin_qiclear: unknown queue iterator id %d\n",idx); script_pushint(st, 1); - } else { - VECTOR_INDEX(script->hqi, idx).items = -1; - script_pushint(st, 0); + return true; } + VECTOR_INDEX(script->hqi, idx).items = -1; + script_pushint(st, 0); return true; } + /** * packageitem({}) * when no item id is provided it tries to assume it comes from the current item id being processed (if any) -- cgit v1.2.3-70-g09d2 From 5869aadef89270cf38bee53f5ce3959142dde10a Mon Sep 17 00:00:00 2001 From: AnnieRuru Date: Thu, 5 Nov 2015 06:22:20 +0800 Subject: Fix @QMapChangeTo$ not usable when HQO_OnMapChange triggered - also add documentation for it --- doc/script_commands.txt | 3 +++ src/map/pc.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 28c218eba..6e2b92417 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -8987,6 +8987,9 @@ Modifies 's . When