diff options
Diffstat (limited to 'src/map/battleground.c')
-rw-r--r-- | src/map/battleground.c | 103 |
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; } |