summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzephyrus <zephyrus@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-08-23 13:09:50 +0000
committerzephyrus <zephyrus@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-08-23 13:09:50 +0000
commit94281a398ef3a288a23cebb9f2d9a5227c570996 (patch)
treeb55207b5a40b9c019d150772ddbb1ffc6661f80c
parent59b08db5fcebd6e3d94f5353602fc685dbf9e3f5 (diff)
downloadhercules-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
-rw-r--r--db/packet_db.txt2
-rw-r--r--src/char_sql/int_homun.c53
-rw-r--r--src/char_sql/inter.c2
-rw-r--r--src/common/mmo.h1
-rw-r--r--src/map/clif.c144
-rw-r--r--src/map/clif.h4
-rw-r--r--src/map/intif.c40
-rw-r--r--src/map/intif.h3
-rw-r--r--src/map/mercenary.c124
-rw-r--r--src/map/mercenary.h11
-rw-r--r--src/map/status.c24
-rw-r--r--src/map/unit.c3
12 files changed, 375 insertions, 36 deletions
diff --git a/db/packet_db.txt b/db/packet_db.txt
index 5e6147de6..0910cbc79 100644
--- a/db/packet_db.txt
+++ b/db/packet_db.txt
@@ -930,7 +930,7 @@ packet_ver: 20
0x029c,66
0x029d,-1
0x029e,11
-0x029f,3
+0x029f,3,mermenu,0
0x02a0,0
0x02a1,0
0x02a2,8
diff --git a/src/char_sql/int_homun.c b/src/char_sql/int_homun.c
index 042db85aa..14a142ef9 100644
--- a/src/char_sql/int_homun.c
+++ b/src/char_sql/int_homun.c
@@ -292,18 +292,71 @@ static void mapif_parse_homunculus_rename(int fd, int account_id, int char_id, c
mapif_homunculus_renamed(fd, account_id, char_id, result, name);
}
+/*==========================================
+ * Mercenary's System
+ *------------------------------------------*/
+bool mapif_mercenary_save(struct s_mercenary* merc)
+{
+ bool flag = true;
+
+ if( merc->mercenary_id == 0 )
+ { // Create new DB entry
+ if( SQL_ERROR == Sql_Query(sql_handle,
+ "INSERT INTO `mercenary` (`char_id`,`class`,`hp`,`sp`,`kill_counter`,`life_time`) VALUES ('%d','%d','%d','%d','%u','%u')",
+ merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->remain_life_time) )
+ {
+ Sql_ShowDebug(sql_handle);
+ flag = false;
+ }
+ else
+ merc->mercenary_id = (int)Sql_LastInsertId(sql_handle);
+ }
+ else if( SQL_ERROR == Sql_Query(sql_handle,
+ "UPDATE `mercenary` SET `char_id` = '%d', `class` = '%d', `hp` = '%d', `sp` = '%d', `kill_counter` = '%u', `life_time` = '%u' WHERE `mer_id` = '%d'",
+ merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->remain_life_time, merc->mercenary_id) )
+ { // Update DB entry
+ Sql_ShowDebug(sql_handle);
+ flag = false;
+ }
+
+ return flag;
+}
+
+static void mapif_mercenary_created(int fd, struct s_mercenary *merc, unsigned char flag)
+{
+ int size = sizeof(struct s_mercenary) + 5;
+
+ WFIFOHEAD(fd,size);
+ WFIFOW(fd,0) = 0x3860;
+ WFIFOW(fd,2) = size;
+ WFIFOB(fd,4) = flag;
+ memcpy(WFIFOP(fd,5),merc,sizeof(struct s_mercenary));
+ WFIFOSET(fd,size);
+}
+
+static void mapif_parse_mercenary_create(int fd, struct s_mercenary* merc)
+{
+ bool result = mapif_mercenary_save(merc);
+ mapif_mercenary_created(fd, merc, result);
+}
+/*==========================================
+ * Inter Packets
+ *------------------------------------------*/
int inter_homunculus_parse_frommap(int fd)
{
unsigned short cmd = RFIFOW(fd,0);
switch( cmd )
{
+ // Homunculus Packets
case 0x3090: mapif_parse_homunculus_create(fd, (int)RFIFOW(fd,2), (int)RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,8)); break;
case 0x3091: mapif_parse_homunculus_load (fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6)); break;
case 0x3092: mapif_parse_homunculus_save (fd, (int)RFIFOW(fd,2), (int)RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,8)); break;
case 0x3093: mapif_parse_homunculus_delete(fd, (int)RFIFOL(fd,2)); break;
case 0x3094: mapif_parse_homunculus_rename(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6), (char*)RFIFOP(fd,10)); break;
+ // Mercenary Packets
+ case 0x3070: mapif_parse_mercenary_create(fd, (struct s_mercenary*)RFIFOP(fd,8)); break;
default:
return 0;
}
diff --git a/src/char_sql/inter.c b/src/char_sql/inter.c
index 58215d5da..f396a7a98 100644
--- a/src/char_sql/inter.c
+++ b/src/char_sql/inter.c
@@ -51,7 +51,7 @@ int inter_recv_packet_length[] = {
5, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040-
-1,-1,10,10, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus]
6,-1,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin]
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3070-
+ -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3070- Mercenary packets [Zephyrus]
48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080-
-1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator]
};
diff --git a/src/common/mmo.h b/src/common/mmo.h
index da036005c..6be0fab19 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -108,7 +108,6 @@
#define MC_SKILLBASE 8201
#define MAX_MERCSKILL 37
#define MAX_MERCENARY_CLASS 30
-#define MAX_MERCENARY_SKILL 4
enum item_types {
IT_HEALING = 0,
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;
}