diff options
-rw-r--r-- | src/map/battleground.c | 143 | ||||
-rw-r--r-- | src/map/clif.c | 6 | ||||
-rw-r--r-- | src/map/script.c | 126 | ||||
-rw-r--r-- | src/map/script.h | 9 |
4 files changed, 127 insertions, 157 deletions
diff --git a/src/map/battleground.c b/src/map/battleground.c index 2b7614761..208b4b99f 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -471,24 +471,34 @@ struct bg_arena *bg_name2arena (char *name) { } return NULL; } -int bg_id2pos ( int queue_id, int account_id ) { + +/** + * Returns a character's position in a battleground's queue. + * + * @param queue_id The ID of the battleground's queue. + * @param account_id The character's account ID. + * + * @return the position (starting at 1). + * @retval 0 if the queue doesn't exist or the given account ID isn't present in it. + */ +int bg_id2pos(int queue_id, int account_id) +{ struct script_queue *queue = script->queue(queue_id); - if( queue ) { - int i, pos = 1; - for(i = 0; i < queue->size; i++ ) { - if( queue->item[i] > 0 ) { - if( queue->item[i] == account_id ) { - return pos; - } - pos++; - } + if (queue) { + int i; + ARR_FIND(0, VECTOR_LENGTH(queue->entries), i, VECTOR_INDEX(queue->entries, i) == account_id); + if (i != VECTOR_LENGTH(queue->entries)) { + return i+1; } } return 0; } -void bg_queue_ready_ack (struct bg_arena *arena, struct map_session_data *sd, bool response) { + +void bg_queue_ready_ack(struct bg_arena *arena, struct map_session_data *sd, bool response) +{ nullpo_retv(arena); nullpo_retv(sd); + if( arena->begin_timer == INVALID_TIMER || !sd->bg_queue.arena || sd->bg_queue.arena != arena ) { bg->queue_pc_cleanup(sd); return; @@ -500,14 +510,14 @@ void bg_queue_ready_ack (struct bg_arena *arena, struct map_session_data *sd, bo int i, count = 0; sd->bg_queue.ready = 1; - for( i = 0; i < queue->size; i++ ) { - if (queue->item[i] > 0 && (sd = map->id2sd(queue->item[i])) != NULL) { - if( sd->bg_queue.ready == 1 ) - count++; - } + for (i = 0; i < VECTOR_LENGTH(queue->entries); i++) { + struct map_session_data *tsd = map->id2sd(VECTOR_INDEX(queue->entries, i)); + + if (tsd != NULL && tsd->bg_queue.ready == 1) + count++; } /* check if all are ready then cancel timer, and start game */ - if( count == queue->items ) { + if (count == VECTOR_LENGTH(queue->entries)) { timer->delete(arena->begin_timer,bg->begin_timer); arena->begin_timer = INVALID_TIMER; bg->begin(arena); @@ -539,19 +549,20 @@ void bg_match_over(struct bg_arena *arena, bool canceled) { return; arena->ongoing = false; - for( i = 0; i < queue->size; i++ ) { - struct map_session_data * sd = NULL; + for (i = 0; i < VECTOR_LENGTH(queue->entries); i++) { + struct map_session_data *sd = map->id2sd(VECTOR_INDEX(queue->entries, i)); - if (queue->item[i] > 0 && (sd = map->id2sd(queue->item[i])) != NULL) { - if( sd->bg_queue.arena ) { - bg->team_leave(sd, 0); - bg->queue_pc_cleanup(sd); - } - if (canceled) - clif->messagecolor_self(sd->fd, COLOR_RED, "BG Match Canceled: not enough players"); - else - pc_setglobalreg(sd, script->add_str(arena->delay_var), (unsigned int)time(NULL)); + if (sd == NULL) + continue; + + if (sd->bg_queue.arena) { + bg->team_leave(sd, 0); + bg->queue_pc_cleanup(sd); } + if (canceled) + clif->messagecolor_self(sd->fd, COLOR_RED, "BG Match Canceled: not enough players"); + else + pc_setglobalreg(sd, script->add_str(arena->delay_var), (unsigned int)time(NULL)); } arena->begin_timer = INVALID_TIMER; @@ -564,15 +575,16 @@ void bg_begin(struct bg_arena *arena) { int i, count = 0; nullpo_retv(arena); - for( i = 0; i < queue->size; i++ ) { - struct map_session_data * sd = NULL; + for (i = 0; i < VECTOR_LENGTH(queue->entries); i++) { + struct map_session_data *sd = map->id2sd(VECTOR_INDEX(queue->entries, i)); - if (queue->item[i] > 0 && (sd = map->id2sd(queue->item[i])) != NULL) { - if( sd->bg_queue.ready == 1 ) - count++; - else - bg->queue_pc_cleanup(sd); - } + if (sd == NULL) + continue; + + if (sd->bg_queue.ready == 1) + count++; + else + bg->queue_pc_cleanup(sd); } /* TODO/FIXME? I *think* it should check what kind of queue the player used, then check if his party/guild * (his team) still meet the join criteria (sort of what bg->can_queue does) @@ -591,25 +603,24 @@ void bg_begin(struct bg_arena *arena) { mapreg->setregstr(script->add_str("$@bg_delay_var$"),bg->gdelay_var); count = 0; - for( i = 0; i < queue->size; i++ ) { - struct map_session_data * sd = NULL; - - if (queue->item[i] > 0 && (sd = map->id2sd(queue->item[i])) != NULL) { - if( sd->bg_queue.ready == 1 ) { - mapreg->setreg(reference_uid(script->add_str("$@bg_member"), count), sd->status.account_id); - mapreg->setreg(reference_uid(script->add_str("$@bg_member_group"), count), - sd->bg_queue.type == BGQT_GUILD ? sd->status.guild_id : - sd->bg_queue.type == BGQT_PARTY ? sd->status.party_id : - 0 - ); - mapreg->setreg(reference_uid(script->add_str("$@bg_member_type"), count), - sd->bg_queue.type == BGQT_GUILD ? 1 : - sd->bg_queue.type == BGQT_PARTY ? 2 : - 0 - ); - count++; - } - } + for (i = 0; i < VECTOR_LENGTH(queue->entries); i++) { + struct map_session_data *sd = map->id2sd(VECTOR_INDEX(queue->entries, i)); + + if (sd == NULL || sd->bg_queue.ready != 1) + continue; + + mapreg->setreg(reference_uid(script->add_str("$@bg_member"), count), sd->status.account_id); + mapreg->setreg(reference_uid(script->add_str("$@bg_member_group"), count), + sd->bg_queue.type == BGQT_GUILD ? sd->status.guild_id : + sd->bg_queue.type == BGQT_PARTY ? sd->status.party_id : + 0 + ); + mapreg->setreg(reference_uid(script->add_str("$@bg_member_type"), count), + sd->bg_queue.type == BGQT_GUILD ? 1 : + sd->bg_queue.type == BGQT_PARTY ? 2 : + 0 + ); + count++; } mapreg->setreg(script->add_str("$@bg_member_size"),count); @@ -650,10 +661,10 @@ void bg_queue_pregame(struct bg_arena *arena) { nullpo_retv(arena); queue = script->queue(arena->queue_id); - for( i = 0; i < queue->size; i++ ) { - struct map_session_data * sd = NULL; + for (i = 0; i < VECTOR_LENGTH(queue->entries); i++) { + struct map_session_data *sd = map->id2sd(VECTOR_INDEX(queue->entries, i)); - if (queue->item[i] > 0 && (sd = map->id2sd(queue->item[i])) != NULL) { + if (sd != NULL) { clif->bgqueue_battlebegins(sd,arena->id,SELF); } } @@ -671,7 +682,7 @@ void bg_queue_check(struct bg_arena *arena) { nullpo_retv(arena); queue = script->queue(arena->queue_id); - count = queue->items; + count = VECTOR_LENGTH(queue->entries); if( count == arena->max_players ) { if( arena->fillup_timer != INVALID_TIMER ) { timer->delete(arena->fillup_timer,bg->fillup_timer); @@ -720,7 +731,7 @@ void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_q break; } - if( !(queue = script->queue(arena->queue_id)) || (queue->items+count) > arena->max_players ) { + if( !(queue = script->queue(arena->queue_id)) || (VECTOR_LENGTH(queue->entries)+count) > arena->max_players ) { clif->bgqueue_ack(sd,BGQA_FAIL_PPL_OVERAMOUNT,arena->id); return; } @@ -731,8 +742,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, queue->items); - clif->bgqueue_update_info(sd,arena->id, queue->items); + clif->bgqueue_joined(sd, VECTOR_LENGTH(queue->entries)); + clif->bgqueue_update_info(sd,arena->id, VECTOR_LENGTH(queue->entries)); break; case BGQT_PARTY: { struct party_data *p = party->search(sd->status.party_id); @@ -742,8 +753,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, queue->items); - clif->bgqueue_update_info(p->data[i].sd,arena->id, queue->items); + clif->bgqueue_joined(p->data[i].sd, VECTOR_LENGTH(queue->entries)); + clif->bgqueue_update_info(p->data[i].sd,arena->id, VECTOR_LENGTH(queue->entries)); } } break; @@ -755,8 +766,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, queue->items); - clif->bgqueue_update_info(sd->guild->member[i].sd,arena->id, queue->items); + clif->bgqueue_joined(sd->guild->member[i].sd, VECTOR_LENGTH(queue->entries)); + clif->bgqueue_update_info(sd->guild->member[i].sd,arena->id, VECTOR_LENGTH(queue->entries)); } break; } diff --git a/src/map/clif.c b/src/map/clif.c index 2b9ed43c6..621f0b44a 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -612,10 +612,10 @@ bool clif_send(const void* buf, int len, struct block_list* bl, enum send_target if( sd && sd->bg_queue.arena ) { 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; + for (i = 0; i < VECTOR_LENGTH(queue->entries); i++) { + struct map_session_data *qsd = map->id2sd(VECTOR_INDEX(queue->entries, i)); - if (queue->item[i] > 0 && (qsd = map->id2sd(queue->item[i])) != NULL) { + if (qsd != NULL) { WFIFOHEAD(qsd->fd,len); memcpy(WFIFOP(qsd->fd,0), buf, len); WFIFOSET(qsd->fd,len); diff --git a/src/map/script.c b/src/map/script.c index 768677d12..ac981dbbd 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -4628,9 +4628,7 @@ void do_final_script(void) { aFree(script->buildin); for (i = 0; i < VECTOR_LENGTH(script->hq); i++) { - if (VECTOR_INDEX(script->hq, i).item != NULL) { - aFree(VECTOR_INDEX(script->hq, i).item); - } + VECTOR_CLEAR(VECTOR_INDEX(script->hq, i).entries); } VECTOR_CLEAR(script->hq); @@ -18799,7 +18797,7 @@ BUILDIN(montransform) { */ struct script_queue *script_hqueue_get(int idx) { - if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, idx).valid) return NULL; return &VECTOR_INDEX(script->hq, idx); } @@ -18814,21 +18812,18 @@ int script_hqueue_create(void) struct script_queue *queue = NULL; int i; - ARR_FIND(0, VECTOR_LENGTH(script->hq), i, VECTOR_INDEX(script->hq, i).size == -1); + ARR_FIND(0, VECTOR_LENGTH(script->hq), i, !VECTOR_INDEX(script->hq, i).valid); if (i == VECTOR_LENGTH(script->hq)) { VECTOR_ENSURE(script->hq, 1, 1); VECTOR_PUSHZEROED(script->hq); } - queue = &VECTOR_INDEX(script->hq, i); + memset(&VECTOR_INDEX(script->hq, i), 0, sizeof(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'; + queue->valid = true; return i; } @@ -18858,13 +18853,13 @@ BUILDIN(queuesize) { int idx = script_getnum(st, 2); - if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || VECTOR_INDEX(script->hq, idx).size == -1) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, idx).valid) { ShowWarning("buildin_queuesize: unknown queue id %d\n",idx); script_pushint(st, 0); return true; } - script_pushint(st, VECTOR_INDEX(script->hq, idx).items); + script_pushint(st, VECTOR_LENGTH(VECTOR_INDEX(script->hq, idx).entries)); return true; } @@ -18878,31 +18873,24 @@ BUILDIN(queuesize) */ bool script_hqueue_add(int idx, int var) { - int i, pos; + 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) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, idx).valid) { ShowWarning("script_hqueue_add: unknown queue id %d\n",idx); return false; } 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 (pos == queue->size) - RECREATE(queue->item, int, ++queue->size); + ARR_FIND(0, VECTOR_LENGTH(queue->entries), i, VECTOR_INDEX(queue->entries, i) == var); + if (i != VECTOR_LENGTH(queue->entries)) { + return false; // Entry already exists + } - queue->item[i] = var; - queue->items++; + VECTOR_ENSURE(queue->entries, 1, 1); + VECTOR_PUSH(queue->entries, var); if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) != NULL) { ARR_FIND(0, sd->queues_count, i, sd->queues[i] == -1); @@ -18952,20 +18940,18 @@ bool script_hqueue_remove(int idx, int var) 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) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, idx).valid) { ShowWarning("script_hqueue_remove: unknown queue id %d (used with var %d)\n",idx,var); return false; } queue = &VECTOR_INDEX(script->hq, idx); - ARR_FIND(0, queue->size, i, queue->item[i] == var); - - if (i == queue->size) + ARR_FIND(0, VECTOR_LENGTH(queue->entries), i, VECTOR_INDEX(queue->entries, i) == var); + if (i == VECTOR_LENGTH(queue->entries)) return false; - queue->item[i] = -1; - queue->items--; + VECTOR_ERASE(queue->entries, i); if (var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) != NULL) { ARR_FIND(0, sd->queues_count, i, sd->queues[i] == -1); @@ -19023,7 +19009,7 @@ BUILDIN(queueopt) 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) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, idx).valid) { ShowWarning("buildin_queueopt: unknown queue id %d\n",idx); script_pushint(st, 0); return true; @@ -19069,29 +19055,10 @@ BUILDIN(queueopt) */ 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); + if (!script->queue_clear(idx)) return false; - } - 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; - } - queue->item[i] = 0; - } - queue->size = -1; - queue->items = 0; + VECTOR_INDEX(script->hq, idx).valid = false; return true; } @@ -19121,36 +19088,36 @@ BUILDIN(queuedel) * Clears a queue. * * @param idx The queue index. + * + * @retval true if the queue was correctly cleared. + * @retval false if the queue didn't exist. */ -void script_hqueue_clear(int idx) +bool 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) { + if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, idx).valid) { ShowWarning("script_hqueue_clear: unknown queue id %d\n",idx); - return; + return false; } queue = &VECTOR_INDEX(script->hq, idx); - for(i = 0; i < queue->size; i++) { - if (queue->item[i] > 0) { - struct map_session_data *sd = NULL; + while (VECTOR_LENGTH(queue->entries) > 0) { + int entry = VECTOR_POP(queue->entries); + 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] == idx); + if (entry >= START_ACCOUNT_NUM && (sd = map->id2sd(entry)) != NULL) { + int i; + ARR_FIND(0, sd->queues_count, i, sd->queues[i] == idx); - if (j != sd->queues_count) - sd->queues[j] = -1; - } - queue->item[i] = 0; + if (i != sd->queues_count) + sd->queues[i] = -1; } } - queue->items = 0; + VECTOR_CLEAR(queue->entries); - return; + return true; } /** @@ -19169,19 +19136,12 @@ BUILDIN(queueiterator) 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)) ) { + if (qid < 0 || qid >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, qid).valid || !(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) { - ShowWarning("queueiterator: attempting to iterate on on empty queue id %d!\n",qid); - script_pushint(st, -1); - return true; - } - ARR_FIND(0, VECTOR_LENGTH(script->hqi), i, VECTOR_INDEX(script->hqi, i).items == -1); if (i == VECTOR_LENGTH(script->hqi)) { @@ -19191,10 +19151,10 @@ BUILDIN(queueiterator) iter = &VECTOR_INDEX(script->hqi, i); - RECREATE(iter->item, int, queue->size); - memcpy(iter->item, queue->item, sizeof(int)*queue->size); + RECREATE(iter->item, int, VECTOR_LENGTH(queue->entries)); + memcpy(iter->item, VECTOR_DATA(queue->entries), sizeof(VECTOR_FIRST(queue->entries))*VECTOR_LENGTH(queue->entries)); - iter->items = queue->size; + iter->items = VECTOR_LENGTH(queue->entries); iter->pos = 0; script_pushint(st, i); diff --git a/src/map/script.h b/src/map/script.h index aa31389f6..6b728ab88 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -397,10 +397,9 @@ struct script_stack { * @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 + int id; ///< Queue identifier + VECTOR_DECL(int) entries; ///< Items in the queue. + bool valid; ///< Whether the queue is valid. /// Events char event_logout[EVENT_NAME_LENGTH]; ///< Logout event char event_death[EVENT_NAME_LENGTH]; ///< Death event @@ -678,7 +677,7 @@ struct script_interface { bool (*queue_del) (int idx); bool (*queue_remove) (int idx, int var); int (*queue_create) (void); - void (*queue_clear) (int idx); + bool (*queue_clear) (int idx); /* */ const char * (*parse_curly_close) (const char *p); const char * (*parse_syntax_close) (const char *p); |