diff options
author | zephyrus <zephyrus@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-08-23 13:09:50 +0000 |
---|---|---|
committer | zephyrus <zephyrus@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-08-23 13:09:50 +0000 |
commit | 94281a398ef3a288a23cebb9f2d9a5227c570996 (patch) | |
tree | b55207b5a40b9c019d150772ddbb1ffc6661f80c /src/map | |
parent | 59b08db5fcebd6e3d94f5353602fc685dbf9e3f5 (diff) | |
download | hercules-94281a398ef3a288a23cebb9f2d9a5227c570996.tar.gz hercules-94281a398ef3a288a23cebb9f2d9a5227c570996.tar.bz2 hercules-94281a398ef3a288a23cebb9f2d9a5227c570996.tar.xz hercules-94281a398ef3a288a23cebb9f2d9a5227c570996.zip |
- Mercenary Packets (Server to Client). Still need a little more info.
- Packet for Mercenary Menu.
- Some other progress as creation but need more code.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13116 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/clif.c | 144 | ||||
-rw-r--r-- | src/map/clif.h | 4 | ||||
-rw-r--r-- | src/map/intif.c | 40 | ||||
-rw-r--r-- | src/map/intif.h | 3 | ||||
-rw-r--r-- | src/map/mercenary.c | 124 | ||||
-rw-r--r-- | src/map/mercenary.h | 11 | ||||
-rw-r--r-- | src/map/status.c | 24 | ||||
-rw-r--r-- | src/map/unit.c | 3 |
8 files changed, 320 insertions, 33 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index f4ed8d1df..202828788 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1122,14 +1122,14 @@ int clif_homskillinfoblock(struct map_session_data *sd) WFIFOW(fd,0)=0x235; for ( i = 0; i < MAX_HOMUNSKILL; i++){ if( (id = hd->homunculus.hskill[i].id) != 0 ){ - j = id - HM_SKILLBASE ; - WFIFOW(fd,len ) = id ; - WFIFOW(fd,len+2) = skill_get_inf(id) ; - WFIFOW(fd,len+4) = 0 ; - WFIFOW(fd,len+6) = hd->homunculus.hskill[j].lv ; - WFIFOW(fd,len+8) = skill_get_sp(id,hd->homunculus.hskill[j].lv) ; - WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,hd->homunculus.hskill[j].lv) ; - safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH) ; + j = id - HM_SKILLBASE; + WFIFOW(fd,len ) = id; + WFIFOW(fd,len+2) = skill_get_inf(id); + WFIFOW(fd,len+4) = 0; + WFIFOW(fd,len+6) = hd->homunculus.hskill[j].lv; + WFIFOW(fd,len+8) = skill_get_sp(id,hd->homunculus.hskill[j].lv); + WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,hd->homunculus.hskill[j].lv); + safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH); WFIFOB(fd,len+36) = (hd->homunculus.hskill[j].lv < merc_skill_tree_get_max(id, hd->homunculus.class_))?1:0; len+=37; } @@ -11272,20 +11272,23 @@ void clif_parse_HomMoveToMaster(int fd, struct map_session_data *sd) unit_walktoxy(&sd->hd->bl, sd->bl.x,sd->bl.y-1, 4); } -void clif_parse_HomMoveTo(int fd,struct map_session_data *sd) +void clif_parse_HomMoveTo(int fd, struct map_session_data *sd) { - short x,y,cmd; - - if(!merc_is_hom_active(sd->hd)) - return; + int id = RFIFOL(fd,2); // Mercenary or Homunculus + struct block_list *bl = NULL; + short x, y, cmd; cmd = RFIFOW(fd,0); - x = RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]) * 4 + - (RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0] + 1) >> 6); - y = ((RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]+1) & 0x3f) << 4) + - (RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0] + 2) >> 4); + x = RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]) * 4 + (RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0] + 1) >> 6); + y = ((RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]+1) & 0x3f) << 4) + (RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0] + 2) >> 4); + + if( sd->md && sd->md->bl.id == id ) + bl = &sd->md->bl; // Moving Mercenary + else if( merc_is_hom_active(sd->hd) && sd->hd->bl.id == id ) + bl = &sd->hd->bl; // Moving Homunculus + else return; - unit_walktoxy(&(sd->hd->bl),x,y,4); + unit_walktoxy(bl, x, y, 4); } void clif_parse_HomAttack(int fd,struct map_session_data *sd) @@ -12334,6 +12337,110 @@ void clif_send_quest_status(struct map_session_data * sd, int quest_id, bool act WFIFOSET(fd, 7); } +/*========================================== + * Mercenary System + *==========================================*/ +void clif_mercenary_info(struct map_session_data *sd) +{ + int fd; + struct mercenary_data *md; + struct status_data *status; + + if( sd == NULL || (md = sd->md) == NULL ) + return; + + fd = sd->fd; + status = &md->battle_status; + + WFIFOHEAD(fd,72); + WFIFOW(fd,0) = 0x029b; + WFIFOL(fd,2) = md->bl.id; + WFIFOW(fd,6) = cap_value(status->rhw.atk2+status->batk, 0, SHRT_MAX); + WFIFOW(fd,8) = cap_value(status->matk_max, 0, SHRT_MAX); + WFIFOW(fd,10) = status->hit; + WFIFOW(fd,12) = status->cri/10; + WFIFOW(fd,14) = status->def + status->vit; + WFIFOW(fd,16) = status->mdef; + WFIFOW(fd,18) = status->flee; + WFIFOW(fd,20) = status->amotion; + safestrncpy((char*)WFIFOP(fd,22), md->db->name, NAME_LENGTH); + WFIFOW(fd,46) = md->db->lv; + WFIFOL(fd,48) = status->hp; + 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); +} + +void clif_mercenary_skillblock(struct map_session_data *sd) +{ + struct mercenary_data *md; + int fd, i, len = 4, id, j; + + if( sd == NULL || (md = sd->md) == NULL ) + return; + + fd = sd->fd; + WFIFOHEAD(fd,4+37*MAX_MERCSKILL); + WFIFOW(fd,0) = 0x029d; + for( i = 0; i < MAX_MERCSKILL; i++ ) + { + if( (id = md->db->skill[i].id) == 0 ) + continue; + j = id - MC_SKILLBASE; + WFIFOW(fd,len) = id; + WFIFOW(fd,len+2) = skill_get_inf(id); + WFIFOW(fd,len+4) = 0; + WFIFOW(fd,len+6) = md->db->skill[j].lv; + WFIFOW(fd,len+8) = skill_get_sp(id, md->db->skill[j].lv); + WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, md->db->skill[j].lv); + safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH); + WFIFOB(fd,len+36) = 0; // Skillable for Mercenary? + len += 37; + } + + WFIFOW(fd,2) = len; + WFIFOSET(fd,len); +} + +void clif_mercenary_updatestatus(struct map_session_data *sd, int type) +{ + struct mercenary_data *md; + int fd; + if( sd == NULL || (md = sd->md) == NULL ) + return; + + fd = sd->fd; + WFIFOHEAD(fd,8); + WFIFOW(fd,0) = 0x02a2; + WFIFOW(fd,2) = type; + switch( type ) + { + case SP_HP: + WFIFOL(fd,4) = md->battle_status.hp; + break; + case SP_MAXHP: + WFIFOL(fd,4) = md->battle_status.max_hp; + break; + case SP_SP: + WFIFOL(fd,4) = md->battle_status.sp; + break; + case SP_MAXSP: + WFIFOL(fd,4) = md->battle_status.max_sp; + break; + } + WFIFOSET(fd,8); +} + +void clif_parse_mercenary_action(int fd, struct map_session_data* sd) +{ + int option = RFIFOB(fd,2); + if( sd->md == NULL ) + return; +} /*========================================== * パケットデバッグ @@ -12780,6 +12887,7 @@ static int packetdb_readdb(void) {clif_parse_cashshop_buy,"cashshopbuy"}, {clif_parse_ViewPlayerEquip,"viewplayerequip"}, {clif_parse_EquipTick,"equiptickbox"}, + {clif_parse_mercenary_action,"mermenu"}, {NULL,NULL} }; diff --git a/src/map/clif.h b/src/map/clif.h index 8c8a40211..f136d4424 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -439,4 +439,8 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd); // ADOPTION void clif_Adopt_reply(struct map_session_data *sd, int type); +// MERCENARIES +void clif_mercenary_info(struct map_session_data *sd); +void clif_mercenary_skillblock(struct map_session_data *sd); + #endif /* _CLIF_H_ */ diff --git a/src/map/intif.c b/src/map/intif.c index 896c30626..7288ec8f8 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] - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 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] }; @@ -1864,6 +1864,41 @@ static void intif_parse_Auction_message(int fd) #endif +/*========================================== + * Mercenary's System + *------------------------------------------*/ +int intif_mercenary_create(struct s_mercenary *merc) +{ + int size = sizeof(struct s_mercenary) + 4; + + if( CheckForCharServer() ) + return 0; + + WFIFOHEAD(inter_fd,size); + WFIFOW(inter_fd,0) = 0x3070; + 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_create(int fd) +{ + int len = RFIFOW(fd,2) - 5; + if( sizeof(struct s_mercenary) != len ) + { + if( battle_config.etc_log ) + ShowError("intif: create mercenary data size error %d != %d\n", sizeof(struct s_homunculus), len); + return 0; + } + + merc_data_received((struct s_mercenary*)RFIFOP(fd,9), RFIFOB(fd,8)); + return 0; +} + + + + //----------------------------------------------------------------- // inter serverからの通信 // エラーがあれば0(false)を返すこと @@ -1952,6 +1987,9 @@ int intif_parse(int fd) case 0x3854: intif_parse_Auction_message(fd); break; case 0x3855: intif_parse_Auction_bid(fd); break; #endif +// Mercenary System + case 0x3870: intif_parse_mercenary_create(fd); break; + case 0x3880: intif_parse_CreatePet(fd); break; case 0x3881: intif_parse_RecvPetData(fd); break; case 0x3882: intif_parse_SavePetOk(fd); break; diff --git a/src/map/intif.h b/src/map/intif.h index c32b09352..0b4cf348f 100644 --- a/src/map/intif.h +++ b/src/map/intif.h @@ -77,6 +77,9 @@ int intif_request_questlog(struct map_session_data * sd); int intif_quest_delete(int char_id, int quest_id); int intif_quest_add(int char_id, struct quest * qd); +// MERCENARY SYSTEM +int intif_mercenary_create(struct s_mercenary *merc); + #ifndef TXT_ONLY // MAIL SYSTEM int intif_Mail_requestinbox(int char_id, unsigned char flag); diff --git a/src/map/mercenary.c b/src/map/mercenary.c index d3b2b7677..bc91a8c60 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -45,11 +45,115 @@ *------------------------------------------*/ struct s_mercenary_db mercenary_db[MAX_MERCENARY_CLASS]; // Mercenary Database -int merc_create(struct map_session_data *sd, int class_) +int merc_search_index(int class_) { + int i; + ARR_FIND(0, MAX_MERCENARY_CLASS, i, mercenary_db[i].class_ == class_); + return (i == MAX_MERCENARY_CLASS)?-1:i; +} + +bool merc_class(int class_) +{ + return (bool)(merc_search_index(class_) < 0); +} + +struct view_data * merc_get_viewdata(int class_) +{ + int i = merc_search_index(class_); + if( i < 0 ) + return 0; + + return &mercenary_db[i].vd; +} + +int merc_create(struct map_session_data *sd, int class_, unsigned int lifetime) +{ + struct s_mercenary merc; + struct s_mercenary_db *db; + int i; + nullpo_retr(1,sd); + + if( (i = merc_search_index(class_)) < 0 ) + return 0; + + db = &mercenary_db[i]; + memset(&merc,0,sizeof(struct s_mercenary)); + + merc.char_id = sd->status.char_id; + merc.class_ = class_; + merc.hp = db->status.max_hp; + merc.sp = db->status.max_sp; + merc.remain_life_time = lifetime; + + // Request Char Server to create this mercenary + intif_mercenary_create(&merc); + return 1; } +int merc_data_received(struct s_mercenary *merc, bool flag) +{ + struct map_session_data *sd; + struct mercenary_data *md; + struct s_mercenary_db *db; + int i = merc_search_index(merc->class_); + + if( (sd = map_charid2sd(merc->char_id)) == NULL ) + return 0; + if( !flag || i < 0 ) + { // Not created - loaded - DB info + sd->status.mer_id = 0; + return 0; + } + + sd->status.mer_id = merc->mercenary_id; + db = &mercenary_db[i]; + + if( !sd->md ) + { + short x = sd->bl.x, y = sd->bl.y; + + sd->md = md = (struct mercenary_data*)aCalloc(1,sizeof(struct mercenary_data)); + md->bl.type = BL_MER; + md->bl.id = npc_get_new_npc_id(); + + md->master = sd; + md->db = db; + memcpy(&md->mercenary, merc, sizeof(struct s_mercenary)); + status_set_viewdata(&md->bl, md->mercenary.class_); + status_change_init(&md->bl); + unit_dataset(&md->bl); + md->ud.dir = sd->ud.dir; + + md->bl.m = sd->bl.m; + md->bl.x = sd->bl.x; + md->bl.y = sd->bl.y; + x = sd->bl.x + 1; + y = sd->bl.y + 1; + map_random_dir(&md->bl, &x, &y); + md->bl.x = x; + md->bl.y = y; + + map_addiddb(&md->bl); + // status_calc_mercenary(md,1); + } + else + memcpy(&sd->md->mercenary, merc, sizeof(struct s_mercenary)); + + md = sd->md; + if( md && md->bl.prev == NULL && sd->bl.prev != NULL ) + { + map_addblock(&md->bl); + clif_spawn(&md->bl); + clif_mercenary_info(sd); + clif_mercenary_skillblock(sd); + // init timers + } + + return 1; +} + + /*========================================== * Homunculus's System *------------------------------------------*/ @@ -936,6 +1040,8 @@ int read_mercenarydb(void) db->lv = atoi(str[3]); status = &db->status; + db->vd.class_ = db->class_; + status->max_hp = atoi(str[4]); status->max_sp = atoi(str[5]); status->rhw.range = atoi(str[6]); @@ -1025,20 +1131,18 @@ int read_mercenary_skilldb(void) ShowError("read_mercenary_skilldb : Class not found in mercenary_db for skill entry, line %d.\n", k); continue; } - - db = &mercenary_db[i]; + skillid = atoi(str[1]); - skilllv = atoi(str[2]); - - ARR_FIND(0, MAX_MERCENARY_SKILL, i, db->skill[i].id == 0 || db->skill[i].id == skillid); - if( i == MAX_MERCENARY_SKILL ) + if( skillid < MC_SKILLBASE || skillid >= MC_SKILLBASE + MAX_MERCSKILL ) { - ShowError("read_mercenary_skilldb : No more free skill slots for Class %d, line %d.\n", class_, k); + ShowError("read_mercenary_skilldb : Skill out of range, line %d.\n", k); continue; } - if( db->skill[i].id == skillid ) - ShowError("read_mercenary_skilldb : Duplicate Skill for Class %d, line %d. Overwriting...\n", class_, k); + db = &mercenary_db[i]; + skilllv = atoi(str[2]); + + i = skillid - MC_SKILLBASE; db->skill[i].id = skillid; db->skill[i].lv = skilllv; j++; diff --git a/src/map/mercenary.h b/src/map/mercenary.h index 51fdea787..a56ecf628 100644 --- a/src/map/mercenary.h +++ b/src/map/mercenary.h @@ -16,9 +16,10 @@ struct s_mercenary_db { unsigned short lv; short range2, range3; struct status_data status; + struct view_data vd; struct { unsigned short id, lv; - } skill[MAX_MERCENARY_SKILL]; + } skill[MAX_MERCSKILL]; }; extern struct s_mercenary_db mercenary_db[MAX_MERCENARY_CLASS]; @@ -27,14 +28,20 @@ struct mercenary_data { struct block_list bl; struct unit_data ud; struct view_data *vd; - struct status_change *base_status, battle_status; + struct status_data *base_status, battle_status; struct status_change sc; struct regen_data regen; struct s_mercenary_db *db; struct s_mercenary mercenary; + + struct map_session_data *master; // Master of mercenary }; +bool merc_class(int class_); +struct view_data * merc_get_viewdata(int class_); +int merc_data_received(struct s_mercenary *merc, bool flag); + // Homunculus DB Structures // =================================== diff --git a/src/map/status.c b/src/map/status.c index 3925a86d2..c77e0ffcc 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -4046,7 +4046,8 @@ int status_get_lv(struct block_list *bl) case BL_MOB: return ((TBL_MOB*)bl)->level; case BL_PET: return ((TBL_PET*)bl)->pet.level; case BL_HOM: return ((TBL_HOM*)bl)->homunculus.level; - } + case BL_MER: return ((TBL_MER*)bl)->db->lv; + } return 1; } @@ -4162,6 +4163,10 @@ int status_get_guild_id(struct block_list *bl) if (((TBL_HOM*)bl)->master) return ((TBL_HOM*)bl)->master->status.guild_id; break; + case BL_MER: + if (((TBL_MER*)bl)->master) + return ((TBL_MER*)bl)->master->status.guild_id; + break; case BL_NPC: if (((TBL_NPC*)bl)->subtype == SCRIPT) return ((TBL_NPC*)bl)->u.scr.guild_id; @@ -4196,6 +4201,10 @@ int status_get_emblem_id(struct block_list *bl) if (((TBL_HOM*)bl)->master) return ((TBL_HOM*)bl)->master->guild_emblem_id; break; + case BL_MER: + if (((TBL_MER*)bl)->master) + return ((TBL_MER*)bl)->master->guild_emblem_id; + break; case BL_NPC: if (((TBL_NPC*)bl)->subtype == SCRIPT && ((TBL_NPC*)bl)->u.scr.guild_id > 0) { struct guild *g = guild_search(((TBL_NPC*)bl)->u.scr.guild_id); @@ -4253,6 +4262,7 @@ struct view_data* status_get_viewdata(struct block_list *bl) case BL_PET: return &((TBL_PET*)bl)->vd; case BL_NPC: return ((TBL_NPC*)bl)->vd; case BL_HOM: return ((TBL_HOM*)bl)->vd; + case BL_MER: return ((TBL_MER*)bl)->vd; } return NULL; } @@ -4267,6 +4277,8 @@ void status_set_viewdata(struct block_list *bl, int class_) vd = npc_get_viewdata(class_); else if (homdb_checkid(class_)) vd = merc_get_hom_viewdata(class_); + else if (merc_class(class_)) + vd = merc_get_viewdata(class_); else vd = NULL; @@ -4365,6 +4377,15 @@ void status_set_viewdata(struct block_list *bl, int class_) ShowError("status_set_viewdata (HOMUNCULUS): No view data for class %d\n", class_); } break; + case BL_MER: + { + struct mercenary_data *md = (struct mercenary_data*)bl; + if (vd) + md->vd = vd; + else + ShowError("status_set_viewdata (MERCENARY): No view data for class %d\n", class_); + } + break; } vd = status_get_viewdata(bl); if (vd && vd->cloth_color && ( @@ -4383,6 +4404,7 @@ struct status_change *status_get_sc(struct block_list *bl) case BL_MOB: return &((TBL_MOB*)bl)->sc; case BL_NPC: return &((TBL_NPC*)bl)->sc; case BL_HOM: return &((TBL_HOM*)bl)->sc; + case BL_MER: return &((TBL_MER*)bl)->sc; } return NULL; } diff --git a/src/map/unit.c b/src/map/unit.c index 73b0f023d..e8d33b4c9 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -42,7 +42,8 @@ struct unit_data* unit_bl2ud(struct block_list *bl) if( bl->type == BL_MOB) return &((struct mob_data*)bl)->ud; if( bl->type == BL_PET) return &((struct pet_data*)bl)->ud; if( bl->type == BL_NPC) return &((struct npc_data*)bl)->ud; - if( bl->type == BL_HOM) return &((struct homun_data*)bl)->ud; //[orn] + if( bl->type == BL_HOM) return &((struct homun_data*)bl)->ud; + if( bl->type == BL_MER) return &((struct mercenary_data*)bl)->ud; return NULL; } |