summaryrefslogtreecommitdiff
path: root/src/map/battleground.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/battleground.c')
-rw-r--r--src/map/battleground.c103
1 files changed, 89 insertions, 14 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;
}