summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/battleground.c103
-rw-r--r--src/map/battleground.h16
-rw-r--r--src/map/map.c2
-rw-r--r--src/map/script.c2
4 files changed, 104 insertions, 19 deletions
diff --git a/src/map/battleground.c b/src/map/battleground.c
index 65f475124..3640b8344 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -113,7 +113,7 @@ bool bg_team_join(int bg_id, struct map_session_data *sd) {
}
/// Single Player leaves team
-int bg_team_leave(struct map_session_data *sd, int flag) {
+int bg_team_leave(struct map_session_data *sd, enum bg_team_leave_type flag) {
int i, bg_id;
struct battleground_data *bgd;
char output[128];
@@ -137,10 +137,18 @@ int bg_team_leave(struct map_session_data *sd, int flag) {
}
if( --bgd->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);
+ switch( flag ) {
+ default:
+ case BGTL_QUIT:
+ sprintf(output, "Server : %s has quit the game...", sd->status.name);
+ break;
+ case BGTL_LEFT:
+ sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name);
+ break;
+ case BGTL_AFK:
+ sprintf(output, "Server : %s has been afk-kicked from the battlefield...", sd->status.name);
+ break;
+ }
clif->bg_message(bgd, 0, "Server", output, strlen(output) + 1);
}
@@ -252,6 +260,34 @@ int bg_send_xy_timer(int tid, int64 tick, int id, intptr_t data) {
bg->team_db->foreach(bg->team_db, bg->send_xy_timer_sub, tick);
return 0;
}
+
+enum bg_queue_types bg_str2teamtype (const char *str) {
+ char temp[200], *parse;
+ enum bg_queue_types type = BGQT_INVALID;
+
+ safestrncpy(temp, str, 200);
+
+ parse = strtok(temp,"|");
+
+ while (parse != NULL) {
+ normalize_name(parse," ");
+ if( strcmpi(parse,"all") == 0 )
+ type |= BGQT_INDIVIDUAL|BGQT_PARTY|BGQT_GUILD;
+ else if( strcmpi(parse,"party") == 0 )
+ type |= BGQT_PARTY;
+ else if( strcmpi(parse,"guild") == 0 )
+ type |= BGQT_GUILD;
+ else if( strcmpi(parse,"solo") == 0 )
+ type |= BGQT_INDIVIDUAL;
+ else {
+ ShowError("bg_str2teamtype: '%s' unknown type, skipping...\n",parse);
+ }
+ parse = strtok(NULL,"|");
+ }
+
+ return type;
+}
+
void bg_config_read(void) {
config_t bg_conf;
config_setting_t *data = NULL;
@@ -274,7 +310,7 @@ void bg_config_read(void) {
safestrncpy(bg->gdelay_var, delay_var, BG_DELAY_VAR_LENGTH);
libconfig->setting_lookup_int(settings, "maximum_afk_seconds", &bg->mafksec);
-
+
libconfig->setting_lookup_bool(settings, "feature_off", &offline);
if( offline == 0 )
@@ -286,12 +322,13 @@ void bg_config_read(void) {
for(i = 0; i < arena_count; i++) {
config_setting_t *arena = libconfig->setting_get_elem(arenas, i);
config_setting_t *reward;
- const char *aName, *aEvent, *aDelayVar;
+ const char *aName, *aEvent, *aDelayVar, *aTeamTypes;
int minLevel = 0, maxLevel = 0;
int prizeWin, prizeLoss, prizeDraw;
int minPlayers, maxPlayers, minTeamPlayers;
int maxDuration;
int fillup_duration = 0, pregame_duration = 0;
+ enum bg_queue_types allowedTypes;
bg->arena[i] = NULL;
@@ -361,6 +398,12 @@ void bg_config_read(void) {
continue;
}
+
+ if( !libconfig->setting_lookup_string(arena, "allowedTypes", &aTeamTypes) ) {
+ ShowError("bg_config_read: failed to find 'allowedTypes' for arena '%s'/#%d\n",aName,i);
+ continue;
+ }
+
libconfig->setting_lookup_int(arena, "maxDuration", &maxDuration);
if( maxDuration < 0 ) {
@@ -381,6 +424,7 @@ void bg_config_read(void) {
pregame_duration = 20;
}
+ allowedTypes = bg->str2teamtype(aTeamTypes);
CREATE( bg->arena[i], struct bg_arena, 1 );
@@ -403,6 +447,7 @@ void bg_config_read(void) {
bg->arena[i]->pregame_duration = pregame_duration;
bg->arena[i]->fillup_duration = fillup_duration;
bg->arena[i]->ongoing = false;
+ bg->arena[i]->allowed_types = allowedTypes;
}
bg->arenas = arena_count;
@@ -452,7 +497,7 @@ void bg_queue_ready_ack (struct bg_arena *arena, struct map_session_data *sd, bo
count++;
}
}
- /* check if all are ready then cancell timer, and start game */
+ /* check if all are ready then cancel timer, and start game */
if( count == queue->items ) {
timer->delete(arena->begin_timer,bg->begin_timer);
arena->begin_timer = INVALID_TIMER;
@@ -527,6 +572,10 @@ void bg_begin(struct bg_arena *arena) {
bg->match_over(arena,true);
} else {
arena->ongoing = true;
+
+ if( bg->afk_timer_id == INVALID_TIMER && bg->mafksec > 0 )
+ bg->afk_timer_id = timer->add(timer->gettick()+10000,bg->afk_timer,0,0);
+
/* TODO: make this a arena-independant var? or just .@? */
mapreg->setreg(script->add_str("$@bg_queue_id"),arena->queue_id);
mapreg->setregstr(script->add_str("$@bg_delay_var$"),bg->gdelay_var);
@@ -557,10 +606,6 @@ void bg_begin(struct bg_arena *arena) {
mapreg->setreg(script->add_str("$@bg_member_size"),count);
npc->event_do(arena->npc_event);
- /* we split evenly? */
- /* but if a party of say 10 joins, it cant be split evenly unless by luck there are 10 soloers in the queue besides them */
- /* not sure how to split T_T needs more info */
- /* currently running only on solo mode so we do it evenly */
}
}
int bg_begin_timer(int tid, int64 tick, int id, intptr_t data) {
@@ -569,6 +614,28 @@ int bg_begin_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
+int bg_afk_timer(int tid, int64 tick, int id, intptr_t data) {
+ struct s_mapiterator* iter;
+ struct map_session_data* sd;
+ int count = 0;
+
+ iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) {
+ if( !sd->bg_queue.arena || !sd->bg_id )
+ continue;
+ if( DIFF_TICK(sockt->last_tick, sd->idletime) < bg->mafksec )
+ bg->team_leave(sd,BGTL_AFK);
+ count++;
+ }
+ mapit->free(iter);
+
+ if( count )
+ bg->afk_timer_id = timer->add(timer->gettick()+10000,bg->afk_timer,0,0);
+ else
+ bg->afk_timer_id = INVALID_TIMER;
+ return 0;
+}
+
void bg_queue_pregame(struct bg_arena *arena) {
struct hQueue *queue = &script->hq[arena->queue_id];
int i;
@@ -605,7 +672,7 @@ void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_q
struct hQueue *queue;
int i, count = 0;
- if( arena->begin_timer != INVALID_TIMER ) {
+ if( arena->begin_timer != INVALID_TIMER || arena->ongoing ) {
clif->bgqueue_ack(sd,BGQA_FAIL_QUEUING_FINISHED,arena->id);
return;
}
@@ -636,7 +703,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)) || (queue->items+count) > arena->max_players ) {
clif->bgqueue_ack(sd,BGQA_FAIL_PPL_OVERAMOUNT,arena->id);
return;
}
@@ -684,6 +751,10 @@ void bg_queue_add(struct map_session_data *sd, struct bg_arena *arena, enum bg_q
enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_arena *arena, enum bg_queue_types type) {
int tick;
unsigned int tsec;
+
+ if( !(arena->allowed_types & type) )
+ return BGQA_FAIL_TYPE_INVALID;
+
if ( sd->status.base_level > arena->max_level || sd->status.base_level < arena->min_level )
return BGQA_FAIL_LEVEL_INCORRECT;
@@ -810,6 +881,7 @@ void battleground_defaults(void) {
bg->queue_on = false;
bg->mafksec = 0;
+ bg->afk_timer_id = INVALID_TIMER;
bg->arena = NULL;
bg->arenas = 0;
/* */
@@ -844,6 +916,9 @@ void battleground_defaults(void) {
bg->send_message = bg_send_message;
bg->send_xy_timer_sub = bg_send_xy_timer_sub;
bg->send_xy_timer = bg_send_xy_timer;
+ bg->afk_timer = bg_afk_timer;
+ /* */
+ bg->str2teamtype = bg_str2teamtype;
/* */
bg->config_read = bg_config_read;
}
diff --git a/src/map/battleground.h b/src/map/battleground.h
index ed7347566..05c4eb060 100644
--- a/src/map/battleground.h
+++ b/src/map/battleground.h
@@ -26,6 +26,12 @@ enum bg_queue_types {
BGQT_GUILD = 0x4,
};
+enum bg_team_leave_type {
+ BGTL_LEFT = 0x0,
+ BGTL_QUIT = 0x1,
+ BGTL_AFK = 0x2,
+};
+
struct battleground_member_data {
unsigned short x, y;
struct map_session_data *sd;
@@ -62,12 +68,13 @@ struct bg_arena {
unsigned short fillup_duration;
unsigned short pregame_duration;
bool ongoing;
+ enum bg_queue_types allowed_types;
};
struct battleground_interface {
bool queue_on;
/* */
- int mafksec;
+ int mafksec, afk_timer_id;
char gdelay_var[BG_DELAY_VAR_LENGTH];
/* */
struct bg_arena **arena;
@@ -97,13 +104,16 @@ struct battleground_interface {
bool (*team_warp) (int bg_id, unsigned short map_index, short x, short y);
void (*send_dot_remove) (struct map_session_data *sd);
bool (*team_join) (int bg_id, struct map_session_data *sd);
- int (*team_leave) (struct map_session_data *sd, int flag);
+ int (*team_leave) (struct map_session_data *sd, enum bg_team_leave_type flag);
bool (*member_respawn) (struct map_session_data *sd);
int (*create) (unsigned short map_index, short rx, short ry, const char *ev, const char *dev);
int (*team_get_id) (struct block_list *bl);
bool (*send_message) (struct map_session_data *sd, const char *mes, int len);
int (*send_xy_timer_sub) (DBKey key, DBData *data, va_list ap);
- int (*send_xy_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*send_xy_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*afk_timer) (int tid, int64 tick, int id, intptr_t data);
+ /* */
+ enum bg_queue_types (*str2teamtype) (const char *str);
/* */
void (*config_read) (void);
};
diff --git a/src/map/map.c b/src/map/map.c
index a7e83cae3..51b717a16 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1685,7 +1685,7 @@ int map_quit(struct map_session_data *sd) {
npc->event_dequeue(sd);
if( sd->bg_id && !sd->bg_queue.arena ) /* TODO: dump this chunk after bg_queue is fully enabled */
- bg->team_leave(sd,1);
+ bg->team_leave(sd,BGTL_QUIT);
if( sd->state.autotrade && runflag != MAPSERVER_ST_SHUTDOWN && !hChSys.closing )
pc->autotrade_update(sd,PAUC_REMOVE);
diff --git a/src/map/script.c b/src/map/script.c
index 17eba6b21..01a7e6410 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -16350,7 +16350,7 @@ BUILDIN(bg_leave)
if( sd == NULL || !sd->bg_id )
return true;
- bg->team_leave(sd,0);
+ bg->team_leave(sd,BGTL_LEFT);
return true;
}