summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map/battleground.c143
-rw-r--r--src/map/clif.c6
-rw-r--r--src/map/script.c126
-rw-r--r--src/map/script.h9
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);