diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map/battleground.c | 82 | ||||
-rw-r--r-- | src/map/battleground.h | 1 | ||||
-rw-r--r-- | src/map/clif.c | 31 | ||||
-rw-r--r-- | src/map/clif.h | 2 | ||||
-rw-r--r-- | src/map/map.c | 2 | ||||
-rw-r--r-- | src/map/script.c | 89 | ||||
-rw-r--r-- | src/map/script.h | 3 |
7 files changed, 122 insertions, 88 deletions
diff --git a/src/map/battleground.c b/src/map/battleground.c index 198ad6bad..3b2e0b1ce 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -93,6 +93,15 @@ int bg_team_join(int bg_id, struct map_session_data *sd) bg->members[i].sd = sd; bg->members[i].x = sd->bl.x; bg->members[i].y = sd->bl.y; + /* populate 'where i came from' */ + if(map[sd->bl.m].flag.nosave || map[sd->bl.m].instance_id >= 0){ + struct map_data *m=&map[sd->bl.m]; + if(m->save.map) + memcpy(&bg->members[i].source,&m->save,sizeof(struct point)); + else + memcpy(&bg->members[i].source,&sd->status.save_point,sizeof(struct point)); + } else + memcpy(&bg->members[i].source,&sd->status.last_point,sizeof(struct point)); bg->count++; guild->send_dot_remove(sd); @@ -115,7 +124,6 @@ int bg_team_leave(struct map_session_data *sd, int flag) if( sd == NULL || !sd->bg_id ) return 0; - bg_send_dot_remove(sd); bg_id = sd->bg_id; sd->bg_id = 0; @@ -124,21 +132,28 @@ int bg_team_leave(struct map_session_data *sd, int flag) return 0; ARR_FIND(0, MAX_BG_MEMBERS, i, bg_data->members[i].sd == sd); - if( i < MAX_BG_MEMBERS ) // Removes member from BG + if( i < MAX_BG_MEMBERS ) { // Removes member from BG + if( sd->bg_queue.arena ) { + bg->queue_pc_cleanup(sd); + pc->setpos(sd,bg_data->members[i].source.map, bg_data->members[i].source.x, bg_data->members[i].source.y, CLR_OUTSIGHT); + } memset(&bg_data->members[i], 0, sizeof(bg_data->members[0])); - bg_data->count--; + } - if( flag ) - sprintf(output, "Server : %s has quit the game...", sd->status.name); - else - sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name); - clif->bg_message(bg_data, 0, "Server", output, strlen(output) + 1); + if( --bg_data->count != 0 ) { + if( flag ) + sprintf(output, "Server : %s has quit the game...", sd->status.name); + else + sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name); + clif->bg_message(bg_data, 0, "Server", output, strlen(output) + 1); + } if( bg_data->logout_event[0] && flag ) npc_event(sd, bg_data->logout_event, 0); - - if( sd->bg_queue.arena ) + + if( sd->bg_queue.arena ) { bg->queue_pc_cleanup(sd); + } return bg_data->count; } @@ -415,10 +430,13 @@ struct bg_arena *bg_name2arena (char *name) { int bg_id2pos ( int queue_id, int account_id ) { struct hQueue *queue = script->queue(queue_id); if( queue ) { - int i; - for(i = 0; i < queue->items; i++ ) { - if( queue->item[i] == account_id ) { - return i; + 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++; } } } @@ -436,14 +454,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->items; i++ ) { - if( ( sd = iMap->id2sd(queue->item[i]) ) ) { + for( i = 0; i < queue->size; i++ ) { + if( queue->item[i] > 0 && ( sd = iMap->id2sd(queue->item[i]) ) ) { if( sd->bg_queue.ready == 1 ) count++; } } /* check if all are ready then cancell timer, and start game */ - if( count == i ) { + if( count == queue->items ) { iTimer->delete_timer(arena->begin_timer,bg->begin_timer); arena->begin_timer = INVALID_TIMER; bg->begin(arena); @@ -454,7 +472,10 @@ void bg_queue_ready_ack (struct bg_arena *arena, struct map_session_data *sd, bo } void bg_queue_player_cleanup(struct map_session_data *sd) { if ( sd->bg_queue.client_has_bg_data ) { - clif->bgqueue_notice_delete(sd,BGQND_CLOSEWINDOW, sd->bg_queue.arena ? sd->bg_queue.arena->id : 0); + if( sd->bg_queue.arena ) + clif->bgqueue_notice_delete(sd,BGQND_CLOSEWINDOW,sd->bg_queue.arena->name); + else + clif->bgqueue_notice_delete(sd,BGQND_FAIL_NOT_QUEUING,bg->arena[0]->name); } if( sd->bg_queue.arena ) script->queue_remove(sd->bg_queue.arena->queue_id,sd->status.account_id); @@ -469,12 +490,16 @@ void bg_match_over(struct bg_arena *arena, bool canceled) { if( !arena->ongoing ) return; - - for( i = 0; i < queue->items; i++ ) { + arena->ongoing = false; + + for( i = 0; i < queue->size; i++ ) { struct map_session_data * sd = NULL; - if( ( sd = iMap->id2sd(queue->item[i]) ) ) { - bg->queue_pc_cleanup(sd); + if( queue->item[i] > 0 && ( sd = iMap->id2sd(queue->item[i]) ) ) { + if( sd->bg_queue.arena ) { + bg_team_leave(sd, 0); + bg->queue_pc_cleanup(sd); + } if( canceled ) clif->colormes(sd->fd,COLOR_RED,"BG Match Cancelled: not enough players"); else { @@ -485,7 +510,6 @@ void bg_match_over(struct bg_arena *arena, bool canceled) { arena->begin_timer = INVALID_TIMER; arena->fillup_timer = INVALID_TIMER; - arena->ongoing = false; /* reset queue */ script->queue_clear(arena->queue_id); } @@ -493,10 +517,10 @@ void bg_begin(struct bg_arena *arena) { struct hQueue *queue = &script->hq[arena->queue_id]; int i, count = 0; - for( i = 0; i < queue->items; i++ ) { + for( i = 0; i < queue->size; i++ ) { struct map_session_data * sd = NULL; - if( ( sd = iMap->id2sd(queue->item[i]) ) ) { + if( queue->item[i] > 0 && ( sd = iMap->id2sd(queue->item[i]) ) ) { if( sd->bg_queue.ready == 1 ) count++; else @@ -527,10 +551,10 @@ void bg_queue_pregame(struct bg_arena *arena) { struct hQueue *queue = &script->hq[arena->queue_id]; int i; - for( i = 0; i < queue->items; i++ ) { + for( i = 0; i < queue->size; i++ ) { struct map_session_data * sd = NULL; - if( ( sd = iMap->id2sd(queue->item[i]) ) ) { + if( queue->item[i] > 0 && ( sd = iMap->id2sd(queue->item[i]) ) ) { clif->bgqueue_battlebegins(sd,arena->id,SELF); } } @@ -594,7 +618,7 @@ void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_q clif->bgqueue_ack(sd,BGQA_FAIL_PPL_OVERAMOUNT,arena->id); return; } - + switch( type ) { case BGQT_INDIVIDUAL: sd->bg_queue.type = type; @@ -630,7 +654,7 @@ void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_q } break; } - + clif->bgqueue_ack(sd,BGQA_SUCCESS,arena->id); bg->queue_check(arena); diff --git a/src/map/battleground.h b/src/map/battleground.h index b6d95b813..1566e92b8 100644 --- a/src/map/battleground.h +++ b/src/map/battleground.h @@ -29,6 +29,7 @@ struct battleground_member_data { unsigned short x, y; struct map_session_data *sd; unsigned afk : 1; + struct point source;/* where did i come from before i join? */ }; struct battleground_data { diff --git a/src/map/clif.c b/src/map/clif.c index 117a315e9..a1e0eedb2 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -558,10 +558,10 @@ int clif_send(const void* buf, int len, struct block_list* bl, enum send_target if( sd && sd->bg_queue.arena ) { struct hQueue *queue = &script->hq[sd->bg_queue.arena->queue_id]; - for( i = 0; i < queue->items; i++ ) { + for( i = 0; i < queue->size; i++ ) { struct map_session_data * sd = NULL; - if( ( sd = iMap->id2sd(queue->item[i]) ) ) { + if( queue->item[i] > 0 && ( sd = iMap->id2sd(queue->item[i]) ) ) { WFIFOHEAD(sd->fd,len); memcpy(WFIFOP(sd->fd,0), buf, len); WFIFOSET(sd->fd,len); @@ -15894,7 +15894,7 @@ void clif_bg_message(struct battleground_data *bg, int src_id, const char *name, { struct map_session_data *sd; unsigned char *buf; - if( (sd = bg_getavailablesd(bg)) == NULL ) + if( !bg->count || (sd = bg_getavailablesd(bg)) == NULL ) return; buf = (unsigned char*)aMalloc((len + NAME_LENGTH + 8)*sizeof(unsigned char)); @@ -17426,12 +17426,12 @@ void clif_bgqueue_ack(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_ACK } -void clif_bgqueue_notice_delete(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, unsigned char arena_id) { +void clif_bgqueue_notice_delete(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, char *name) { struct packet_bgqueue_notice_delete p; p.PacketType = bgqueue_notice_deleteType; p.type = response; - safestrncpy(p.bg_name, bg->arena[arena_id]->name, sizeof(p.bg_name)); + safestrncpy(p.bg_name, name, sizeof(p.bg_name)); clif->send(&p,sizeof(p), &sd->bl, SELF); } @@ -17474,33 +17474,34 @@ void clif_bgqueue_update_info(struct map_session_data *sd, unsigned char arena_i } void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) { - //struct packet_bgqueue_checkstate *p = P2PTR(fd, bgqueue_checkstateType); /* TODO: bgqueue_notice_delete should use this p->bg_name */ - if( !bg->queue_on ) return; /* temp, until feature is complete */ + struct packet_bgqueue_checkstate *p = P2PTR(fd); + if ( sd->bg_queue.arena && sd->bg_queue.type ) { clif->bgqueue_update_info(sd,sd->bg_queue.arena->id,bg->id2pos(sd->bg_queue.arena->queue_id,sd->status.account_id)); } else - clif->bgqueue_notice_delete(sd, BGQND_FAIL_NOT_QUEUING,0);/* TODO: wrong response, should respond with p->bg_name not id 0 */ + clif->bgqueue_notice_delete(sd, BGQND_FAIL_NOT_QUEUING,p->bg_name); } void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) { - //struct packet_bgqueue_revoke_req *p = P2PTR(fd, bgqueue_revokereqType); - return; - //bg->queue_leave(sd, p->bg_name); + struct packet_bgqueue_revoke_req *p = P2PTR(fd); + + if( sd->bg_queue.arena ) + bg->queue_pc_cleanup(sd); + else + clif->bgqueue_notice_delete(sd, BGQND_FAIL_NOT_QUEUING,p->bg_name); } void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) { struct packet_bgqueue_battlebegin_ack *p = P2PTR(fd); struct bg_arena *arena; + if( !bg->queue_on ) return; /* temp, until feature is complete */ + if( ( arena = bg->name2arena(p->bg_name) ) ) { bg->queue_ready_ack(arena,sd, ( p->result == 1 ) ? true : false); } else { clif->bgqueue_ack(sd,BGQA_FAIL_BGNAME_INVALID, 0); } - //if ( p->result == 1 ) - // bg->queue_pc_ready(sd); - //else - // bg->queue_leave(sd, p->bg_name); } void clif_bgqueue_joined(struct map_session_data *sd, int pos) { diff --git a/src/map/clif.h b/src/map/clif.h index 2cf193965..f931e41e7 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -906,7 +906,7 @@ struct clif_interface { void (*elemental_updatestatus) (struct map_session_data *sd, int type); /* bgqueue */ void (*bgqueue_ack) (struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_ACK response, unsigned char arena_id); - void (*bgqueue_notice_delete) (struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, unsigned char arena_id); + void (*bgqueue_notice_delete) (struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, char *name); void (*bgqueue_update_info) (struct map_session_data *sd, unsigned char arena_id, int position); void (*bgqueue_joined) (struct map_session_data *sd, int pos); void (*bgqueue_pcleft) (struct map_session_data *sd); diff --git a/src/map/map.c b/src/map/map.c index dbada2e96..de805e83f 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1536,7 +1536,7 @@ int map_quit(struct map_session_data *sd) { if (sd->npc_id) npc_event_dequeue(sd); - if( sd->bg_id ) + if( sd->bg_id && !sd->bg_queue.arena ) /* TODO: dump this chunk after bg_queue is fully enabled */ bg_team_leave(sd,1); skill->cooldown_save(sd); diff --git a/src/map/script.c b/src/map/script.c index 2a917236a..005768a58 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -17088,7 +17088,7 @@ BUILDIN(npcskill) return true; } struct hQueue *script_hqueue_get(int idx) { - if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) + if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) return NULL; return &script->hq[idx]; } @@ -17097,7 +17097,7 @@ int script_hqueue_create(void) { int i; for(i = 0; i < script->hqs; i++) { - if( script->hq[i].items == -1 ) { + if( script->hq[i].size == -1 ) { break; } } @@ -17109,6 +17109,7 @@ int script_hqueue_create(void) { 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'; @@ -17126,47 +17127,42 @@ BUILDIN(queue) { BUILDIN(queuesize) { int idx = script_getnum(st, 2); - if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) { + if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { ShowWarning("buildin_queuesize: unknown queue id %d\n",idx); script_pushint(st, 0); } else { - /* value of script->hq[].items isn't to be trusted for we dont reduce the size when members are removed to save on memory allocation */ - int i, count = 0; - for( i = 0; i < script->hq[ idx ].items; i++ ) - if( script->hq[ idx ].item[i] != -1 ) - count++; - script_pushint(st, count); + script_pushint(st, script->hq[ idx ].items); } return true; } bool script_hqueue_add(int idx, int var) { - if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) { + if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { ShowWarning("script_hqueue_add: unknown queue id %d\n",idx); return true; } else { struct map_session_data *sd; int i; - for(i = 0; i < script->hq[idx].items; i++) { + for(i = 0; i < script->hq[idx].size; i++) { if( script->hq[idx].item[i] == var ) { return true; } } - if( i == script->hq[idx].items ) { + if( i == script->hq[idx].size ) { - for(i = 0; i < script->hq[idx].items; i++) { + for(i = 0; i < script->hq[idx].size; i++) { if( script->hq[idx].item[i] == 0 ) { break; } } - if( i == script->hq[idx].items ) - RECREATE(script->hq[idx].item, int, ++script->hq[idx].items); + if( i == script->hq[idx].size ) + RECREATE(script->hq[idx].item, int, ++script->hq[idx].size); script->hq[idx].item[i] = var; - + script->hq[idx].items++; if( var >= START_ACCOUNT_NUM && (sd = iMap->id2sd(var)) ) { for(i = 0; i < sd->queues_count; i++) { if( sd->queues[i] == -1 ) { @@ -17195,21 +17191,23 @@ BUILDIN(queueadd) { return true; } bool script_hqueue_remove(int idx, int var) { - if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) { + if( idx < 0 || idx >= script->hqs || 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].items; i++) { + for(i = 0; i < script->hq[idx].size; i++) { if( script->hq[idx].item[i] == var ) { break; } } - if( i != script->hq[idx].items ) { + if( i != script->hq[idx].size ) { struct map_session_data *sd; + script->hq[idx].item[i] = -1; + script->hq[idx].items--; if( var >= START_ACCOUNT_NUM && (sd = iMap->id2sd(var)) ) { for(i = 0; i < sd->queues_count; i++) { @@ -17245,7 +17243,7 @@ BUILDIN(queueopt) { int idx = script_getnum(st, 2); int var = script_getnum(st, 3); - if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) { + if( idx < 0 || idx >= script->hqs || 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 ) { @@ -17281,14 +17279,14 @@ BUILDIN(queueopt) { return true; } bool script_hqueue_del(int idx) { - if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) { + if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { ShowWarning("script_queue_del: unknown queue id %d\n",idx); return true; } else { struct map_session_data *sd; int i; - for(i = 0; i < script->hq[idx].items; i++) { + for(i = 0; i < script->hq[idx].size; i++) { if( script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = iMap->id2sd(script->hq[idx].item[i])) ) { int j; for(j = 0; j < sd->queues_count; j++) { @@ -17300,9 +17298,11 @@ bool script_hqueue_del(int idx) { if( j != sd->queues_count ) sd->queues[j] = -1; } + script->hq[idx].item[i] = 0; } - script->hq[idx].items = -1; + script->hq[idx].size = -1; + script->hq[idx].items = 0; } return false; } @@ -17316,29 +17316,30 @@ BUILDIN(queuedel) { return true; } void script_hqueue_clear(int idx) { - if( idx < 0 || idx >= script->hqs || script->hq[idx].items == -1 ) { + if( idx < 0 || idx >= script->hqs || 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].items; i++) { - if( script->hq[idx].item[i] != -1 ) { - - if( script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = iMap->id2sd(script->hq[idx].item[i])) ) { - for(j = 0; j < sd->queues_count; j++) { - if( sd->queues[j] == idx ) { - break; - } + for(i = 0; i < script->hq[idx].size; i++) { + if( script->hq[idx].item[i] > 0 ) { + + if( script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = iMap->id2sd(script->hq[idx].item[i])) ) { + for(j = 0; j < sd->queues_count; j++) { + if( sd->queues[j] == idx ) { + break; } - - if( j != sd->queues_count ) - sd->queues[j] = -1; } - script->hq[idx].item[i] = -1; + + if( j != sd->queues_count ) + sd->queues[j] = -1; } + script->hq[idx].item[i] = 0; } + } + script->hq[idx].items = 0; } return; } @@ -17350,11 +17351,17 @@ BUILDIN(queueiterator) { int idx = script->hqis; int i; - if( qid < 0 || qid >= script->hqs || script->hq[qid].items == -1 || !(queue = script->queue(qid)) ) { + if( qid < 0 || qid >= script->hqs || script->hq[qid].size == -1 || !(queue = script->queue(qid)) ) { ShowWarning("queueiterator: invalid queue id %d\n",qid); 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); + return true; + } + for(i = 0; i < script->hqis; i++) { if( script->hqi[i].items == -1 ) { break; @@ -17366,12 +17373,12 @@ BUILDIN(queueiterator) { script->hqi[ idx ].item = NULL; } else idx = i; + + RECREATE(script->hqi[ idx ].item, int, queue->size); - RECREATE(script->hqi[ idx ].item, int, queue->items); - - memcpy(script->hqi[idx].item, queue->item, sizeof(int)*queue->items); + memcpy(script->hqi[idx].item, queue->item, sizeof(int)*queue->size); - script->hqi[ idx ].items = queue->items; + script->hqi[ idx ].items = queue->size; script->hqi[ idx ].pos = 0; script_pushint(st,idx); diff --git a/src/map/script.h b/src/map/script.h index 82224a7af..774101eb3 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -142,7 +142,8 @@ struct script_stack { struct hQueue { int id; int *item; - int items; + 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]; |