diff options
Diffstat (limited to 'src/map/party.c')
-rw-r--r-- | src/map/party.c | 576 |
1 files changed, 353 insertions, 223 deletions
diff --git a/src/map/party.c b/src/map/party.c index adcb35c5a..7cf340edb 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -1,46 +1,46 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams -#include "../common/cbasetypes.h" -#include "../common/timer.h" -#include "../common/socket.h" // last_tick -#include "../common/nullpo.h" -#include "../common/malloc.h" -#include "../common/random.h" -#include "../common/showmsg.h" -#include "../common/utils.h" -#include "../common/strlib.h" +#define HERCULES_CORE +#include "../config/core.h" // GP_BOUND_ITEMS, RENEWAL_EXP #include "party.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + #include "atcommand.h" //msg_txt() -#include "pc.h" -#include "map.h" -#include "instance.h" #include "battle.h" -#include "intif.h" #include "clif.h" +#include "instance.h" +#include "intif.h" +#include "itemdb.h" #include "log.h" +#include "map.h" +#include "mob.h" // struct mob_data +#include "pc.h" #include "skill.h" #include "status.h" -#include "itemdb.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - - -static DBMap* party_db; // int party_id -> struct party_data* (releases data) -static DBMap* party_booking_db; // int char_id -> struct party_booking_ad_info* (releases data) // Party Booking [Spiria] -static unsigned long party_booking_nextid = 1; +#include "../common/HPM.h" +#include "../common/cbasetypes.h" +#include "../common/malloc.h" +#include "../common/nullpo.h" +#include "../common/random.h" +#include "../common/showmsg.h" +#include "../common/socket.h" // last_tick +#include "../common/strlib.h" +#include "../common/timer.h" +#include "../common/utils.h" -int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data); +struct party_interface party_s; /*========================================== * Fills the given party_member structure according to the sd provided. * Used when creating/adding people to a party. [Skotlex] *------------------------------------------*/ -static void party_fill_member(struct party_member* member, struct map_session_data* sd, unsigned int leader) -{ +void party_fill_member(struct party_member* member, struct map_session_data* sd, unsigned int leader) { member->account_id = sd->status.account_id; member->char_id = sd->status.char_id; safestrncpy(member->name, sd->status.name, NAME_LENGTH); @@ -52,8 +52,7 @@ static void party_fill_member(struct party_member* member, struct map_session_da } /// Get the member_id of a party member. /// Return -1 if not in party. -int party_getmemberid(struct party_data* p, struct map_session_data* sd) -{ +int party_getmemberid(struct party_data* p, struct map_session_data* sd) { int member_id; nullpo_retr(-1, p); if( sd == NULL ) @@ -66,7 +65,6 @@ int party_getmemberid(struct party_data* p, struct map_session_data* sd) return member_id; } - /*========================================== * Request an available sd of this party *------------------------------------------*/ @@ -81,10 +79,8 @@ struct map_session_data* party_getavailablesd(struct party_data *p) /*========================================== * Retrieves and validates the sd pointer for this party member [Skotlex] *------------------------------------------*/ - -static TBL_PC* party_sd_check(int party_id, int account_id, int char_id) -{ - TBL_PC* sd = iMap->id2sd(account_id); +TBL_PC* party_sd_check(int party_id, int account_id, int char_id) { + TBL_PC* sd = map->id2sd(account_id); if (!(sd && sd->status.char_id == char_id)) return NULL; @@ -93,7 +89,7 @@ static TBL_PC* party_sd_check(int party_id, int account_id, int char_id) sd->status.party_id = party_id;// auto-join if not in a party if (sd->status.party_id != party_id) { //If player belongs to a different party, kick him out. - intif_party_leave(party_id,account_id,char_id); + intif->party_leave(party_id,account_id,char_id); return NULL; } @@ -102,35 +98,30 @@ static TBL_PC* party_sd_check(int party_id, int account_id, int char_id) int party_db_final(DBKey key, DBData *data, va_list ap) { struct party_data *p; - if( ( p = DB->data2ptr(data) ) && p->instance ) - aFree(p->instance); + if( ( p = DB->data2ptr(data) ) ) { + int j; + + if( p->instance ) + aFree(p->instance); + + for( j = 0; j < p->hdatac; j++ ) { + if( p->hdata[j]->flag.free ) { + aFree(p->hdata[j]->data); + } + aFree(p->hdata[j]); + } + if( p->hdata ) + aFree(p->hdata); + } return 0; } -/*========================================== - * Destructor - * Called in map shutdown, cleanup var - *------------------------------------------*/ -void do_final_party(void) -{ - party_db->destroy(party_db,party_db_final); - party_booking_db->destroy(party_booking_db,NULL); // Party Booking [Spiria] -} -// Constructor, init vars -void do_init_party(void) -{ - party_db = idb_alloc(DB_OPT_RELEASE_DATA); - party_booking_db = idb_alloc(DB_OPT_RELEASE_DATA); // Party Booking [Spiria] - iTimer->add_timer_func_list(party_send_xy_timer, "party_send_xy_timer"); - iTimer->add_timer_interval(iTimer->gettick()+battle_config.party_update_interval, party_send_xy_timer, 0, 0, battle_config.party_update_interval); -} - /// Party data lookup using party id. struct party_data* party_search(int party_id) { if(!party_id) return NULL; - return (struct party_data*)idb_get(party_db,party_id); + return (struct party_data*)idb_get(party->db,party_id); } /// Party data lookup using party name. @@ -138,7 +129,7 @@ struct party_data* party_searchname(const char* str) { struct party_data* p; - DBIterator *iter = db_iterator(party_db); + DBIterator *iter = db_iterator(party->db); for( p = dbi_first(iter); dbi_exists(iter); p = dbi_next(iter) ) { if( strncmpi(p->party.name,str,NAME_LENGTH) == 0 ) @@ -170,22 +161,21 @@ int party_create(struct map_session_data *sd,char *name,int item,int item2) sd->party_creating = true; - party_fill_member(&leader, sd, 1); + party->fill_member(&leader, sd, 1); - intif_create_party(&leader,name,item,item2); + intif->create_party(&leader,name,item,item2); return 0; } -void party_created(int account_id,int char_id,int fail,int party_id,char *name) -{ +void party_created(int account_id,int char_id,int fail,int party_id,char *name) { struct map_session_data *sd; - sd=iMap->id2sd(account_id); + sd=map->id2sd(account_id); - if (!sd || sd->status.char_id != char_id || !sd->party_creating ) - { //Character logged off before creation ack? + if (!sd || sd->status.char_id != char_id || !sd->party_creating ) { + //Character logged off before creation ack? if (!fail) //break up party since player could not be added to it. - intif_party_leave(party_id,account_id,char_id); + intif->party_leave(party_id,account_id,char_id); return; } @@ -203,46 +193,43 @@ void party_created(int account_id,int char_id,int fail,int party_id,char *name) int party_request_info(int party_id, int char_id) { - return intif_request_partyinfo(party_id, char_id); + return intif->request_partyinfo(party_id, char_id); } /// Invoked (from char-server) when the party info is not found. -int party_recv_noinfo(int party_id, int char_id) -{ +int party_recv_noinfo(int party_id, int char_id) { party->broken(party_id); - if( char_id != 0 )// requester - { + if( char_id != 0 ) { + // requester struct map_session_data* sd; - sd = iMap->charid2sd(char_id); + sd = map->charid2sd(char_id); if( sd && sd->status.party_id == party_id ) sd->status.party_id = 0; } return 0; } -static void party_check_state(struct party_data *p) -{ +void party_check_state(struct party_data *p) { int i; memset(&p->state, 0, sizeof(p->state)); - for (i = 0; i < MAX_PARTY; i ++) - { - if (!p->party.member[i].online) continue; //Those not online shouldn't aport to skill usage and all that. + for (i = 0; i < MAX_PARTY; i ++) { + if (!p->party.member[i].online) continue; //Those not online shouldn't apart to skill usage and all that. switch (p->party.member[i].class_) { - case JOB_MONK: - case JOB_BABY_MONK: - case JOB_CHAMPION: - p->state.monk = 1; - break; - case JOB_STAR_GLADIATOR: - p->state.sg = 1; - break; - case JOB_SUPER_NOVICE: - case JOB_SUPER_BABY: - p->state.snovice = 1; - break; - case JOB_TAEKWON: - p->state.tk = 1; - break; + case JOB_MONK: + case JOB_BABY_MONK: + case JOB_CHAMPION: + p->state.monk = 1; + break; + case JOB_STAR_GLADIATOR: + p->state.sg = 1; + break; + case JOB_SUPER_NOVICE: + case JOB_SUPER_BABY: + p->state.snovice = 1; + break; + case JOB_TAEKWON: + p->state.tk = 1; + break; } } } @@ -261,7 +248,7 @@ int party_recv_info(struct party* sp, int char_id) nullpo_ret(sp); - p = (struct party_data*)idb_get(party_db, sp->party_id); + p = (struct party_data*)idb_get(party->db, sp->party_id); if( p != NULL ) {// diff members for( member_id = 0; member_id < MAX_PARTY; ++member_id ) { member = &p->party.member[member_id]; @@ -290,7 +277,7 @@ int party_recv_info(struct party* sp, int char_id) CREATE(p, struct party_data, 1); p->instance = NULL; p->instances = 0; - idb_put(party_db, sp->party_id, p); + idb_put(party->db, sp->party_id, p); } while( removed_count > 0 ) {// no longer in party member_id = removed[--removed_count]; @@ -306,9 +293,9 @@ int party_recv_info(struct party* sp, int char_id) member = &p->party.member[member_id]; if ( member->char_id == 0 ) continue;// empty - p->data[member_id].sd = party_sd_check(sp->party_id, member->account_id, member->char_id); + p->data[member_id].sd = party->sd_check(sp->party_id, member->account_id, member->char_id); } - party_check_state(p); + party->check_state(p); while( added_count > 0 ) { // new in party member_id = added[--added_count]; sd = p->data[member_id].sd; @@ -319,15 +306,17 @@ int party_recv_info(struct party* sp, int char_id) clif->party_option(p,sd,0x100); clif->party_info(p,NULL); for( j = 0; j < p->instances; j++ ) { - if( instances[p->instance[j]].idle_timer == INVALID_TIMER && instances[p->instance[j]].progress_timer == INVALID_TIMER ) - continue; - clif->instance_join(sd->fd, p->instance[j]); - break; + if( p->instance[j] >= 0 ) { + if( instance->list[p->instance[j]].idle_timer == INVALID_TIMER && instance->list[p->instance[j]].progress_timer == INVALID_TIMER ) + continue; + clif->instance_join(sd->fd, p->instance[j]); + break; + } } } - if( char_id != 0 )// requester - { - sd = iMap->charid2sd(char_id); + if( char_id != 0 ) { + // requester + sd = map->charid2sd(char_id); if( sd && sd->status.party_id == sp->party_id && party->getmemberid(p,sd) == -1 ) sd->status.party_id = 0;// was not in the party } @@ -396,8 +385,7 @@ int party_invite(struct map_session_data *sd,struct map_session_data *tsd) return 1; } -void party_reply_invite(struct map_session_data *sd,int party_id,int flag) -{ +void party_reply_invite(struct map_session_data *sd,int party_id,int flag) { struct map_session_data* tsd; struct party_member member; @@ -407,13 +395,13 @@ void party_reply_invite(struct map_session_data *sd,int party_id,int flag) sd->party_invite_account = 0; return; } - tsd = iMap->id2sd(sd->party_invite_account); + tsd = map->id2sd(sd->party_invite_account); if( flag == 1 && !sd->party_creating && !sd->party_joining ) {// accepted and allowed sd->party_joining = true; - party_fill_member(&member, sd, 0); - intif_party_addmember(sd->party_invite, &member); + party->fill_member(&member, sd, 0); + intif->party_addmember(sd->party_invite, &member); } else {// rejected or failure @@ -441,10 +429,12 @@ void party_member_joined(struct map_session_data *sd) int j; p->data[i].sd = sd; for( j = 0; j < p->instances; j++ ) { - if( instances[p->instance[j]].idle_timer == INVALID_TIMER && instances[p->instance[j]].progress_timer == INVALID_TIMER ) - continue; - clif->instance_join(sd->fd, p->instance[j]); - break; + if( p->instance[j] >= 0 ) { + if( instance->list[p->instance[j]].idle_timer == INVALID_TIMER && instance->list[p->instance[j]].progress_timer == INVALID_TIMER ) + continue; + clif->instance_join(sd->fd, p->instance[j]); + break; + } } } else sd->status.party_id = 0; //He does not belongs to the party really? @@ -452,19 +442,18 @@ void party_member_joined(struct map_session_data *sd) /// Invoked (from char-server) when a new member is added to the party. /// flag: 0-success, 1-failure -int party_member_added(int party_id,int account_id,int char_id, int flag) -{ - struct map_session_data *sd = iMap->id2sd(account_id),*sd2; +int party_member_added(int party_id,int account_id,int char_id, int flag) { + struct map_session_data *sd = map->id2sd(account_id),*sd2; struct party_data *p = party->search(party_id); int i, j; if(sd == NULL || sd->status.char_id != char_id || !sd->party_joining ) { if (!flag) //Char logged off before being accepted into party. - intif_party_leave(party_id,account_id,char_id); + intif->party_leave(party_id,account_id,char_id); return 0; } - sd2 = iMap->id2sd(sd->party_invite_account); + sd2 = map->id2sd(sd->party_invite_account); sd->party_joining = false; sd->party_invite = 0; @@ -472,7 +461,7 @@ int party_member_added(int party_id,int account_id,int char_id, int flag) if (!p) { ShowError("party_member_added: party %d not found.\n",party_id); - intif_party_leave(party_id,account_id,char_id); + intif->party_leave(party_id,account_id,char_id); return 0; } @@ -502,10 +491,12 @@ int party_member_added(int party_id,int account_id,int char_id, int flag) clif->charnameupdate(sd); //Update char name's display [Skotlex] for( j = 0; j < p->instances; j++ ) { - if( instances[p->instance[j]].idle_timer == INVALID_TIMER && instances[p->instance[j]].progress_timer == INVALID_TIMER ) - continue; - clif->instance_join(sd->fd, p->instance[j]); - break; + if( p->instance[j] >= 0 ) { + if( instance->list[p->instance[j]].idle_timer == INVALID_TIMER && instance->list[p->instance[j]].progress_timer == INVALID_TIMER ) + continue; + clif->instance_join(sd->fd, p->instance[j]); + break; + } } return 0; @@ -532,7 +523,7 @@ int party_removemember(struct map_session_data* sd, int account_id, char* name) if( i == MAX_PARTY ) return 0; // no such char in party - intif_party_leave(p->party.party_id,account_id,p->party.member[i].char_id); + intif->party_leave(p->party.party_id,account_id,p->party.member[i].char_id); return 1; } @@ -550,14 +541,14 @@ int party_leave(struct map_session_data *sd) if( i == MAX_PARTY ) return 0; - intif_party_leave(p->party.party_id,sd->status.account_id,sd->status.char_id); + intif->party_leave(p->party.party_id,sd->status.account_id,sd->status.char_id); return 1; } /// Invoked (from char-server) when a party member leaves the party. int party_member_withdraw(int party_id, int account_id, int char_id) { - struct map_session_data* sd = iMap->id2sd(account_id); + struct map_session_data* sd = map->id2sd(account_id); struct party_data* p = party->search(party_id); if( p ) { @@ -568,18 +559,26 @@ int party_member_withdraw(int party_id, int account_id, int char_id) memset(&p->party.member[i], 0, sizeof(p->party.member[0])); memset(&p->data[i], 0, sizeof(p->data[0])); p->party.count--; - party_check_state(p); + party->check_state(p); } } if( sd && sd->status.party_id == party_id && sd->status.char_id == char_id ) { +#ifdef GP_BOUND_ITEMS + pc->bound_clear(sd,IBT_PARTY); +#endif sd->status.party_id = 0; clif->charnameupdate(sd); //Update name display [Skotlex] //TODO: hp bars should be cleared too - if( p->instances ) + if( p && p->instances ) instance->check_kick(sd); } - + if (sd && sd->sc.data[SC_DANCING]) { + status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); + status_change_end(&sd->bl, SC_DRUMBATTLE, INVALID_TIMER); + status_change_end(&sd->bl, SC_NIBELUNGEN, INVALID_TIMER); + status_change_end(&sd->bl, SC_SIEGFRIED, INVALID_TIMER); + } return 0; } @@ -594,8 +593,10 @@ int party_broken(int party_id) return 0; for( j = 0; j < p->instances; j++ ) { - instance->destroy( p->instance[j] ); - instances[p->instance[j]].owner_id = 0; + if( p->instance[j] >= 0 ) { + instance->destroy( p->instance[j] ); + instance->list[p->instance[j]].owner_id = 0; + } } for( i = 0; i < MAX_PARTY; i++ ) { @@ -605,7 +606,19 @@ int party_broken(int party_id) } } - idb_remove(party_db,party_id); + if( p->instance ) + aFree(p->instance); + + for( j = 0; j < p->hdatac; j++ ) { + if( p->hdata[j]->flag.free ) { + aFree(p->hdata[j]->data); + } + aFree(p->hdata[j]); + } + if( p->hdata ) + aFree(p->hdata); + + idb_remove(party->db,party_id); return 0; } @@ -615,14 +628,13 @@ int party_changeoption(struct map_session_data *sd,int exp,int item) if( sd->status.party_id==0) return 0; - intif_party_changeoption(sd->status.party_id,sd->status.account_id,exp,item); + intif->party_changeoption(sd->status.party_id,sd->status.account_id,exp,item); return 0; } -int party_optionchanged(int party_id,int account_id,int exp,int item,int flag) -{ +int party_optionchanged(int party_id,int account_id,int exp,int item,int flag) { struct party_data *p; - struct map_session_data *sd=iMap->id2sd(account_id); + struct map_session_data *sd=map->id2sd(account_id); if( (p=party->search(party_id))==NULL) return 0; @@ -650,8 +662,7 @@ bool party_changeleader(struct map_session_data *sd, struct map_session_data *ts return false; } - if( map[sd->bl.m].flag.partylock ) - { + if( map->list[sd->bl.m].flag.partylock ) { clif->message(sd->fd, msg_txt(287)); return false; } @@ -683,7 +694,7 @@ bool party_changeleader(struct map_session_data *sd, struct map_session_data *ts clif->message(p->data[tmi].sd->fd, msg_txt(285)); //Update info. - intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id); + intif->party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id); clif->party_info(p,NULL); return true; } @@ -692,7 +703,7 @@ bool party_changeleader(struct map_session_data *sd, struct map_session_data *ts /// - changes maps /// - logs in or out /// - gains a level (disabled) -int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv) +int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short mapid,int online,int lv) { struct party_member* m; struct party_data* p; @@ -710,11 +721,11 @@ int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short m } m = &p->party.member[i]; - m->map = map; + m->map = mapid; m->online = online; m->lv = lv; //Check if they still exist on this map server - p->data[i].sd = party_sd_check(party_id, account_id, char_id); + p->data[i].sd = party->sd_check(party_id, account_id, char_id); clif->party_info(p,NULL); return 0; @@ -727,7 +738,7 @@ void party_send_movemap(struct map_session_data *sd) if( sd->status.party_id==0 ) return; - intif_party_changemap(sd,1); + intif->party_changemap(sd,1); p=party->search(sd->status.party_id); if (!p) return; @@ -755,7 +766,7 @@ void party_send_movemap(struct map_session_data *sd) void party_send_levelup(struct map_session_data *sd) { - intif_party_changemap(sd,1); + intif->party_changemap(sd,1); } int party_send_logout(struct map_session_data *sd) @@ -766,7 +777,7 @@ int party_send_logout(struct map_session_data *sd) if(!sd->status.party_id) return 0; - intif_party_changemap(sd,0); + intif->party_changemap(sd,0); p=party->search(sd->status.party_id); if(!p) return 0; @@ -783,7 +794,7 @@ int party_send_message(struct map_session_data *sd,const char *mes,int len) { if(sd->status.party_id==0) return 0; - intif_party_message(sd->status.party_id,sd->status.account_id,mes,len); + intif->party_message(sd->status.party_id,sd->status.account_id,mes,len); party->recv_message(sd->status.party_id,sd->status.account_id,mes,len); // Chat logging type 'P' / Party Chat @@ -833,7 +844,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id case TK_COUNTER: //Increase Triple Attack rate of Monks. if((p_sd->class_&MAPID_UPPERMASK) == MAPID_MONK && pc->checkskill(p_sd,MO_TRIPLEATTACK)) { - sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,MO_TRIPLEATTACK, + sc_start4(&p_sd->bl,&p_sd->bl,SC_SKILLRATE_UP,100,MO_TRIPLEATTACK, 50+50*skill_lv, //+100/150/200% rate 0,0,skill->get_time(SG_FRIEND, 1)); } @@ -842,7 +853,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id if((p_sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR && sd->sc.data[SC_COUNTERKICK_READY] && pc->checkskill(p_sd,SG_FRIEND)) { - sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER, + sc_start4(&p_sd->bl,&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER, 50+50*pc->checkskill(p_sd,SG_FRIEND), //+100/150/200% rate 0,0,skill->get_time(SG_FRIEND, 1)); } @@ -852,11 +863,10 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id return 0; } -int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) -{ +int party_send_xy_timer(int tid, int64 tick, int id, intptr_t data) { struct party_data* p; - DBIterator *iter = db_iterator(party_db); + DBIterator *iter = db_iterator(party->db); // for each existing party, for( p = dbi_first(iter); dbi_exists(iter); p = dbi_next(iter) ) { @@ -871,7 +881,7 @@ int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) for( i = 0; i < MAX_PARTY; i++ ) { struct map_session_data* sd = p->data[i].sd; - if( !sd ) continue; + if( !sd || sd->bg_id ) continue; if( p->data[i].x != sd->bl.x || p->data[i].y != sd->bl.y ) {// perform position update @@ -948,7 +958,9 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b for (i = 0; i < c; i++) { #ifdef RENEWAL_EXP if( !(src && src->type == BL_MOB && ((TBL_MOB*)src)->db->mexp) ){ - int rate = pc->level_penalty_mod(sd[i], (TBL_MOB*)src, 1); + struct mob_data *md = (TBL_MOB*)src; + int rate = pc->level_penalty_mod(md->level - (sd[i])->status.base_level, md->status.race, md->status.mode, 1); + base_exp = (unsigned int)cap_value(base_exp_bonus * rate / 100, 1, UINT_MAX); job_exp = (unsigned int)cap_value(job_exp_bonus * rate / 100, 1, UINT_MAX); } @@ -1050,9 +1062,11 @@ int party_sub_count(struct block_list *bl, va_list ap) return 1; } -/// Executes 'func' for each party member on the same map and in range (0:whole map) -int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...) -{ +/** + * Arglist-based version of party_foreachsamemap + * @see party_foreachsamemap + */ +int party_vforeachsamemap(int (*func)(struct block_list*,va_list), struct map_session_data *sd, int range, va_list ap) { struct party_data *p; int i; int x0,y0,x1,y1; @@ -1083,138 +1097,220 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess list[blockcount++]=&psd->bl; } - iMap->freeblock_lock(); + map->freeblock_lock(); - for(i=0;i<blockcount;i++) - { - va_list ap; - va_start(ap, range); - total += func(list[i], ap); - va_end(ap); + for(i=0;i<blockcount;i++) { + va_list ap_copy; + va_copy(ap_copy, ap); + total += func(list[i], ap_copy); + va_end(ap_copy); } - iMap->freeblock_unlock(); + map->freeblock_unlock(); return total; } +// Special check for Minstrel's and Wanderer's chorus skills. +int party_sub_count_chorus(struct block_list *bl, va_list ap) { + struct map_session_data *sd = (TBL_PC *)bl; + + if (sd->state.autotrade) + return 0; + + if (battle_config.idle_no_share && pc_isidle(sd)) + return 0; + + if ( (sd->class_&MAPID_THIRDMASK) != MAPID_MINSTRELWANDERER ) + return 0; + + return 1; +} + +/** + * Executes 'func' for each party member on the same map and within a 'range' cells area + * @param func Function to execute + * @param sd Reference character for party, map, area center + * @param range Area size (0 = whole map) + * @param ... Additional parameters to pass to func() + * @return Sum of the return values from func() + */ +int party_foreachsamemap(int (*func)(struct block_list*,va_list), struct map_session_data *sd, int range, ...) { + va_list ap; + int ret; + va_start(ap, range); + ret = party->vforeachsamemap(func, sd, range, ap); + va_end(ap); + return ret; +} + /*========================================== * Party Booking in KRO [Spiria] *------------------------------------------*/ -static struct party_booking_ad_info* create_party_booking_data(void) -{ +struct party_booking_ad_info* create_party_booking_data(void) { struct party_booking_ad_info *pb_ad; CREATE(pb_ad, struct party_booking_ad_info, 1); - pb_ad->index = party_booking_nextid++; + pb_ad->index = party->booking_nextid++; return pb_ad; } -#ifndef PARTY_RECRUIT -void party_booking_register(struct map_session_data *sd, short level, short mapid, short* job) -#else -void party_booking_register(struct map_session_data *sd, short level, const char *notice) -#endif -{ +void party_recruit_register(struct map_session_data *sd, short level, const char *notice) { +#ifdef PARTY_RECRUIT struct party_booking_ad_info *pb_ad; -#ifndef PARTY_RECRUIT - int i; -#endif - pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id); + pb_ad = (struct party_booking_ad_info*)idb_get(party->booking_db, sd->status.char_id); if( pb_ad == NULL ) { - pb_ad = create_party_booking_data(); - idb_put(party_booking_db, sd->status.char_id, pb_ad); + pb_ad = party->create_booking_data(); + idb_put(party->booking_db, sd->status.char_id, pb_ad); } else {// already registered - clif->PartyBookingRegisterAck(sd, 2); + clif->PartyRecruitRegisterAck(sd, 2); return; } memcpy(pb_ad->charname,sd->status.name,NAME_LENGTH); pb_ad->expiretime = (int)time(NULL); pb_ad->p_detail.level = level; + safestrncpy(pb_ad->p_detail.notice, notice, PB_NOTICE_LENGTH); + + clif->PartyRecruitRegisterAck(sd, 0); + clif->PartyRecruitInsertNotify(sd, pb_ad); // Notice +#else + return; +#endif +} + +void party_booking_register(struct map_session_data *sd, short level, short mapid, short* job) { #ifndef PARTY_RECRUIT + struct party_booking_ad_info *pb_ad; + int i; + + pb_ad = (struct party_booking_ad_info*)idb_get(party->booking_db, sd->status.char_id); + + if( pb_ad == NULL ) + { + pb_ad = party->create_booking_data(); + idb_put(party->booking_db, sd->status.char_id, pb_ad); + } + else + {// already registered + clif->PartyBookingRegisterAck(sd, 2); + return; + } + + memcpy(pb_ad->charname,sd->status.name,NAME_LENGTH); + pb_ad->expiretime = (int)time(NULL); + pb_ad->p_detail.level = level; pb_ad->p_detail.mapid = mapid; - + for(i=0;i<PARTY_BOOKING_JOBS;i++) if(job[i] != 0xFF) pb_ad->p_detail.job[i] = job[i]; else pb_ad->p_detail.job[i] = -1; -#else - safestrncpy(pb_ad->p_detail.notice, notice, PB_NOTICE_LENGTH); -#endif - + clif->PartyBookingRegisterAck(sd, 0); clif->PartyBookingInsertNotify(sd, pb_ad); // Notice -} - -#ifndef PARTY_RECRUIT -void party_booking_update(struct map_session_data *sd, short* job) #else -void party_booking_update(struct map_session_data *sd, const char *notice) -#endif -{ -#ifndef PARTY_RECRUIT - int i; + return; #endif +} + +void party_recruit_update(struct map_session_data *sd, const char *notice) { +#ifdef PARTY_RECRUIT struct party_booking_ad_info *pb_ad; - pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id); + pb_ad = (struct party_booking_ad_info*)idb_get(party->booking_db, sd->status.char_id); if( pb_ad == NULL ) return; pb_ad->expiretime = (int)time(NULL);// Update time. + if (notice != NULL) { + safestrncpy(pb_ad->p_detail.notice, notice, PB_NOTICE_LENGTH); + } + + clif->PartyRecruitUpdateNotify(sd, pb_ad); +#else + return; +#endif +} +void party_booking_update(struct map_session_data *sd, short* job) { #ifndef PARTY_RECRUIT + int i; + struct party_booking_ad_info *pb_ad; + + pb_ad = (struct party_booking_ad_info*)idb_get(party->booking_db, sd->status.char_id); + + if( pb_ad == NULL ) + return; + + pb_ad->expiretime = (int)time(NULL);// Update time. + for(i=0;i<PARTY_BOOKING_JOBS;i++) if(job[i] != 0xFF) pb_ad->p_detail.job[i] = job[i]; else pb_ad->p_detail.job[i] = -1; + + clif->PartyBookingUpdateNotify(sd, pb_ad); #else - if (notice != NULL) { - safestrncpy(pb_ad->p_detail.notice, notice, PB_NOTICE_LENGTH); - } + return; #endif - - clif->PartyBookingUpdateNotify(sd, pb_ad); } -#ifndef PARTY_RECRUIT -void party_booking_search(struct map_session_data *sd, short level, short mapid, short job, unsigned long lastindex, short resultcount) -#else -void party_booking_search(struct map_session_data *sd, short level, short mapid, unsigned long lastindex, short resultcount) -#endif -{ + +void party_recruit_search(struct map_session_data *sd, short level, short mapid, unsigned long lastindex, short resultcount) { +#ifdef PARTY_RECRUIT struct party_booking_ad_info *pb_ad; -#ifndef PARTY_RECRUIT - int i; -#endif int count = 0; struct party_booking_ad_info* result_list[PARTY_BOOKING_RESULTS]; bool more_result = false; - DBIterator* iter = db_iterator(party_booking_db); + DBIterator* iter = db_iterator(party->booking_db); memset(result_list, 0, sizeof(result_list)); for( pb_ad = dbi_first(iter); dbi_exists(iter); pb_ad = dbi_next(iter) ) { -#ifndef PARTY_RECRUIT - if (pb_ad->index < lastindex || (level && (pb_ad->p_detail.level < level-15 || pb_ad->p_detail.level > level))) - continue; -#else if ((level && (pb_ad->p_detail.level < level-15 || pb_ad->p_detail.level > level))) continue; -#endif if (count >= PARTY_BOOKING_RESULTS){ more_result = true; break; } + result_list[count] = pb_ad; + if( result_list[count] ) + { + count++; + } + } + dbi_destroy(iter); + clif->PartyRecruitSearchAck(sd->fd, result_list, count, more_result); +#else + return; +#endif +} +void party_booking_search(struct map_session_data *sd, short level, short mapid, short job, unsigned long lastindex, short resultcount) { #ifndef PARTY_RECRUIT + struct party_booking_ad_info *pb_ad; + int i; + int count = 0; + struct party_booking_ad_info* result_list[PARTY_BOOKING_RESULTS]; + bool more_result = false; + DBIterator* iter = db_iterator(party->booking_db); + + memset(result_list, 0, sizeof(result_list)); + + for( pb_ad = dbi_first(iter); dbi_exists(iter); pb_ad = dbi_next(iter) ) { + if (pb_ad->index < lastindex || (level && (pb_ad->p_detail.level < level-15 || pb_ad->p_detail.level > level))) + continue; + if (count >= PARTY_BOOKING_RESULTS){ + more_result = true; + break; + } if (mapid == 0 && job == -1) result_list[count] = pb_ad; else if (mapid == 0) { @@ -1225,9 +1321,6 @@ void party_booking_search(struct map_session_data *sd, short level, short mapid, if (pb_ad->p_detail.mapid == mapid) result_list[count] = pb_ad; } -#else - result_list[count] = pb_ad; -#endif if( result_list[count] ) { count++; @@ -1235,32 +1328,57 @@ void party_booking_search(struct map_session_data *sd, short level, short mapid, } dbi_destroy(iter); clif->PartyBookingSearchAck(sd->fd, result_list, count, more_result); +#else + return; +#endif } + bool party_booking_delete(struct map_session_data *sd) { struct party_booking_ad_info* pb_ad; - if((pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, sd->status.char_id))!=NULL) + if((pb_ad = (struct party_booking_ad_info*)idb_get(party->booking_db, sd->status.char_id))!=NULL) { +#ifdef PARTY_RECRUIT + clif->PartyRecruitDeleteNotify(sd, pb_ad->index); +#else clif->PartyBookingDeleteNotify(sd, pb_ad->index); - idb_remove(party_booking_db,sd->status.char_id); +#endif + idb_remove(party->booking_db,sd->status.char_id); } return true; } +void do_final_party(void) { + party->db->destroy(party->db,party->db_final); + db_destroy(party->booking_db); // Party Booking [Spiria] +} +// Constructor, init vars +void do_init_party(bool minimal) { + if (minimal) + return; + party->db = idb_alloc(DB_OPT_RELEASE_DATA); + party->booking_db = idb_alloc(DB_OPT_RELEASE_DATA); // Party Booking [Spiria] + timer->add_func_list(party->send_xy_timer, "party_send_xy_timer"); + timer->add_interval(timer->gettick()+battle_config.party_update_interval, party->send_xy_timer, 0, 0, battle_config.party_update_interval); +} /*===================================== -* Default Functions : party.h +* Default Functions : party.h * Generated by HerculesInterfaceMaker * created by Susu *-------------------------------------*/ void party_defaults(void) { party = &party_s; + /* */ + party->db = NULL; + party->booking_db = NULL; + party->booking_nextid = 1; /* funcs */ - - party->do_init_party = do_init_party; - party->do_final_party = do_final_party; + party->init = do_init_party; + party->final = do_final_party; + /* */ party->search = party_search; party->searchname = party_searchname; party->getmemberid = party_getmemberid; @@ -1294,8 +1412,20 @@ void party_defaults(void) { party->share_loot = party_share_loot; party->send_dot_remove = party_send_dot_remove; party->sub_count = party_sub_count; + party->sub_count_chorus = party_sub_count_chorus; party->booking_register = party_booking_register; party->booking_update = party_booking_update; party->booking_search = party_booking_search; + party->recruit_register = party_recruit_register; + party->recruit_update = party_recruit_update; + party->recruit_search = party_recruit_search; party->booking_delete = party_booking_delete; + party->vforeachsamemap = party_vforeachsamemap; + party->foreachsamemap = party_foreachsamemap; + party->send_xy_timer = party_send_xy_timer; + party->fill_member = party_fill_member; + party->sd_check = party_sd_check; + party->check_state = party_check_state; + party->create_booking_data = create_party_booking_data; + party->db_final = party_db_final; } |