summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/battleground.c82
-rw-r--r--src/map/battleground.h1
-rw-r--r--src/map/clif.c31
-rw-r--r--src/map/clif.h2
-rw-r--r--src/map/map.c2
-rw-r--r--src/map/script.c89
-rw-r--r--src/map/script.h3
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];