From 1963ef3c77c8c2035da2e7a2310db341c4c421fc Mon Sep 17 00:00:00 2001 From: L0ne_W0lf Date: Tue, 5 Oct 2010 17:17:58 +0000 Subject: * Added Spira's Party Booking System implementation - Added two additional mercenaries and updated data. - Added place holder values to the item database. - Added packets for the party booking system. - Updated the 13.2 monster skills to official. - Updated stats and drop rates on several monsters. - Fixed Lullaby working on allies/party members. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@14412 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/clif.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++- src/map/clif.h | 7 +++ src/map/map.c | 2 + src/map/party.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/map/party.h | 21 ++++++++ 5 files changed, 326 insertions(+), 1 deletion(-) (limited to 'src/map') diff --git a/src/map/clif.c b/src/map/clif.c index f33a286b7..abac41cdb 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -2408,6 +2408,8 @@ void clif_clearcart(int fd) { WFIFOHEAD(fd, packet_len(0x12b)); WFIFOW(fd,0) = 0x12b; + WFIFOSET(fd, packet_len(0x12b)); + } // Guild XY locators [Valaris] @@ -10784,6 +10786,145 @@ void clif_parse_PartyChangeLeader(int fd, struct map_session_data* sd) party_changeleader(sd, map_id2sd(RFIFOL(fd,2))); } + /*========================================== + * Party Booking in KRO [Spiria] + *------------------------------------------*/ +void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data* sd) +{ + short level = RFIFOW(fd,2); + short mapid = RFIFOW(fd,4); + short job[6]; + int i; + + for(i=0; i<6; i++) + job[i] = RFIFOB(fd,6+i*2); + + party_booking_register(sd, level, mapid, job); +} + +/*========================================== + * flag: 0 - success, 1 - failed + *------------------------------------------*/ +void clif_PartyBookingRegisterAck(struct map_session_data *sd, int flag) +{ + int fd = sd->fd; + + WFIFOHEAD(fd,packet_len(0x803)); + WFIFOW(fd,0) = 0x803; + WFIFOW(fd,2) = flag; + WFIFOSET(fd,packet_len(0x803)); +} + +void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data* sd) +{ + short level = RFIFOW(fd,2); + short mapid = RFIFOW(fd,4); + short job = RFIFOW(fd,6); + unsigned long lastindex = RFIFOL(fd,8); + short resultcount = RFIFOB(fd,12); + + party_booking_search(sd, level, mapid, job, lastindex, resultcount); +} + +/*========================================== + * more_result: 0 - no more, 1 - more + *------------------------------------------*/ +void clif_PartyBookingSearchAck(int fd, unsigned long *index, int count, bool more_result) +{ + int i, j; + int size = sizeof(struct party_booking_ad_info); // structure size (48) + struct party_booking_ad_info *pb_ad; + WFIFOHEAD(fd,size*count + 5); + WFIFOW(fd,0) = 0x805; + WFIFOW(fd,2) = size*count + 5; + WFIFOB(fd,4) = (bool)more_result; + for(i=0; iindex; + memcpy(WFIFOP(fd,i*size+9),pb_ad->charname,NAME_LENGTH); + WFIFOL(fd,i*size+33) = pb_ad->starttime; + WFIFOW(fd,i*size+37) = pb_ad->p_detail.level; + WFIFOW(fd,i*size+39) = pb_ad->p_detail.mapid; + for(j=0; j<6; j++) + WFIFOW(fd,i*size+41+j*2) = pb_ad->p_detail.job[j]; + } + WFIFOSET(fd,WFIFOW(fd,2)); +} + +void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data* sd) +{ + if(party_booking_delete(sd, false)) + clif_PartyBookingDeleteAck(sd, 0); +} + +/*========================================== + * flag: 0 - success, other - failed + *------------------------------------------*/ +void clif_PartyBookingDeleteAck(struct map_session_data* sd, int flag) +{ + int fd = sd->fd; + + WFIFOHEAD(fd,packet_len(0x807)); + WFIFOW(fd,0) = 0x807; + WFIFOW(fd,2) = flag; + WFIFOSET(fd,packet_len(0x807)); +} + +void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data* sd) +{ + short job[6]; + int i; + + for(i=0; i<6; i++) + job[i] = RFIFOW(fd,2+i*2); + + party_booking_update(sd, job); +} + +void clif_PartyBookingInsertNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad) +{ + int i; + + if(pb_ad == NULL) return; + + WFIFOHEAD(sd->fd,packet_len(0x809)); + WFIFOW(sd->fd,0) = 0x809; + WFIFOL(sd->fd,2) = pb_ad->index; + memcpy(WFIFOP(sd->fd,6),pb_ad->charname,NAME_LENGTH); + WFIFOL(sd->fd,30) = pb_ad->starttime; + WFIFOW(sd->fd,34) = pb_ad->p_detail.level; + WFIFOW(sd->fd,36) = pb_ad->p_detail.mapid; + for(i=0; i<6; i++) + WFIFOW(sd->fd,38+i*2) = pb_ad->p_detail.job[i]; + + WFIFOSET(sd->fd,packet_len(0x809)); +} + +void clif_PartyBookingUpdateNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad) +{ + int i; + uint8 buf[18]; + + if(pb_ad == NULL) return; + + WBUFW(buf,0) = 0x80a; + WBUFL(buf,2) = pb_ad->index; + for(i=0; i<6; i++) + WBUFW(buf,6+i*2) = pb_ad->p_detail.job[i]; + clif_send(buf,packet_len(0x80a),&sd->bl,ALL_CLIENT); // Now UPDATE all client. +} + +void clif_PartyBookingDeleteNotify(struct map_session_data* sd, int index) +{ + uint8 buf[6]; + WBUFW(buf,0) = 0x80b; + WBUFL(buf,2) = index; + + clif_send(buf, packet_len(0x80b), &sd->bl, ALL_CLIENT); // Now UPDATE all client. +} + /*========================================== * IX *------------------------------------------*/ @@ -14214,7 +14355,11 @@ static int packetdb_readdb(void) 0, 0, 0, 0, 0, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, -1, -1, -1, 8, 0, 0, 0, 26, 0, //#0x0800 - -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 20, +#if PACKETVER < 20091229 + -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 20, +#else // for Party booking ( PACKETVER >= 20091229 ) + -1, -1, 18, 4, 8, 6, 2, 4, 14, 50, 18, 6, 2, 3, 14, 20, +#endif 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/src/map/clif.h b/src/map/clif.h index 035052256..1def2233f 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -466,4 +466,11 @@ void clif_party_show_picker(struct map_session_data * sd, struct item * item_dat void clif_progressbar(struct map_session_data * sd, unsigned long color, unsigned int second); void clif_progressbar_abort(struct map_session_data * sd); +void clif_PartyBookingRegisterAck(struct map_session_data *sd, int flag); +void clif_PartyBookingDeleteAck(struct map_session_data* sd, int flag); +void clif_PartyBookingSearchAck(int fd, unsigned long *index, int count, bool more_result); +void clif_PartyBookingUpdateNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad); +void clif_PartyBookingDeleteNotify(struct map_session_data* sd, int index); +void clif_PartyBookingInsertNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad); + #endif /* _CLIF_H_ */ diff --git a/src/map/map.c b/src/map/map.c index 27d7e01d8..c9f9a6294 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1665,6 +1665,8 @@ int map_quit(struct map_session_data *sd) } } + party_booking_delete(sd, true); // Party Booking [Spiria] + party_booking_delete(sd, true); // Party Booking [Spiria] pc_makesavestatus(sd); pc_clean_skilltree(sd); chrif_save(sd,1); diff --git a/src/map/party.c b/src/map/party.c index 53755b777..33c079fdf 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -29,7 +29,9 @@ static DBMap* party_db; // int party_id -> struct party_data* +static DBMap* party_booking_db; // Party Booking [Spiria] int party_send_xy_timer(int tid, unsigned int tick, int id, intptr data); +bool check_party_leader(struct map_session_data *sd, struct party_data *p); // Party Booking [Spiria] /*========================================== * Fills the given party_member structure according to the sd provided. @@ -84,11 +86,13 @@ static TBL_PC* party_sd_check(int party_id, int account_id, int char_id) void do_final_party(void) { party_db->destroy(party_db,NULL); + party_booking_db->destroy(party_booking_db,NULL); // Party Booking [Spiria] } // 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] add_timer_func_list(party_send_xy_timer, "party_send_xy_timer"); add_timer_interval(gettick()+battle_config.party_update_interval, party_send_xy_timer, 0, 0, battle_config.party_update_interval); } @@ -511,6 +515,11 @@ int party_leave(struct map_session_data *sd) if( i == MAX_PARTY ) return 0; + if( check_party_leader(sd, p) ){ // when party leader leaves party, cancel booking. + party_booking_delete(sd,true); + clif_PartyBookingDeleteAck(sd,0); + } + intif_party_leave(p->party.party_id,sd->status.account_id,sd->status.char_id); return 1; } @@ -656,6 +665,8 @@ bool party_changeleader(struct map_session_data *sd, struct map_session_data *ts //Update info. intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id); clif_party_info(p,NULL); + party_booking_delete(sd, true); // Party Booking [Spiria] + clif_PartyBookingDeleteAck(sd, 0); // Close small window return true; } @@ -1054,3 +1065,142 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess return total; } + +/*========================================== + * Party Booking in KRO [Spiria] + *------------------------------------------*/ + +static struct party_booking_ad_info* create_party_booking_data(int party_id) +{ + struct party_booking_ad_info *pb_ad; + CREATE(pb_ad, struct party_booking_ad_info, 1); + pb_ad->index = party_id; + return pb_ad; +} + +struct party_booking_ad_info* party_booking_getdata(unsigned long index) +{ + struct party_booking_ad_info *pb_ad; + pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, index); + return pb_ad; +} + +bool check_party_leader(struct map_session_data *sd, struct party_data *p) +{ + int i; + + if (!sd || !sd->status.party_id) return false; + + if( p == NULL ) return false; + + ARR_FIND(0, MAX_PARTY, i, p->party.member[i].leader && p->party.member[i].online && p->data[i].sd == sd); + if(i == MAX_PARTY) return false; + + return true; +} + +void party_booking_register(struct map_session_data *sd, short level, short mapid, short* job) +{ + struct party_booking_ad_info *pb_ad; + struct party_data *p=party_search(sd->status.party_id); + int i; + + if (!check_party_leader(sd, p)) { + clif_PartyBookingRegisterAck(sd, 1); + return; + } + + pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, p->party.party_id); + + if( pb_ad == NULL ) + { + pb_ad = create_party_booking_data(p->party.party_id); + idb_put(party_booking_db, pb_ad->index, pb_ad); + } + + memcpy(pb_ad->charname,sd->status.name,NAME_LENGTH); + pb_ad->starttime = (int)time(NULL); + pb_ad->p_detail.level = level; + pb_ad->p_detail.mapid = mapid; + + for(i=0;i<6;i++) + if(job[i] != 0xFF) + pb_ad->p_detail.job[i] = job[i]; + else pb_ad->p_detail.job[i] = -1; + + clif_PartyBookingRegisterAck(sd, 0); + clif_PartyBookingInsertNotify(sd, pb_ad); // Notice + clif_PartyBookingSearchAck(sd->fd, &pb_ad->index, 1, false); // Update Client! + return; +} + +void party_booking_update(struct map_session_data *sd, short* job) +{ + int i; + struct party_data *p=party_search(sd->status.party_id); + struct party_booking_ad_info *pb_ad; + + if (!check_party_leader(sd, p)) { + return; + } + + pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, p->party.party_id); + + if( pb_ad == NULL ) + return; + + pb_ad->starttime = (int)time(NULL);// Update time. + + for(i=0;i<6;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); + return; +} + +void party_booking_search(struct map_session_data *sd, short level, short mapid, short job, unsigned long lastindex, short resultcount) +{ + struct party_booking_ad_info *pb_ad; + int i, count=0; + unsigned long index_list[10]; + bool more_result = false; + DBIterator* iter = party_booking_db->iterator(party_booking_db); + + memset(index_list, 0, sizeof(index_list)); + + for( pb_ad = (struct party_booking_ad_info*)iter->first(iter,NULL); iter->exists(iter); pb_ad = (struct party_booking_ad_info*)iter->next(iter,NULL) ) + { + if (pb_ad->index < lastindex || (pb_ad->p_detail.level < level || pb_ad->p_detail.level-15 > level)) + continue; + if (count >= 10){ + more_result = true; + break; + } + if (mapid == 0 && job == -1) + index_list[count] = pb_ad->index; + else if (mapid == 0) { + for(i=0; i<6; i++) + if (pb_ad->p_detail.job[i] == job && job != -1) + index_list[count] = pb_ad->index; + } else if (job == -1){ + if (pb_ad->p_detail.mapid == mapid) + index_list[count] = pb_ad->index; + } + count++; + } + iter->destroy(iter); + clif_PartyBookingSearchAck(sd->fd, index_list, count, more_result); +} + +bool party_booking_delete(struct map_session_data *sd, bool force_delete) +{ + struct party_data *p=party_search(sd->status.party_id); + if (!check_party_leader(sd, p) && !force_delete) { + return false; + } + clif_PartyBookingDeleteNotify(sd, sd->status.party_id); + idb_remove(party_booking_db,sd->status.party_id); + return true; +} diff --git a/src/map/party.h b/src/map/party.h index 25142e4af..d396d0fe6 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -31,6 +31,18 @@ struct party_data { } state; }; +struct party_booking_detail { + short level; + short mapid; + short job[6]; +}; + +struct party_booking_ad_info { + unsigned long index; + char charname[NAME_LENGTH]; + long starttime; + struct party_booking_detail p_detail; +}; void do_init_party(void); void do_final_party(void); @@ -68,4 +80,13 @@ int party_send_dot_remove(struct map_session_data *sd); int party_sub_count(struct block_list *bl, va_list ap); int party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range,...); +/*========================================== + * Party Booking in KRO [Spiria] + *------------------------------------------*/ +struct party_booking_ad_info* party_booking_getdata(unsigned long index); +void party_booking_register(struct map_session_data *sd, short level, short mapid, short* job); +void party_booking_update(struct map_session_data *sd, short* job); +void party_booking_search(struct map_session_data *sd, short level, short mapid, short job, unsigned long lastindex, short resultcount); +bool party_booking_delete(struct map_session_data *sd, bool force_delete); + #endif /* _PARTY_H_ */ -- cgit v1.2.3-70-g09d2