diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/chrif.c | 7 | ||||
-rw-r--r-- | src/map/clif.c | 18 | ||||
-rw-r--r-- | src/map/intif.c | 47 | ||||
-rw-r--r-- | src/map/intif.h | 2 | ||||
-rw-r--r-- | src/map/map.c | 3 | ||||
-rw-r--r-- | src/map/mercenary.c | 11 | ||||
-rw-r--r-- | src/map/mercenary.h | 2 | ||||
-rw-r--r-- | src/map/unit.c | 340 |
8 files changed, 277 insertions, 153 deletions
diff --git a/src/map/chrif.c b/src/map/chrif.c index a46186fc1..8ebb88226 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -281,11 +281,12 @@ int chrif_save(struct map_session_data *sd, int flag) WFIFOSET(char_fd, WFIFOW(char_fd,2)); - if(sd->status.pet_id > 0 && sd->pd) + if( sd->status.pet_id > 0 && sd->pd ) intif_save_petdata(sd->status.account_id,&sd->pd->pet); - - if (sd->hd && merc_is_hom_active(sd->hd)) + if( sd->hd && merc_is_hom_active(sd->hd) ) merc_save(sd->hd); + if( sd->md && sd->md->mercenary.remain_life_time > 0 ) + mercenary_save(sd->md); return 0; } diff --git a/src/map/clif.c b/src/map/clif.c index 202828788..a82495aa0 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -7056,7 +7056,8 @@ int clif_charnameack (int fd, struct block_list *bl) WBUFW(buf,0) = cmd; WBUFL(buf,2) = bl->id; - switch(bl->type) { + switch( bl->type ) + { case BL_PC: { struct map_session_data *ssd = (struct map_session_data *)bl; @@ -7117,6 +7118,9 @@ int clif_charnameack (int fd, struct block_list *bl) case BL_HOM: memcpy(WBUFP(buf,6), ((TBL_HOM*)bl)->homunculus.name, NAME_LENGTH); break; + case BL_MER: + memcpy(WBUFP(buf,6), ((TBL_MER*)bl)->db->name, NAME_LENGTH); + break; case BL_PET: memcpy(WBUFP(buf,6), ((TBL_PET*)bl)->pet.name, NAME_LENGTH); break; @@ -12352,7 +12356,7 @@ void clif_mercenary_info(struct map_session_data *sd) fd = sd->fd; status = &md->battle_status; - WFIFOHEAD(fd,72); + WFIFOHEAD(fd,80); WFIFOW(fd,0) = 0x029b; WFIFOL(fd,2) = md->bl.id; WFIFOW(fd,6) = cap_value(status->rhw.atk2+status->batk, 0, SHRT_MAX); @@ -12369,10 +12373,12 @@ void clif_mercenary_info(struct map_session_data *sd) WFIFOL(fd,52) = status->max_hp; WFIFOL(fd,56) = status->sp; WFIFOL(fd,60) = status->max_sp; - WFIFOL(fd,64) = 0; // Expiration Time - WFIFOW(fd,68) = 0; // No documentation (Guild Rank?) - WFIFOW(fd,70) = 0; // Times Summoned - WFIFOSET(fd,72); + WFIFOL(fd,64) = 0; // Contract End + WFIFOW(fd,68) = 0; // Loyalty + WFIFOL(fd,70) = 0; // Summon Count + WFIFOL(fd,74) = 0; // Kill Counter + WFIFOW(fd,78) = 0; + WFIFOSET(fd,80); } void clif_mercenary_skillblock(struct map_session_data *sd) diff --git a/src/map/intif.c b/src/map/intif.c index 6a46c6d3c..8615317c8 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -38,7 +38,7 @@ static const int packet_len_table[]={ 9, 9,-1,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840 -1,-1, 7, 7, 7,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] -1,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] - -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3870 Mercenaries [Zephyrus] + -1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3870 Mercenaries [Zephyrus] 11,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880 -1,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator] }; @@ -1909,6 +1909,49 @@ int intif_mercenary_request(int merc_id, int char_id) return 0; } +int intif_mercenary_delete(int merc_id) +{ + if (CheckForCharServer()) + return 0; + + WFIFOHEAD(inter_fd,6); + WFIFOW(inter_fd,0) = 0x3072; + WFIFOL(inter_fd,2) = merc_id; + WFIFOSET(inter_fd,6); + return 0; +} + +int intif_parse_mercenary_deleted(int fd) +{ + if( RFIFOB(fd,2) != 1 ) + ShowError("Mercenary data delete failure\n"); + + return 0; +} + +int intif_mercenary_save(struct s_mercenary *merc) +{ + int size = sizeof(struct s_mercenary) + 4; + + if( CheckForCharServer() ) + return 0; + + WFIFOHEAD(inter_fd,size); + WFIFOW(inter_fd,0) = 0x3073; + WFIFOW(inter_fd,2) = size; + memcpy(WFIFOP(inter_fd,4), merc, sizeof(struct s_mercenary)); + WFIFOSET(inter_fd,size); + return 0; +} + +int intif_parse_mercenary_saved(int fd) +{ + if( RFIFOB(fd,2) != 1 ) + ShowError("Mercenary data save failure\n"); + + return 0; +} + //----------------------------------------------------------------- // inter serverからの通信 // エラーがあれば0(false)を返すこと @@ -1999,6 +2042,8 @@ int intif_parse(int fd) #endif // Mercenary System case 0x3870: intif_parse_mercenary_received(fd); break; + case 0x3871: intif_parse_mercenary_deleted(fd); break; + case 0x3872: intif_parse_mercenary_saved(fd); break; case 0x3880: intif_parse_CreatePet(fd); break; case 0x3881: intif_parse_RecvPetData(fd); break; diff --git a/src/map/intif.h b/src/map/intif.h index b1ee824e0..9ebbd6989 100644 --- a/src/map/intif.h +++ b/src/map/intif.h @@ -80,6 +80,8 @@ int intif_quest_add(int char_id, struct quest * qd); // MERCENARY SYSTEM int intif_mercenary_create(struct s_mercenary *merc); int intif_mercenary_request(int merc_id, int char_id); +int intif_mercenary_delete(int merc_id); +int intif_mercenary_save(struct s_mercenary *merc); #ifndef TXT_ONLY // MAIL SYSTEM diff --git a/src/map/map.c b/src/map/map.c index fad39c9cd..d1605a35e 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1584,7 +1584,8 @@ int map_quit(struct map_session_data *sd) //Unit_free handles clearing the player related data, //map_quit handles extra specific data which is related to quitting normally //(changing map-servers invokes unit_free but bypasses map_quit) - if(sd->sc.count) { + if( sd->sc.count ) + { //Status that are not saved... if(sd->sc.data[SC_BOSSMAPINFO]) status_change_end(&sd->bl,SC_BOSSMAPINFO,-1); diff --git a/src/map/mercenary.c b/src/map/mercenary.c index bc91a8c60..16851d8f7 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -54,7 +54,7 @@ int merc_search_index(int class_) bool merc_class(int class_) { - return (bool)(merc_search_index(class_) < 0); + return (bool)(merc_search_index(class_) > -1); } struct view_data * merc_get_viewdata(int class_) @@ -91,6 +91,15 @@ int merc_create(struct map_session_data *sd, int class_, unsigned int lifetime) return 1; } +int mercenary_save(struct mercenary_data *md) +{ + md->mercenary.hp = md->battle_status.hp; + md->mercenary.sp = md->battle_status.sp; + intif_mercenary_save(&md->mercenary); + + return 1; +} + int merc_data_received(struct s_mercenary *merc, bool flag) { struct map_session_data *sd; diff --git a/src/map/mercenary.h b/src/map/mercenary.h index a56ecf628..a9e572f50 100644 --- a/src/map/mercenary.h +++ b/src/map/mercenary.h @@ -40,7 +40,9 @@ struct mercenary_data { bool merc_class(int class_); struct view_data * merc_get_viewdata(int class_); +int merc_create(struct map_session_data *sd, int class_, unsigned int lifetime); int merc_data_received(struct s_mercenary *merc, bool flag); +int mercenary_save(struct mercenary_data *md); // Homunculus DB Structures // =================================== diff --git a/src/map/unit.c b/src/map/unit.c index e8d33b4c9..20cd20de6 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1772,9 +1772,9 @@ int unit_remove_map_(struct block_list *bl, int clrtype, const char* file, int l } case BL_HOM: { - struct homun_data *hd = (struct homun_data *) bl; + struct homun_data *hd = (struct homun_data *)bl; ud->canact_tick = ud->canmove_tick; //It appears HOM do reset the can-act tick. - if(!hd->homunculus.intimacy && !(hd->master && !hd->master->state.active) ) + if( !hd->homunculus.intimacy && !(hd->master && !hd->master->state.active) ) { //If logging out, this is deleted on unit_free clif_emotion(bl, 28) ; //sob clif_clearunit_area(bl,clrtype); @@ -1786,6 +1786,20 @@ int unit_remove_map_(struct block_list *bl, int clrtype, const char* file, int l break; } + case BL_MER: + { + struct mercenary_data *md = (struct mercenary_data *)bl; + ud->canact_tick = ud->canmove_tick; + if( !md->mercenary.remain_life_time && !(md->master && !md->master->state.active) ) + { + clif_clearunit_area(bl,clrtype); + map_delblock(bl); + unit_free(bl,0); + map_freeblock_unlock(); + return 0; + } + break; + } default: ;// do nothing } @@ -1805,12 +1819,15 @@ void unit_remove_map_pc(struct map_session_data *sd, int clrtype) unit_remove_map(&sd->pd->bl, clrtype); if(merc_is_hom_active(sd->hd)) unit_remove_map(&sd->hd->bl, clrtype); + if(sd->md) + unit_remove_map(&sd->md->bl, clrtype); } void unit_free_pc(struct map_session_data *sd) { if (sd->pd) unit_free(&sd->pd->bl,0); if (sd->hd) unit_free(&sd->hd->bl,0); + if (sd->md) unit_free(&sd->md->bl,0); unit_free(&sd->bl,3); } @@ -1828,171 +1845,212 @@ int unit_free(struct block_list *bl, int clrtype) map_freeblock_lock(); if( bl->prev ) //Players are supposed to logout with a "warp" effect. unit_remove_map(bl, clrtype); - - if( bl->type == BL_PC ) { - struct map_session_data *sd = (struct map_session_data*)bl; - if(status_isdead(bl)) - pc_setrestartvalue(sd,2); - - pc_delinvincibletimer(sd); - - pc_autoscript_clear(sd->autoscript, ARRAYLENGTH(sd->autoscript)); - pc_autoscript_clear(sd->autoscript2, ARRAYLENGTH(sd->autoscript2)); - - if (sd->followtimer != -1) - pc_stop_following(sd); - - if(sd->duel_invite > 0) - duel_reject(sd->duel_invite, sd); - - // Notify friends that this char logged out. [Skotlex] - map_foreachpc(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 0); - party_send_logout(sd); - guild_send_memberinfoshort(sd,0); - pc_cleareventtimer(sd); - pc_delspiritball(sd,sd->spiritball,1); - - if(sd->reg) - { //Double logout already freed pointer fix... [Skotlex] - aFree(sd->reg); - sd->reg = NULL; - sd->reg_num = 0; - } - if(sd->regstr) - { - int i; - for( i = 0; i < sd->regstr_num; ++i ) - if( sd->regstr[i].data ) - aFree(sd->regstr[i].data); - aFree(sd->regstr); - sd->regstr = NULL; - sd->regstr_num = 0; - } - //Tell the script to end, not delete it, it will free itself when necessary [Kevin] - if (sd->st) { - sd->st->rid = 0; - sd->st->state = END; - } - } else if( bl->type == BL_PET ) { - struct pet_data *pd = (struct pet_data*)bl; - struct map_session_data *sd = pd->msd; - pet_hungry_timer_delete(pd); - if (pd->a_skill) + switch( bl->type ) + { + case BL_PC: { - aFree(pd->a_skill); - pd->a_skill = NULL; + struct map_session_data *sd = (struct map_session_data*)bl; + if( status_isdead(bl) ) + pc_setrestartvalue(sd,2); + + pc_delinvincibletimer(sd); + pc_autoscript_clear(sd->autoscript, ARRAYLENGTH(sd->autoscript)); + pc_autoscript_clear(sd->autoscript2, ARRAYLENGTH(sd->autoscript2)); + + if( sd->followtimer != -1 ) + pc_stop_following(sd); + + if( sd->duel_invite > 0 ) + duel_reject(sd->duel_invite, sd); + + // Notify friends that this char logged out. [Skotlex] + map_foreachpc(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 0); + party_send_logout(sd); + guild_send_memberinfoshort(sd,0); + pc_cleareventtimer(sd); + pc_delspiritball(sd,sd->spiritball,1); + + if( sd->reg ) + { //Double logout already freed pointer fix... [Skotlex] + aFree(sd->reg); + sd->reg = NULL; + sd->reg_num = 0; + } + if( sd->regstr ) + { + int i; + for( i = 0; i < sd->regstr_num; ++i ) + if( sd->regstr[i].data ) + aFree(sd->regstr[i].data); + aFree(sd->regstr); + sd->regstr = NULL; + sd->regstr_num = 0; + } + //Tell the script to end, not delete it, it will free itself when necessary [Kevin] + if( sd->st ) + { + sd->st->rid = 0; + sd->st->state = END; + } + break; } - if (pd->s_skill) + case BL_PET: { - if (pd->s_skill->timer != -1) { - if (pd->s_skill->id) - delete_timer(pd->s_skill->timer, pet_skill_support_timer); + struct pet_data *pd = (struct pet_data*)bl; + struct map_session_data *sd = pd->msd; + pet_hungry_timer_delete(pd); + if( pd->a_skill ) + { + aFree(pd->a_skill); + pd->a_skill = NULL; + } + if( pd->s_skill ) + { + if (pd->s_skill->timer != -1) { + if (pd->s_skill->id) + delete_timer(pd->s_skill->timer, pet_skill_support_timer); + else + delete_timer(pd->s_skill->timer, pet_heal_timer); + } + aFree(pd->s_skill); + pd->s_skill = NULL; + } + if( pd->recovery ) + { + if(pd->recovery->timer != -1) + delete_timer(pd->recovery->timer, pet_recovery_timer); + aFree(pd->recovery); + pd->recovery = NULL; + } + if( pd->bonus ) + { + if (pd->bonus->timer != -1) + delete_timer(pd->bonus->timer, pet_skill_bonus_timer); + aFree(pd->bonus); + pd->bonus = NULL; + } + if( pd->loot ) + { + pet_lootitem_drop(pd,sd); + if (pd->loot->item) + aFree(pd->loot->item); + aFree (pd->loot); + pd->loot = NULL; + } + if( clrtype >= 0 ) + { + if( pd->pet.intimate > 0 ) + intif_save_petdata(pd->pet.account_id,&pd->pet); else - delete_timer(pd->s_skill->timer, pet_heal_timer); + { //Remove pet. + intif_delete_petdata(pd->pet.pet_id); + if (sd) sd->status.pet_id = 0; + } } - aFree(pd->s_skill); - pd->s_skill = NULL; - } - if(pd->recovery) - { - if(pd->recovery->timer != -1) - delete_timer(pd->recovery->timer, pet_recovery_timer); - aFree(pd->recovery); - pd->recovery = NULL; - } - if(pd->bonus) - { - if (pd->bonus->timer != -1) - delete_timer(pd->bonus->timer, pet_skill_bonus_timer); - aFree(pd->bonus); - pd->bonus = NULL; + if( sd ) + sd->pd = NULL; + break; } - if (pd->loot) + case BL_MOB: { - pet_lootitem_drop(pd,sd); - if (pd->loot->item) - aFree(pd->loot->item); - aFree (pd->loot); - pd->loot = NULL; - } - if (clrtype >= 0) { - if(pd->pet.intimate > 0) - intif_save_petdata(pd->pet.account_id,&pd->pet); - else - { //Remove pet. - intif_delete_petdata(pd->pet.pet_id); - if (sd) sd->status.pet_id = 0; + struct mob_data *md = (struct mob_data*)bl; + if( md->deletetimer != -1 ) + { + delete_timer(md->deletetimer,mob_timer_delete); + md->deletetimer = INVALID_TIMER; } - } - if (sd) sd->pd = NULL; - } else if(bl->type == BL_MOB) { - struct mob_data *md = (struct mob_data*)bl; - if(md->deletetimer!=-1) { - delete_timer(md->deletetimer,mob_timer_delete); - md->deletetimer = INVALID_TIMER; - } - if(md->lootitem) { - aFree(md->lootitem); - md->lootitem=NULL; - } - if( md->guardian_data ) - { - struct guild_castle* gc = md->guardian_data->castle; - if( md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS ) + if( md->lootitem ) { - gc->guardian[md->guardian_data->number].id = 0; + aFree(md->lootitem); + md->lootitem=NULL; } - else + if( md->guardian_data ) { - int i; - ARR_FIND(0, gc->temp_guardians_max, i, gc->temp_guardians[i] == md->bl.id); - if( i < gc->temp_guardians_max ) - gc->temp_guardians[i] = 0; + struct guild_castle* gc = md->guardian_data->castle; + if( md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS ) + { + gc->guardian[md->guardian_data->number].id = 0; + } + else + { + int i; + ARR_FIND(0, gc->temp_guardians_max, i, gc->temp_guardians[i] == md->bl.id); + if( i < gc->temp_guardians_max ) + gc->temp_guardians[i] = 0; + } + aFree(md->guardian_data); + md->guardian_data = NULL; + } + if( md->spawn ) + { + md->spawn->active--; + if( !md->spawn->state.dynamic ) + {// permanently remove the mob + if( --md->spawn->num == 0 ) + {// Last freed mob is responsible for deallocating the group's spawn data. + aFree(md->spawn); + md->spawn = NULL; + } + } } - aFree(md->guardian_data); - md->guardian_data = NULL; + if( md->base_status) + { + aFree(md->base_status); + md->base_status = NULL; + } + if( mob_is_clone(md->class_) ) + mob_clone_delete(md->class_); + + break; } - if(md->spawn) + case BL_HOM: { - md->spawn->active--; - - if( !md->spawn->state.dynamic ) - {// permanently remove the mob - if( --md->spawn->num == 0 ) - {// Last freed mob is responsible for deallocating the group's spawn data. - aFree(md->spawn); - md->spawn = NULL; + struct homun_data *hd = (TBL_HOM*)bl; + struct map_session_data *sd = hd->master; + // Desactive timers + merc_hom_hungry_timer_delete(hd); + if( clrtype >= 0 ) + { + if( hd->homunculus.intimacy > 0 ) + merc_save(hd); + else + { + intif_homunculus_requestdelete(hd->homunculus.hom_id); + if( sd ) + sd->status.hom_id = 0; } } + if( sd ) + sd->hd = NULL; + break; } - if(md->base_status) { - aFree(md->base_status); - md->base_status = NULL; - } - if(mob_is_clone(md->class_)) - mob_clone_delete(md->class_); - } else if(bl->type == BL_HOM) { - struct homun_data *hd = (TBL_HOM*)bl; - struct map_session_data *sd = hd->master; - // Desactive timers - merc_hom_hungry_timer_delete(hd); - if (clrtype >= 0) { - if (hd->homunculus.intimacy > 0) - merc_save(hd); - else + case BL_MER: + { + struct mercenary_data *md = (TBL_MER*)bl; + struct map_session_data *sd = md->master; + /* Stop Mercenary Timer */ + if( clrtype >= 0 ) { - intif_homunculus_requestdelete(hd->homunculus.hom_id); - if (sd) sd->status.hom_id = 0; + if( md->mercenary.remain_life_time > 0 ) + mercenary_save(md); + else + { + intif_mercenary_delete(md->mercenary.mercenary_id); + if( sd ) + sd->status.mer_id = 0; + } } + if( sd ) + sd->md = NULL; + break; } - if(sd) sd->hd = NULL; } skill_clear_unitgroup(bl); status_change_clear(bl,1); map_deliddb(bl); - if (bl->type != BL_PC) //Players are handled by map_quit + if( bl->type != BL_PC ) //Players are handled by map_quit map_freeblock(bl); map_freeblock_unlock(); return 0; |