summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-10-20 18:30:05 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-10-20 18:30:05 +0000
commit54a7f124543239c98d696da37c91eb5e2e99b25d (patch)
tree03c1c0d7148de31a112f2c3d82c7eabf910dd351 /src/map
parent1893d0bc7b07a362ac6efcd8de4af056544bad3a (diff)
downloadhercules-54a7f124543239c98d696da37c91eb5e2e99b25d.tar.gz
hercules-54a7f124543239c98d696da37c91eb5e2e99b25d.tar.bz2
hercules-54a7f124543239c98d696da37c91eb5e2e99b25d.tar.xz
hercules-54a7f124543239c98d696da37c91eb5e2e99b25d.zip
- Fixed Charge Atk being able to go through chasm/pits.
- Moved the homunculus DB information from the player structure to the homun structure. Modified the homunculus creation packets to hold this information during creation, also, all initial values are handled by the map-server, the char server only assigns it a homun ID. - Removed target_id/attacked_id from homun_data as it wasn't really used. - Codes cleanup (removing of commented code mostly) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9031 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c28
-rw-r--r--src/map/battle.c8
-rw-r--r--src/map/clif.c104
-rw-r--r--src/map/intif.c63
-rw-r--r--src/map/map.h4
-rw-r--r--src/map/mercenary.c369
-rw-r--r--src/map/mercenary.h8
-rw-r--r--src/map/pc.c2
-rw-r--r--src/map/script.c12
-rw-r--r--src/map/skill.c49
-rw-r--r--src/map/status.c40
-rw-r--r--src/map/unit.c22
12 files changed, 312 insertions, 397 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 82d1b4c9a..b8f1c6cab 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -9910,7 +9910,7 @@ int atcommand_homlevel(
hd = sd->hd;
for (i = 1; i <= level && hd->exp_next; i++){
- sd->homunculus.exp += hd->exp_next;
+ hd->homunculus.exp += hd->exp_next;
merc_hom_levelup(hd);
}
status_calc_homunculus(hd,0);
@@ -9980,7 +9980,7 @@ int atcommand_homfriendly(
friendly = atoi(message);
if (merc_is_hom_active(sd->hd)) {
if (friendly > 0 && friendly <= 1000) {
- sd->homunculus.intimacy = friendly * 100 ;
+ sd->hd->homunculus.intimacy = friendly * 100 ;
clif_send_homdata(sd,SP_INTIMATE,friendly);
} else {
return -1;
@@ -10007,9 +10007,10 @@ int atcommand_homhungry(
hungry = atoi(message);
if (sd->status.hom_id > 0 && sd->hd) {
+ struct homun_data *hd = sd->hd;
if (hungry >= 0 && hungry <= 100) {
- sd->homunculus.hunger = hungry;
- clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger);
+ hd->homunculus.hunger = hungry;
+ clif_send_homdata(sd,SP_HUNGRY,hd->homunculus.hunger);
} else {
return -1;
}
@@ -10030,13 +10031,13 @@ int atcommand_homtalk(
nullpo_retr(-1, sd);
- if(!sd->status.hom_id || !sd->hd || !sd->homunculus.hp)
+ if(!merc_is_hom_active(sd->hd))
return -1;
if (sscanf(message, "%99[^\n]", mes) < 1)
return -1;
- snprintf(temp, sizeof temp ,"%s : %s",sd->homunculus.name,mes);
+ snprintf(temp, sizeof temp ,"%s : %s",sd->hd->homunculus.name,mes);
clif_message(&sd->hd->bl, temp);
return 0;
@@ -10050,21 +10051,26 @@ int atcommand_hominfo(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
-
+ struct homun_data *hd;
+ struct status_data *status;
nullpo_retr(-1, sd);
if(!merc_is_hom_active(sd->hd))
return -1;
-
+ hd = sd->hd;
+ status = status_get_status_data(&hd->bl);
clif_displaymessage(fd, "Homunculus stats :");
- snprintf(atcmd_output, sizeof(atcmd_output) ,"HP : %d/%d - SP : %d/%d", sd->hd->battle_status.hp, sd->hd->battle_status.max_hp, sd->hd->battle_status.sp, sd->hd->battle_status.max_sp);
+ snprintf(atcmd_output, sizeof(atcmd_output) ,"HP : %d/%d - SP : %d/%d",
+ status->hp, status->max_hp, status->sp, status->max_sp);
clif_displaymessage(fd, atcmd_output);
- snprintf(atcmd_output, sizeof(atcmd_output) ,"ATK : %d - MATK : %d~%d", sd->hd->battle_status.rhw.atk2+sd->hd->battle_status.batk, sd->hd->battle_status.matk_min, sd->hd->battle_status.matk_max);
+ snprintf(atcmd_output, sizeof(atcmd_output) ,"ATK : %d - MATK : %d~%d",
+ status->rhw.atk2 +status->batk, status->matk_min, status->matk_max);
clif_displaymessage(fd, atcmd_output);
- snprintf(atcmd_output, sizeof(atcmd_output) ,"Hungry : %d - Intimacy : %u", sd->homunculus.hunger, sd->homunculus.intimacy/100);
+ snprintf(atcmd_output, sizeof(atcmd_output) ,"Hungry : %d - Intimacy : %u",
+ hd->homunculus.hunger, hd->homunculus.intimacy/100);
clif_displaymessage(fd, atcmd_output);
return 0;
diff --git a/src/map/battle.c b/src/map/battle.c
index da209b2a1..95a4ac49f 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -101,7 +101,7 @@ int battle_gettarget(struct block_list *bl)
case BL_PET:
return ((struct pet_data*)bl)->target_id;
case BL_HOM:
- return ((struct homun_data*)bl)->target_id;
+ return ((struct homun_data*)bl)->ud.target;
}
return 0;
}
@@ -300,6 +300,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
if(sc->data[SC_DODGE].timer != -1 && !sc->opt1 &&
(flag&BF_LONG || sc->data[SC_SPURT].timer != -1)
&& rand()%100 < 20) {
+ if (sd && pc_issit(sd)) pc_setstand(sd); //Stand it to dodge.
clif_skill_nodamage(bl,bl,TK_DODGE,1,1);
if (sc->data[SC_COMBO].timer == -1)
sc_start4(bl, SC_COMBO, 100, TK_JUMPKICK, src->id, 1, 0, 2000);
@@ -1231,8 +1232,8 @@ static struct Damage battle_calc_weapon_attack(
break;
}
case HFLI_SBR44: //[orn]
- if(src->type == BL_HOM && ((TBL_HOM*)src)->master) {
- wd.damage = ((TBL_HOM*)src)->master->homunculus.intimacy ;
+ if(src->type == BL_HOM) {
+ wd.damage = ((TBL_HOM*)src)->homunculus.intimacy ;
break;
}
default:
@@ -1508,7 +1509,6 @@ static struct Damage battle_calc_weapon_attack(
//Preserve damage ratio when max cart weight is changed.
if(sd && sd->cart_weight && sd->cart_max_weight)
skillratio += sd->cart_weight/i * 80000/sd->cart_max_weight - 100;
-// skillratio += sd->cart_weight/i - 100;
else if (!sd)
skillratio += 80000 / i - 100;
flag.cardfix = 0;
diff --git a/src/map/clif.c b/src/map/clif.c
index 516b909e4..a667b74be 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1461,13 +1461,12 @@ int clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
status = &hd->battle_status;
malloc_set(buf,0,packet_len_table[0x22e]);
WBUFW(buf,0)=0x22e;
- memcpy(WBUFP(buf,2),sd->homunculus.name,NAME_LENGTH);
-// WBUFB(buf,26)=sd->homunculus.rename_flag * 2;
+ memcpy(WBUFP(buf,2),hd->homunculus.name,NAME_LENGTH);
// Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true)
- WBUFB(buf,26)=sd->homunculus.rename_flag | (sd->homunculus.vaporize << 1) | (sd->homunculus.hp?0:4);
- WBUFW(buf,27)=sd->homunculus.level;
- WBUFW(buf,29)=sd->homunculus.hunger;
- WBUFW(buf,31)=(unsigned short) (sd->homunculus.intimacy / 100) ;
+ WBUFB(buf,26)=hd->homunculus.rename_flag | (hd->homunculus.vaporize << 1) | (hd->homunculus.hp?0:4);
+ WBUFW(buf,27)=hd->homunculus.level;
+ WBUFW(buf,29)=hd->homunculus.hunger;
+ WBUFW(buf,31)=(unsigned short) (hd->homunculus.intimacy / 100) ;
WBUFW(buf,33)=0; // equip id
WBUFW(buf,35)=cap_value(status->rhw.atk2+status->batk, 0, SHRT_MAX);
WBUFW(buf,37)=cap_value(status->matk_max, 0, SHRT_MAX);
@@ -1491,9 +1490,9 @@ int clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
WBUFW(buf,55)=status->sp;
WBUFW(buf,57)=status->max_sp;
}
- WBUFL(buf,59)=sd->homunculus.exp;
+ WBUFL(buf,59)=hd->homunculus.exp;
WBUFL(buf,63)=hd->exp_next;
- WBUFW(buf,67)=sd->homunculus.skillpts;
+ WBUFW(buf,67)=hd->homunculus.skillpts;
WBUFW(buf,69)=1; // FIXME: Attackable? When exactly is a homun not attackable? [Skotlex]
clif_send(buf,packet_len_table[0x22e],&sd->bl,SELF);
return 0;
@@ -1516,28 +1515,29 @@ void clif_send_homdata(struct map_session_data *sd, int type, int param) { //[or
}
int clif_homskillinfoblock(struct map_session_data *sd) { //[orn]
+ struct homun_data *hd;
int fd;
- int i,j,len=4,id/*, inf2*/;
+ int i,j,len=4,id;
nullpo_retr(0, sd);
- nullpo_retr(0, sd->hd);
- if ( !sd->hd )
+ hd = sd->hd;
+ if ( !hd )
return 0 ;
fd=sd->fd;
WFIFOW(fd,0)=0x235;
for ( i = 0; i < MAX_HOMUNSKILL; i++){
- if( (id = sd->homunculus.hskill[i].id) != 0 ){
+ if( (id = hd->homunculus.hskill[i].id) != 0 ){
j = id - HM_SKILLBASE - 1 ;
WFIFOW(fd,len ) = id ;
WFIFOW(fd,len+2) = skill_get_inf(id) ;
WFIFOW(fd,len+4) = 0 ;
- WFIFOW(fd,len+6) = sd->homunculus.hskill[j].lv ;
- WFIFOW(fd,len+8) = skill_get_sp(id,sd->homunculus.hskill[j].lv) ;
- WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,sd->homunculus.hskill[j].lv) ;
+ 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) ;
strncpy(WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH) ;
- WFIFOB(fd,len+36) = (sd->homunculus.hskill[j].lv < merc_skill_tree_get_max(id, sd->homunculus.class_))?1:0;
+ WFIFOB(fd,len+36) = (hd->homunculus.hskill[j].lv < merc_skill_tree_get_max(id, hd->homunculus.class_))?1:0;
len+=37;
}
}
@@ -1548,47 +1548,49 @@ int clif_homskillinfoblock(struct map_session_data *sd) { //[orn]
}
void clif_homskillup(struct map_session_data *sd, int skill_num) { //[orn]
- int range,fd,skillid;
+ struct homun_data *hd;
+ int fd,skillid;
nullpo_retv(sd);
skillid = skill_num - HM_SKILLBASE - 1;
fd=sd->fd;
+ hd=sd->hd;
+
WFIFOW(fd,0) = 0x239;
WFIFOW(fd,2) = skill_num;
- WFIFOW(fd,4) = sd->homunculus.hskill[skillid].lv;
- WFIFOW(fd,6) = skill_get_sp(skill_num,sd->homunculus.hskill[skillid].lv);
- range = skill_get_range(skill_num,sd->homunculus.hskill[skillid].lv);
- if(range < 0)
- range = status_get_range(&sd->bl) - (range + 1);
- WFIFOW(fd,8) = range;
- WFIFOB(fd,10) = (sd->homunculus.hskill[skillid].lv < skill_get_max(sd->homunculus.hskill[skillid].id)) ? 1 : 0;
+ WFIFOW(fd,4) = hd->homunculus.hskill[skillid].lv;
+ WFIFOW(fd,6) = skill_get_sp(skill_num,hd->homunculus.hskill[skillid].lv);
+ WFIFOW(fd,8) = skill_get_range2(&hd->bl, skill_num,hd->homunculus.hskill[skillid].lv);
+ WFIFOB(fd,10) = (hd->homunculus.hskill[skillid].lv < skill_get_max(hd->homunculus.hskill[skillid].id)) ? 1 : 0;
WFIFOSET(fd,packet_len_table[0x239]);
return;
}
void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd) { //[orn]
-
+ struct homun_data *hd;
nullpo_retv(sd);
- if(sd->hd == NULL)
+ if((hd=sd->hd) == NULL)
return;
RFIFOHEAD(fd);
- memcpy(sd->homunculus.name,RFIFOP(fd,2),24);
- sd->homunculus.rename_flag = 1;
- clif_hominfo(sd,sd->hd,0);
- clif_charnameack(sd->fd,&sd->hd->bl);
+ memcpy(hd->homunculus.name,RFIFOP(fd,2),24);
+ hd->homunculus.rename_flag = 1;
+ clif_hominfo(sd,hd,0);
+ clif_charnameack(sd->fd,&hd->bl);
}
void clif_parse_HomMoveToMaster(int fd, struct map_session_data *sd) { //[orn]
nullpo_retv(sd);
- if(sd->hd == NULL || status_isdead(&sd->hd->bl) || sd->homunculus.vaporize)
+ if(!merc_is_hom_active(sd->hd))
return;
+ if (!unit_can_move(&sd->hd->bl))
+ return;
unit_walktoxy(&sd->hd->bl, sd->bl.x,sd->bl.y-1, 0);
}
@@ -1597,7 +1599,7 @@ void clif_parse_HomMoveTo(int fd,struct map_session_data *sd) { //[orn]
nullpo_retv(sd);
- if(sd->hd == NULL || status_isdead(&sd->hd->bl) || sd->homunculus.vaporize)
+ if(!merc_is_hom_active(sd->hd))
return;
cmd = RFIFOW(fd,0);
@@ -1606,6 +1608,9 @@ void clif_parse_HomMoveTo(int fd,struct map_session_data *sd) { //[orn]
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 (!unit_can_move(&sd->hd->bl))
+ return;
+
unit_walktoxy(&(sd->hd->bl),x,y,0);
}
@@ -1614,7 +1619,7 @@ void clif_parse_HomAttack(int fd,struct map_session_data *sd) { //[orn]
nullpo_retv(sd);
- if(sd->hd == NULL || status_isdead(&sd->hd->bl) || sd->homunculus.vaporize || sd->hd->bl.id != RFIFOL(fd,2))
+ if(!merc_is_hom_active(sd->hd))
return;
if ((target = map_id2bl(RFIFOL(fd,6))) == NULL || status_isdead(target))
@@ -1622,10 +1627,7 @@ void clif_parse_HomAttack(int fd,struct map_session_data *sd) { //[orn]
merc_stop_walking(sd->hd, 1);
merc_stop_attack(sd->hd);
- if ( sd->hd && target ) {
- sd->hd->target_id = RFIFOL(fd,6) ;
- unit_attack(&sd->hd->bl,RFIFOL(fd,6),1) ;
- }
+ unit_attack(&sd->hd->bl,RFIFOL(fd,6),1) ;
}
void clif_parse_HomMenu(int fd, struct map_session_data *sd) { //[orn]
@@ -1634,7 +1636,7 @@ void clif_parse_HomMenu(int fd, struct map_session_data *sd) { //[orn]
RFIFOHEAD(fd);
cmd = RFIFOW(fd,0);
- if(sd->hd == NULL || status_isdead(&sd->hd->bl) || sd->homunculus.vaporize)
+ if(!merc_is_hom_active(sd->hd))
return;
merc_menu(sd,RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]));
@@ -7831,13 +7833,13 @@ int clif_charnameack (int fd, struct block_list *bl)
break;
//[blackhole89]
case BL_HOM:
- memcpy(WBUFP(buf,6), ((struct homun_data*)bl)->master->homunculus.name, NAME_LENGTH);
+ memcpy(WBUFP(buf,6), ((TBL_HOM*)bl)->homunculus.name, NAME_LENGTH);
break;
case BL_PET:
- memcpy(WBUFP(buf,6), ((struct pet_data*)bl)->pet.name, NAME_LENGTH);
+ memcpy(WBUFP(buf,6), ((TBL_PET*)bl)->pet.name, NAME_LENGTH);
break;
case BL_NPC:
- memcpy(WBUFP(buf,6), ((struct npc_data*)bl)->name, NAME_LENGTH);
+ memcpy(WBUFP(buf,6), ((TBL_NPC*)bl)->name, NAME_LENGTH);
break;
case BL_MOB:
{
@@ -9689,7 +9691,7 @@ static void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_sess
} else if (DIFF_TICK(tick, hd->ud.canact_tick) < 0)
return;
- lv = merc_hom_checkskill(sd, skillnum);
+ lv = merc_hom_checkskill(hd, skillnum);
if (skilllv > lv)
skilllv = lv;
@@ -10155,26 +10157,14 @@ void clif_parse_ResetChar(int fd, struct map_session_data *sd) {
*/
void clif_parse_LGMmessage(int fd, struct map_session_data *sd) {
unsigned char buf[512];
-// int len = RFIFOREST(fd);
- int plen = RFIFOW(fd,2);
RFIFOHEAD(fd);
- //This shouldn't be needed.... because the parsing code makes sure
- //this function is not invoked until enough bytes have been received.
- //So if the client "hacks" the packet, all that will happen is that
- //it will not be parsed until enough data is received, on which point
- //the following packets will be offset, causing them to fail to parse,
- //which leads to disconnecting them :3 [Skotlex]
-// if(plen <= 0 || plen > len) // Possible hack! [Lance]
-// plen = len;
-
if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
(pc_isGM(sd) >= get_atcommand_level(AtCommand_LocalBroadcast))) {
WBUFW(buf,0) = 0x9a;
- WBUFW(buf,2) = plen;
- memcpy(WBUFP(buf,4), RFIFOP(fd,4), plen - 4);
- WBUFB(buf,plen-1) = '\0'; // Must have NULL termination [Lance]
- clif_send(buf, plen, &sd->bl, ALL_SAMEMAP);
+ WBUFW(buf,2) = RFIFOW(fd,2);
+ memcpy(WBUFP(buf,4), RFIFOP(fd,4), RFIFOW(fd,2) - 4);
+ clif_send(buf, RFIFOW(fd,2), &sd->bl, ALL_SAMEMAP);
}
}
diff --git a/src/map/intif.c b/src/map/intif.c
index 6dc5f15cd..bab76b40b 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -36,7 +36,7 @@ static const int packet_len_table[]={
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,
11,-1, 7, 3, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880
- 16,-1, 7, 3, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator]
+ -1,-1, 7, 3, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator]
};
extern int char_fd; // inter serverのfdはchar_fdを使う
@@ -786,22 +786,12 @@ int intif_homunculus_create(int account_id, struct s_homunculus *sh)
{
if (CheckForCharServer())
return 0;
- WFIFOHEAD(inter_fd, 44+NAME_LENGHT);
- WFIFOW(inter_fd, 0) = 0x3090;
- WFIFOL(inter_fd, 2) = account_id;
- WFIFOL(inter_fd, 6) = sh->char_id;
- WFIFOW(inter_fd, 10) = sh->class_;
- WFIFOL(inter_fd,12) = sh->max_hp;
- WFIFOL(inter_fd,16) = sh->max_sp;
- memcpy(WFIFOP(inter_fd,20), sh->name, NAME_LENGTH);
- WFIFOL(inter_fd,44) = sh->str;
- WFIFOL(inter_fd,48) = sh->agi;
- WFIFOL(inter_fd,52) = sh->vit;
- WFIFOL(inter_fd,56) = sh->int_;
- WFIFOL(inter_fd,60) = sh->dex;
- WFIFOL(inter_fd,64) = sh->luk;
- WFIFOSET(inter_fd, 44+NAME_LENGTH);
-
+ WFIFOHEAD(inter_fd, sizeof(struct s_homunculus)+8);
+ WFIFOW(inter_fd,0) = 0x3090;
+ WFIFOW(inter_fd,2) = sizeof(struct s_homunculus)+8;
+ WFIFOL(inter_fd,4) = account_id;
+ memcpy(WFIFOP(inter_fd,8),sh,sizeof(struct s_homunculus));
+ WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
return 0;
}
@@ -814,7 +804,7 @@ int intif_homunculus_requestload(int account_id, int homun_id)
WFIFOL(inter_fd,2) = account_id;
WFIFOL(inter_fd,6) = homun_id;
WFIFOSET(inter_fd, 10);
- return 0;
+ return 1;
}
int intif_homunculus_requestsave(int account_id, struct s_homunculus* sh)
@@ -1446,47 +1436,32 @@ int intif_parse_RenamePetOk(int fd)
int intif_parse_CreateHomunculus(int fd)
{
- struct map_session_data *sd = NULL;
+ int len;
RFIFOHEAD(fd);
-
- if((sd=map_id2sd(RFIFOL(fd,2)))==NULL ||
- sd->status.char_id != RFIFOL(fd,6))
+ len=RFIFOW(fd,2)-9;
+ if(sizeof(struct s_homunculus)!=len) {
+ if(battle_config.etc_log)
+ ShowError("intif: create homun data: data size error %d != %d\n",sizeof(struct s_homunculus),len);
return 0;
-
- if(RFIFOW(fd,10)==1)
- {
- ShowInfo("Homunculus created successfully\n");
- sd->status.hom_id = sd->homunculus.hom_id = RFIFOL(fd,12);
- merc_hom_recv_data(RFIFOL(fd,2), &sd->homunculus, 1) ;
- }
- else
- {
- ShowError("intif_parse_CreateHomunculus: failed to create homunculus\n");
- clif_displaymessage(sd->fd, "[debug] fail to create homunculus"); // display error message..
}
-
+ merc_hom_recv_data(RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,9), RFIFOB(fd,8)) ;
return 0;
}
int intif_parse_RecvHomunculusData(int fd)
{
- struct s_homunculus sh;
int len;
RFIFOHEAD(fd);
- len=RFIFOW(fd,2);
+ len=RFIFOW(fd,2)-9;
- if(sizeof(struct s_homunculus)!=len-9) {
+ if(sizeof(struct s_homunculus)!=len) {
if(battle_config.etc_log)
- ShowError("intif: homun data: data size error %d %d\n",sizeof(struct s_homunculus),len-9);
- }
- else{
- memcpy(&sh,RFIFOP(fd,9),sizeof(struct s_homunculus));
- merc_hom_recv_data(RFIFOL(fd,4),&sh,RFIFOB(fd,8));
+ ShowError("intif: homun data: data size error %d %d\n",sizeof(struct s_homunculus),len);
+ return 0;
}
-
+ merc_hom_recv_data(RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,9), RFIFOB(fd,8));
return 0;
-
}
int intif_parse_SaveHomunculusOk(int fd)
diff --git a/src/map/map.h b/src/map/map.h
index 1c500a1cf..6f0816c78 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -800,8 +800,6 @@ struct map_session_data {
struct vending vending[MAX_VENDING];
struct pet_data *pd;
-
- struct s_homunculus homunculus ; //[orn]
struct homun_data *hd; // [blackhole89]
struct{
@@ -990,10 +988,10 @@ struct homun_data {
struct status_change sc;
struct regen_data regen;
struct homunculus_db *homunculusDB; //[orn]
+ struct s_homunculus homunculus ; //[orn]
struct map_session_data *master; //pointer back to its master
int hungry_timer; //[orn]
- int target_id,attacked_id;
unsigned int exp_next;
char blockskill[MAX_SKILL]; // [orn]
};
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index 24ced263b..f027d9234 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -51,18 +51,20 @@ void merc_damage(struct homun_data *hd,struct block_list *src,int hp,int sp)
int merc_hom_dead(struct homun_data *hd, struct block_list *src)
{
+ //There's no intimacy penalties on death (from Tharis)
struct map_session_data *sd = hd->master;
clif_emotion(&hd->bl, 16) ; //wah
- if (!sd) //unit remove map will invoke unit free
- return 3;
- //There's no intimacy penalties on death (from Tharis)
//Delete timers when dead.
merc_hom_hungry_timer_delete(hd);
- sd->homunculus.hp = 0 ;
+ hd->homunculus.hp = 0;
+
+ if (!sd) //unit remove map will invoke unit free
+ return 3;
+
clif_hominfo(sd,hd,0); // Send dead flag
- clif_emotion(&sd->bl, 28) ; //sob
+ clif_emotion(&sd->bl, 28) ; //sob
//Remove from map (if it has no intimacy, it is auto-removed from memory)
return 3;
}
@@ -75,7 +77,7 @@ int merc_hom_vaporize(struct map_session_data *sd, int flag)
nullpo_retr(0, sd);
hd = sd->hd;
- if (!hd || sd->homunculus.vaporize)
+ if (!hd || hd->homunculus.vaporize)
return 0;
if (status_isdead(&hd->bl))
@@ -87,7 +89,7 @@ int merc_hom_vaporize(struct map_session_data *sd, int flag)
hd->regen.state.block = 3; //Block regen while vaporized.
//Delete timers when vaporized.
merc_hom_hungry_timer_delete(hd);
- sd->homunculus.vaporize = 1;
+ hd->homunculus.vaporize = 1;
clif_hominfo(sd, sd->hd, 0);
merc_save(hd);
return unit_remove_map(&hd->bl, 0);
@@ -108,53 +110,52 @@ int merc_hom_delete(struct homun_data *hd, int emote)
clif_emotion(&sd->bl, emote);
//This makes it be deleted right away.
- sd->homunculus.intimacy = 0;
+ hd->homunculus.intimacy = 0;
// Send homunculus_dead to client
- sd->homunculus.hp = 0;
+ hd->homunculus.hp = 0;
clif_hominfo(sd, hd, 0);
return unit_remove_map(&hd->bl,0);
}
-int merc_hom_calc_skilltree(struct map_session_data *sd)
+int merc_hom_calc_skilltree(struct homun_data *hd)
{
int i,id=0 ;
int j,f=1;
int c=0;
- nullpo_retr(0, sd);
- c = sd->homunculus.class_ - HM_CLASS_BASE;
+ nullpo_retr(0, hd);
+ c = hd->homunculus.class_ - HM_CLASS_BASE;
for(i=0;i < MAX_SKILL_TREE && (id = hskill_tree[c][i].id) > 0;i++)
{
- if(sd->homunculus.hskill[id-HM_SKILLBASE-1].id)
+ if(hd->homunculus.hskill[id-HM_SKILLBASE-1].id)
continue; //Skill already known.
if(!battle_config.skillfree)
{
for(j=0;j<5;j++)
{
if( hskill_tree[c][i].need[j].id &&
- merc_hom_checkskill(sd,hskill_tree[c][i].need[j].id) < hskill_tree[c][i].need[j].lv)
+ merc_hom_checkskill(hd,hskill_tree[c][i].need[j].id) < hskill_tree[c][i].need[j].lv)
{
f=0;
break;
}
}
}
- if (f){
- sd->homunculus.hskill[id-HM_SKILLBASE-1].id = id ;
- }
+ if (f)
+ hd->homunculus.hskill[id-HM_SKILLBASE-1].id = id ;
}
return 0;
}
-int merc_hom_checkskill(struct map_session_data *sd,int skill_id)
+int merc_hom_checkskill(struct homun_data *hd,int skill_id)
{
int i = skill_id - HM_SKILLBASE - 1;
- if(!sd)
+ if(!hd)
return 0;
- if(sd->homunculus.hskill[i].id == skill_id)
- return (sd->homunculus.hskill[i].lv);
+ if(hd->homunculus.hskill[i].id == skill_id)
+ return (hd->homunculus.hskill[i].lv);
return 0;
}
@@ -173,17 +174,17 @@ void merc_hom_skillup(struct homun_data *hd,int skillnum)
int i = 0 ;
nullpo_retv(hd);
- if(!hd->master->homunculus.vaporize)
+ if(!hd->homunculus.vaporize)
{
i = skillnum - HM_SKILLBASE - 1 ;
- if( hd->master->homunculus.skillpts > 0 &&
- hd->master->homunculus.hskill[i].id &&
- hd->master->homunculus.hskill[i].flag == 0 && //Don't allow raising while you have granted skills. [Skotlex]
- hd->master->homunculus.hskill[i].lv < merc_skill_tree_get_max(skillnum, hd->master->homunculus.class_)
+ if( hd->homunculus.skillpts > 0 &&
+ hd->homunculus.hskill[i].id &&
+ hd->homunculus.hskill[i].flag == 0 && //Don't allow raising while you have granted skills. [Skotlex]
+ hd->homunculus.hskill[i].lv < merc_skill_tree_get_max(skillnum, hd->homunculus.class_)
)
{
- hd->master->homunculus.hskill[i].lv++ ;
- hd->master->homunculus.skillpts-- ;
+ hd->homunculus.hskill[i].lv++ ;
+ hd->homunculus.skillpts-- ;
status_calc_homunculus(hd,0) ;
clif_homskillup(hd->master, skillnum) ;
clif_hominfo(hd->master,hd,0) ;
@@ -198,15 +199,15 @@ int merc_hom_levelup(struct homun_data *hd)
int growth_max_hp, growth_max_sp ;
char output[256] ;
- if (hd->master->homunculus.level == MAX_LEVEL || !hd->exp_next || hd->master->homunculus.exp < hd->exp_next)
+ if (hd->homunculus.level == MAX_LEVEL || !hd->exp_next || hd->homunculus.exp < hd->exp_next)
return 0 ;
- hd->master->homunculus.level++ ;
- if (!(hd->master->homunculus.level % 3))
- hd->master->homunculus.skillpts++ ; //1 skillpoint each 3 base level
+ hd->homunculus.level++ ;
+ if (!(hd->homunculus.level % 3))
+ hd->homunculus.skillpts++ ; //1 skillpoint each 3 base level
- hd->master->homunculus.exp -= hd->exp_next ;
- hd->exp_next = hexptbl[hd->master->homunculus.level - 1] ;
+ hd->homunculus.exp -= hd->exp_next ;
+ hd->exp_next = hexptbl[hd->homunculus.level - 1] ;
if ( hd->homunculusDB->gmaxHP <= hd->homunculusDB->gminHP )
growth_max_hp = hd->homunculusDB->gminHP ;
@@ -241,14 +242,14 @@ int merc_hom_levelup(struct homun_data *hd)
else
growth_luk = rand(hd->homunculusDB->gminLUK, hd->homunculusDB->gmaxLUK) ;
- hd->master->homunculus.max_hp += growth_max_hp;
- hd->master->homunculus.max_sp += growth_max_sp;
- hd->master->homunculus.str += growth_str ;
- hd->master->homunculus.agi += growth_agi ;
- hd->master->homunculus.vit += growth_vit ;
- hd->master->homunculus.dex += growth_dex ;
- hd->master->homunculus.int_ += growth_int ;
- hd->master->homunculus.luk += growth_luk ;
+ hd->homunculus.max_hp += growth_max_hp;
+ hd->homunculus.max_sp += growth_max_sp;
+ hd->homunculus.str += growth_str ;
+ hd->homunculus.agi += growth_agi ;
+ hd->homunculus.vit += growth_vit ;
+ hd->homunculus.dex += growth_dex ;
+ hd->homunculus.int_ += growth_int ;
+ hd->homunculus.luk += growth_luk ;
if ( battle_config.homunculus_show_growth ) {
sprintf(output,
@@ -262,13 +263,12 @@ int merc_hom_change_class(struct homun_data *hd, short class_)
{
int i;
i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS);
- if(i < 0) {
+ if(i < 0)
return 0;
- }
hd->homunculusDB = &homunculus_db[i];
- hd->master->homunculus.class_ = class_;
+ hd->homunculus.class_ = class_;
status_set_viewdata(&hd->bl, class_);
- merc_hom_calc_skilltree(hd->master);
+ merc_hom_calc_skilltree(hd);
return 1;
}
@@ -289,11 +289,11 @@ int merc_hom_evolution(struct homun_data *hd)
merc_hom_vaporize(sd, 0);
if (!merc_hom_change_class(hd, hd->homunculusDB->evo_class)) {
- ShowError("merc_hom_evolution: Can't evoluate homunc from %d to %d", hd->master->homunculus.class_, hd->homunculusDB->evo_class);
+ ShowError("merc_hom_evolution: Can't evoluate homunc from %d to %d", hd->homunculus.class_, hd->homunculusDB->evo_class);
return 0;
}
- sd->homunculus.intimacy = 500;
- merc_call_homunculus(sd, hd->bl.x, hd->bl.y);
+ hd->homunculus.intimacy = 500;
+ merc_call_homunculus(sd);
clif_emotion(&sd->bl, 21); //no1
clif_misceffect2(&hd->bl,568);
return 1 ;
@@ -301,17 +301,17 @@ int merc_hom_evolution(struct homun_data *hd)
int merc_hom_gainexp(struct homun_data *hd,int exp)
{
- if(hd->master->homunculus.vaporize)
+ if(hd->homunculus.vaporize)
return 1;
if( hd->exp_next == 0 ) {
- hd->master->homunculus.exp = 0 ;
+ hd->homunculus.exp = 0 ;
return 0;
}
- hd->master->homunculus.exp += exp;
+ hd->homunculus.exp += exp;
- if(hd->master->homunculus.exp < hd->exp_next) {
+ if(hd->homunculus.exp < hd->exp_next) {
clif_hominfo(hd->master,hd,0);
return 0;
}
@@ -321,10 +321,10 @@ int merc_hom_gainexp(struct homun_data *hd,int exp)
{
merc_hom_levelup(hd) ;
}
- while(hd->master->homunculus.exp > hd->exp_next && hd->exp_next != 0 );
+ while(hd->homunculus.exp > hd->exp_next && hd->exp_next != 0 );
if( hd->exp_next == 0 )
- hd->master->homunculus.exp = 0 ;
+ hd->homunculus.exp = 0 ;
clif_misceffect2(&hd->bl,568);
status_calc_homunculus(hd,0);
@@ -338,22 +338,22 @@ int merc_hom_increase_intimacy(struct homun_data * hd, unsigned int value)
if (battle_config.homunculus_friendly_rate != 100)
value = (value * battle_config.homunculus_friendly_rate) / 100;
- if (hd->master->homunculus.intimacy + value <= 100000)
- hd->master->homunculus.intimacy += value;
+ if (hd->homunculus.intimacy + value <= 100000)
+ hd->homunculus.intimacy += value;
else
- hd->master->homunculus.intimacy = 100000;
- return hd->master->homunculus.intimacy;
+ hd->homunculus.intimacy = 100000;
+ return hd->homunculus.intimacy;
}
// Return 0 if decrease fails or intimacy became 0 else the new value
int merc_hom_decrease_intimacy(struct homun_data * hd, unsigned int value)
{
- if (hd->master->homunculus.intimacy >= value)
- hd->master->homunculus.intimacy -= value;
+ if (hd->homunculus.intimacy >= value)
+ hd->homunculus.intimacy -= value;
else
- hd->master->homunculus.intimacy = 0;
+ hd->homunculus.intimacy = 0;
- return hd->master->homunculus.intimacy;
+ return hd->homunculus.intimacy;
}
void merc_hom_heal(struct homun_data *hd,int hp,int sp)
@@ -368,68 +368,11 @@ void merc_save(struct homun_data *hd)
//Do not check for max_hp/max_sp caps as current could be higher to max due
//to status changes/skills (they will be capped as needed upon stat
//calculation on login)
- sd->homunculus.hp = hd->battle_status.hp;
- sd->homunculus.sp = hd->battle_status.sp;
- intif_homunculus_requestsave(sd->status.account_id, &sd->homunculus) ;
+ hd->homunculus.hp = hd->battle_status.hp;
+ hd->homunculus.sp = hd->battle_status.sp;
+ intif_homunculus_requestsave(sd->status.account_id, &hd->homunculus) ;
}
-#if 0
-// Not currently used [Toms]
-static int merc_calc_pos(struct homun_data *hd,int tx,int ty,int dir) //[orn]
-{
- int x,y,dx,dy;
- int i,k;
-
- nullpo_retr(0, hd);
-
- hd->ud.to_x = tx;
- hd->ud.to_y = ty;
-
- if(dir < 0 || dir >= 8)
- return 1;
-
- dx = -dirx[dir]*2;
- dy = -diry[dir]*2;
- x = tx + dx;
- y = ty + dy;
- if(!unit_can_reach_pos(&hd->bl,x,y,0)) {
- if(dx > 0) x--;
- else if(dx < 0) x++;
- if(dy > 0) y--;
- else if(dy < 0) y++;
- if(!unit_can_reach_pos(&hd->bl,x,y,0)) {
- for(i=0;i<12;i++) {
- k = rand(1, 8);
-// k = rand()%8;
- dx = -dirx[k]*2;
- dy = -diry[k]*2;
- x = tx + dx;
- y = ty + dy;
- if(unit_can_reach_pos(&hd->bl,x,y,0))
- break;
- else {
- if(dx > 0) x--;
- else if(dx < 0) x++;
- if(dy > 0) y--;
- else if(dy < 0) y++;
- if(unit_can_reach_pos(&hd->bl,x,y,0))
- break;
- }
- }
- if(i>=12) {
- x = tx;
- y = ty;
- if(!unit_can_reach_pos(&hd->bl,x,y,0))
- return 1;
- }
- }
- }
- hd->ud.to_x = x;
- hd->ud.to_y = y;
- return 0;
-}
-#endif
-
int merc_menu(struct map_session_data *sd,int menunum)
{
nullpo_retr(0, sd);
@@ -456,7 +399,7 @@ int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
{
int i, foodID, emotion;
- if(sd->homunculus.vaporize)
+ if(hd->homunculus.vaporize)
return 1 ;
foodID = hd->homunculusDB->foodID;
@@ -467,16 +410,16 @@ int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
}
pc_delitem(sd,i,1,0);
- if ( sd->homunculus.hunger >= 91 ) {
+ if ( hd->homunculus.hunger >= 91 ) {
merc_hom_decrease_intimacy(hd, 50);
emotion = 16;
- } else if ( sd->homunculus.hunger >= 76 ) {
+ } else if ( hd->homunculus.hunger >= 76 ) {
merc_hom_decrease_intimacy(hd, 5);
emotion = 19;
- } else if ( sd->homunculus.hunger >= 26 ) {
+ } else if ( hd->homunculus.hunger >= 26 ) {
merc_hom_increase_intimacy(hd, 75);
emotion = 2;
- } else if ( sd->homunculus.hunger >= 11 ) {
+ } else if ( hd->homunculus.hunger >= 11 ) {
merc_hom_increase_intimacy(hd, 100);
emotion = 2;
} else {
@@ -484,17 +427,17 @@ int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
emotion = 2;
}
- sd->homunculus.hunger += 10; //dunno increase value for each food
- if(sd->homunculus.hunger > 100)
- sd->homunculus.hunger = 100;
+ hd->homunculus.hunger += 10; //dunno increase value for each food
+ if(hd->homunculus.hunger > 100)
+ hd->homunculus.hunger = 100;
clif_emotion(&hd->bl,emotion) ;
- clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger);
- clif_send_homdata(sd,SP_INTIMATE,sd->homunculus.intimacy / 100);
+ clif_send_homdata(sd,SP_HUNGRY,hd->homunculus.hunger);
+ clif_send_homdata(sd,SP_INTIMATE,hd->homunculus.intimacy / 100);
clif_hom_food(sd,foodID,1);
// Too much food :/
- if(sd->homunculus.intimacy == 0)
+ if(hd->homunculus.intimacy == 0)
return merc_hom_delete(sd->hd, 23); //omg
return 0;
@@ -520,24 +463,24 @@ static int merc_hom_hungry(int tid,unsigned int tick,int id,int data)
hd->hungry_timer = -1;
- sd->homunculus.hunger-- ;
- if(sd->homunculus.hunger <= 10) {
+ hd->homunculus.hunger-- ;
+ if(hd->homunculus.hunger <= 10) {
clif_emotion(&hd->bl, 6) ; //an
- } else if(sd->homunculus.hunger == 25) {
+ } else if(hd->homunculus.hunger == 25) {
clif_emotion(&hd->bl, 20) ; //hmm
- } else if(sd->homunculus.hunger == 75) {
+ } else if(hd->homunculus.hunger == 75) {
clif_emotion(&hd->bl, 33) ; //ok
}
- if(sd->homunculus.hunger < 0) {
- sd->homunculus.hunger = 0;
+ if(hd->homunculus.hunger < 0) {
+ hd->homunculus.hunger = 0;
// Delete the homunculus if intimacy <= 100
if ( !merc_hom_decrease_intimacy(hd, 100) )
return merc_hom_delete(sd->hd, 23); //omg
- clif_send_homdata(sd,SP_INTIMATE,sd->homunculus.intimacy / 100);
+ clif_send_homdata(sd,SP_INTIMATE,hd->homunculus.intimacy / 100);
}
- clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger);
+ clif_send_homdata(sd,SP_HUNGRY,hd->homunculus.hunger);
hd->hungry_timer = add_timer(tick+hd->homunculusDB->hungryDelay,merc_hom_hungry,sd->bl.id,0); //simple Fix albator
return 0;
}
@@ -576,7 +519,7 @@ int search_homunculusDB_index(int key,int type)
}
// Create homunc structure
-int merc_hom_alloc(struct map_session_data *sd)
+int merc_hom_alloc(struct map_session_data *sd, struct s_homunculus *hom)
{
struct homun_data *hd;
int i = 0;
@@ -586,19 +529,20 @@ int merc_hom_alloc(struct map_session_data *sd)
Assert((sd->status.hom_id == 0 || sd->hd == 0) || sd->hd->master == sd);
- i = search_homunculusDB_index(sd->homunculus.class_,HOMUNCULUS_CLASS);
+ i = search_homunculusDB_index(hom->class_,HOMUNCULUS_CLASS);
if(i < 0) {
+ ShowError("merc_hom_alloc: unknown homunculus class [%d]", hom->class_);
sd->status.hom_id = 0;
- ShowError("merc_hom_alloc: unknown homunculus class [%d]", sd->homunculus.class_);
+ intif_homunculus_requestdelete(hom->hom_id);
return 1;
}
- sd->hd = hd = (struct homun_data *)aCalloc(1,sizeof(struct homun_data));
+ sd->hd = hd = aCalloc(1,sizeof(struct homun_data));
hd->homunculusDB = &homunculus_db[i];
+ memcpy(&hd->homunculus, hom, sizeof(struct s_homunculus));
hd->master = sd;
- hd->bl.m = sd->bl.m;
-
// Find a random valid pos around the player
+ hd->bl.m = sd->bl.m;
hd->bl.x = sd->bl.x;
hd->bl.y = sd->bl.y;
x = sd->bl.x + 1;
@@ -612,9 +556,9 @@ int merc_hom_alloc(struct map_session_data *sd)
hd->bl.id = npc_get_new_npc_id();
hd->bl.prev = NULL;
hd->bl.next = NULL;
- hd->exp_next = hexptbl[sd->homunculus.level - 1];
+ hd->exp_next = hexptbl[hd->homunculus.level - 1];
- status_set_viewdata(&hd->bl, sd->homunculus.class_);
+ status_set_viewdata(&hd->bl, hd->homunculus.class_);
status_change_init(&hd->bl);
unit_dataset(&hd->bl);
hd->ud.dir = sd->ud.dir;
@@ -635,28 +579,28 @@ void merc_hom_init_timers(struct homun_data * hd)
hd->regen.state.block = 0; //Restore HP/SP block.
}
-int merc_call_homunculus(struct map_session_data *sd, short x, short y)
+int merc_call_homunculus(struct map_session_data *sd)
{
struct homun_data *hd;
if (!sd->status.hom_id) //Create a new homun.
return merc_create_homunculus_request(sd, HM_CLASS_BASE + rand(0, 7)) ;
- if (!sd->homunculus.vaporize)
- return 0; //Can't use this if homun wasn't vaporized.
-
// If homunc not yet loaded, load it
if (!sd->hd)
- merc_hom_alloc(sd);
- else
- merc_hom_init_timers(sd->hd);
+ return intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
hd = sd->hd;
- sd->homunculus.vaporize = 0;
+
+ if (!hd->homunculus.vaporize)
+ return 0; //Can't use this if homun wasn't vaporized.
+
+ merc_hom_init_timers(hd);
+ hd->homunculus.vaporize = 0;
if (hd->bl.prev == NULL)
{ //Spawn him
- hd->bl.x = x;
- hd->bl.y = y;
+ hd->bl.x = sd->bl.x;
+ hd->bl.y = sd->bl.y;
hd->bl.m = sd->bl.m;
map_addblock(&hd->bl);
clif_spawn(&hd->bl);
@@ -667,36 +611,48 @@ int merc_call_homunculus(struct map_session_data *sd, short x, short y)
merc_save(hd);
} else
//Warp him to master.
- unit_warp(&hd->bl,sd->bl.m, x, y,0);
+ unit_warp(&hd->bl,sd->bl.m, sd->bl.x, sd->bl.y,0);
return 1;
}
// Recv homunculus data from char server
int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag)
{
- struct map_session_data *sd ;
+ struct map_session_data *sd;
+ struct homun_data *hd;
sd = map_id2sd(account_id);
if(!sd)
return 0;
-
+ if (sd->char_id != sh->char_id)
+ {
+ if (sd->status.hom_id == sh->hom_id)
+ sh->char_id = sd->char_id; //Correct char id.
+ else
+ return 0;
+ }
if(!flag) { // Failed to load
sd->status.hom_id = 0;
return 0;
}
- memcpy(&sd->homunculus, sh, sizeof(struct s_homunculus));
- if(sd->homunculus.hp && !sd->homunculus.vaporize)
+ if (!sd->status.hom_id) //Hom just created.
+ sd->status.hom_id = sh->hom_id;
+ if (sd->hd) //uh? Overwrite the data.
+ memcpy(&sd->hd->homunculus, sh, sizeof(struct s_homunculus));
+ else
+ merc_hom_alloc(sd, sh);
+
+ hd = sd->hd;
+ if(hd->homunculus.hp && !hd->homunculus.vaporize)
{
- merc_hom_alloc(sd);
-
- if ( sd->hd && sd->bl.prev != NULL) {
- map_addblock(&sd->hd->bl);
- clif_spawn(&sd->hd->bl);
- clif_hominfo(sd,sd->hd,1);
- clif_hominfo(sd,sd->hd,0); // send this x2. dunno why, but kRO does that [blackhole89]
+ if (hd->bl.prev != NULL) {
+ map_addblock(&hd->bl);
+ clif_spawn(&hd->bl);
+ clif_hominfo(sd,hd,1);
+ clif_hominfo(sd,hd,0); // send this x2. dunno why, but kRO does that [blackhole89]
clif_homskillinfoblock(sd);
- clif_hominfo(sd,sd->hd,0);
+ clif_hominfo(sd,hd,0);
clif_send_homdata(sd,SP_ACK,0);
}
}
@@ -706,42 +662,40 @@ int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag)
// Ask homunculus creation to char server
int merc_create_homunculus_request(struct map_session_data *sd, int class_)
{
+ struct s_homunculus homun;
int i;
nullpo_retr(1, sd);
i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS);
- if(i < 0) {
- sd->status.hom_id = 0;
- return 0;
- }
- strncpy(sd->homunculus.name, homunculus_db[i].name, NAME_LENGTH-1);
-
- sd->homunculus.class_ = class_;
- sd->homunculus.level=1;
- sd->homunculus.intimacy = 500;
- sd->homunculus.hunger = 50;
- sd->homunculus.exp = 0;
- sd->homunculus.rename_flag = 0;
- sd->homunculus.skillpts = 0;
- sd->homunculus.char_id = sd->status.char_id;
- sd->homunculus.vaporize = 0;
+ if(i < 0) return 0;
- sd->homunculus.hp = sd->homunculus.max_hp = homunculus_db[i].basemaxHP ;
- sd->homunculus.sp = sd->homunculus.max_sp = homunculus_db[i].basemaxSP ;
- sd->homunculus.str = homunculus_db[i].baseSTR * 10;
- sd->homunculus.agi = homunculus_db[i].baseAGI * 10;
- sd->homunculus.vit = homunculus_db[i].baseVIT * 10;
- sd->homunculus.int_ = homunculus_db[i].baseINT * 10;
- sd->homunculus.dex = homunculus_db[i].baseDEX * 10;
- sd->homunculus.luk = homunculus_db[i].baseLUK * 10;
-
- // Clear all skills
- for(i=0;i<MAX_HOMUNSKILL;i++)
- sd->homunculus.hskill[i].id = sd->homunculus.hskill[i].lv = sd->homunculus.hskill[i].flag = 0;
+ memset(&homun, 0, sizeof(struct s_homunculus));
+ //Initial data
+ strncpy(homun.name, homunculus_db[i].name, NAME_LENGTH-1);
+ homun.class_ = class_;
+ homun.level = 1;
+// FIXME: Commented value is what the map-server had as initial value,
+// Uncommented value is what the char-server was overwriting it with
+// So which one is correct?
+// homun.hunger = 50;
+ homun.hunger = 32;
+// homun.intimacy = 500;
+ homun.intimacy = 21;
+ homun.char_id = sd->status.char_id;
+ homun.hp = 10 ;
+ homun.max_hp = homunculus_db[i].basemaxHP;
+ homun.max_sp = homunculus_db[i].basemaxSP;
+ homun.str = homunculus_db[i].baseSTR * 10;
+ homun.agi = homunculus_db[i].baseAGI * 10;
+ homun.vit = homunculus_db[i].baseVIT * 10;
+ homun.int_ = homunculus_db[i].baseINT * 10;
+ homun.dex = homunculus_db[i].baseDEX * 10;
+ homun.luk = homunculus_db[i].baseLUK * 10;
+
// Request homunculus creation
- intif_homunculus_create(sd->status.account_id, &sd->homunculus);
+ intif_homunculus_create(sd->status.account_id, &homun);
return 1;
}
@@ -749,19 +703,22 @@ int merc_resurrect_homunculus(struct map_session_data *sd, unsigned char per, sh
{
struct homun_data *hd;
nullpo_retr(0, sd);
- if (!sd->status.hom_id || sd->homunculus.vaporize)
+ if (!sd->status.hom_id)
return 0;
if (!sd->hd) //Load homun data;
- merc_hom_alloc(sd);
- else
- merc_hom_init_timers(sd->hd);
+ return intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
hd = sd->hd;
+ if (hd->homunculus.vaporize)
+ return 0;
+
if (!status_isdead(&hd->bl))
return 0;
+ merc_hom_init_timers(hd);
+
if (!hd->bl.prev)
{ //Add it back to the map.
hd->bl.m = sd->bl.m;
@@ -771,13 +728,13 @@ int merc_resurrect_homunculus(struct map_session_data *sd, unsigned char per, sh
clif_spawn(&sd->hd->bl);
}
status_revive(&hd->bl, per, 0);
- sd->homunculus.hp = hd->battle_status.hp;
return 1;
}
void merc_hom_revive(struct homun_data *hd, unsigned int hp, unsigned int sp)
{
struct map_session_data *sd = hd->master;
+ hd->homunculus.hp = hd->battle_status.hp;
if (!sd)
return;
clif_send_homdata(sd,SP_ACK,0);
diff --git a/src/map/mercenary.h b/src/map/mercenary.h
index d116db77e..73f791c68 100644
--- a/src/map/mercenary.h
+++ b/src/map/mercenary.h
@@ -44,7 +44,7 @@ enum {
SP_HUNGRY = 0x200
};
// merc_is_hom_alive(struct homun_data *)
-#define merc_is_hom_active(x) (x && x->master && x->master->homunculus.vaporize != 1 && x->battle_status.hp != 0)
+#define merc_is_hom_active(x) (x && x->homunculus.vaporize != 1 && x->battle_status.hp > 0)
int do_init_merc(void);
int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag); //albator
void merc_load_sub(struct homun_data *hd, struct map_session_data *sd);
@@ -53,8 +53,8 @@ char *merc_hom_skill_get_name(int id);
void merc_damage(struct homun_data *hd,struct block_list *src,int hp,int sp);
int merc_hom_dead(struct homun_data *hd, struct block_list *src);
void merc_hom_skillup(struct homun_data *hd,int skillnum);
-int merc_hom_calc_skilltree(struct map_session_data *sd) ;
-int merc_hom_checkskill(struct map_session_data *sd,int skill_id) ;
+int merc_hom_calc_skilltree(struct homun_data *hd) ;
+int merc_hom_checkskill(struct homun_data *hd,int skill_id) ;
int merc_hom_gainexp(struct homun_data *hd,int exp) ;
int merc_hom_levelup(struct homun_data *hd) ;
int merc_hom_evolution(struct homun_data *hd) ;
@@ -63,7 +63,7 @@ int merc_hom_vaporize(struct map_session_data *sd, int flag);
int merc_resurrect_homunculus(struct map_session_data *sd, unsigned char per, short x, short y);
void merc_hom_revive(struct homun_data *hd, unsigned int hp, unsigned int sp);
void merc_save(struct homun_data *hd);
-int merc_call_homunculus(struct map_session_data *sd, short x, short y);
+int merc_call_homunculus(struct map_session_data *sd);
int merc_create_homunculus_request(struct map_session_data *sd, int class_);
int search_homunculusDB_index(int key,int type);
int merc_menu(struct map_session_data *sd,int menunum);
diff --git a/src/map/pc.c b/src/map/pc.c
index ee003a66a..782b51d79 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -3360,7 +3360,7 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
unit_remove_map(&sd->pd->bl, clrtype);
}
if(sd->status.hom_id > 0 && sd->hd) { //orn
- intif_homunculus_requestsave(sd->status.account_id, &sd->homunculus);
+ intif_homunculus_requestsave(sd->status.account_id, &sd->hd->homunculus);
unit_remove_map(&sd->hd->bl, clrtype);
}
chrif_save(sd,2);
diff --git a/src/map/script.c b/src/map/script.c
index a8fbf454c..eef5cac23 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -7765,7 +7765,7 @@ int buildin_homunculus_evolution(struct script_state *st)
{
struct map_session_data *sd;
sd=script_rid2sd(st);
- if ( sd->hd && sd->hd->homunculusDB->evo_class && sd->homunculus.intimacy > 91000 ) {
+ if ( sd->hd && sd->hd->homunculusDB->evo_class && sd->hd->homunculus.intimacy > 91000 ) {
return merc_hom_evolution(sd->hd) ;
}
clif_emotion(&sd->hd->bl, 4) ; //swt
@@ -11737,19 +11737,19 @@ int buildin_rid2name(struct script_state *st){
if((bl = map_id2bl(rid))){
switch(bl->type){
case BL_MOB:
- push_str(st->stack,C_CONSTSTR,((struct mob_data *)bl)->name);
+ push_str(st->stack,C_CONSTSTR,((TBL_MOB*)bl)->name);
break;
case BL_PC:
- push_str(st->stack,C_CONSTSTR,((struct map_session_data *)bl)->status.name);
+ push_str(st->stack,C_CONSTSTR,((TBL_PC*)bl)->status.name);
break;
case BL_NPC:
- push_str(st->stack,C_CONSTSTR,((struct npc_data *)bl)->exname);
+ push_str(st->stack,C_CONSTSTR,((TBL_NPC*)bl)->exname);
break;
case BL_PET:
- push_str(st->stack,C_CONSTSTR,((struct pet_data *)bl)->pet.name);
+ push_str(st->stack,C_CONSTSTR,((TBL_PET*)bl)->pet.name);
break;
case BL_HOM:
- push_str(st->stack,C_CONSTSTR,((struct homun_data *)bl)->master->homunculus.name);
+ push_str(st->stack,C_CONSTSTR,((TBL_HOM*)bl)->homunculus.name);
break;
default:
ShowError("buildin_rid2name: BL type unknown.\n");
diff --git a/src/map/skill.c b/src/map/skill.c
index b3c87ddaf..d3bbb5617 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -757,11 +757,6 @@ int skill_get_range2 (struct block_list *bl, int id, int lv)
return status_get_range(bl);
range *=-1;
}
-
- //Use attack range.
- if(!range && !(skill_get_inf(id)&INF_SELF_SKILL))
- return status_get_range(bl);
-
//TODO: Find a way better than hardcoding the list of skills affected by AC_VULTURE
switch (id) {
case AC_SHOWER:
@@ -810,7 +805,7 @@ int skill_calc_heal (struct block_list *bl, int skill_lv)
if(bl->type == BL_PC && (skill = pc_checkskill((TBL_PC*)bl, HP_MEDITATIO)) > 0)
heal += heal * skill * 2 / 100;
- if(bl->type == BL_HOM && (skill = merc_hom_checkskill( ((TBL_HOM*)bl)->master, HLIF_BRAIN)) > 0) //[orn]
+ if(bl->type == BL_HOM && (skill = merc_hom_checkskill(((TBL_HOM*)bl), HLIF_BRAIN)) > 0)
heal += heal * skill * 2 / 100;
return heal;
}
@@ -1513,10 +1508,9 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
case HVAN_EXPLOSION:
if(src->type == BL_HOM){
TBL_HOM *hd = (TBL_HOM*)src;
- if (hd->master) {
- hd->master->homunculus.intimacy = 200;
- clif_send_homdata(hd->master,0x100,hd->master->homunculus.intimacy/100);
- }
+ hd->homunculus.intimacy = 200;
+ if (hd->master)
+ clif_send_homdata(hd->master,0x100,hd->homunculus.intimacy/100);
}
break;
}
@@ -2357,11 +2351,11 @@ static int skill_check_condition_hom (struct homun_data *hd, int skill, int lv,
switch(skill) { // Check for cost reductions due to skills & SCs
case HFLI_SBR44:
- if(sd->homunculus.intimacy <= 200)
+ if(hd->homunculus.intimacy <= 200)
return 0;
break;
case HVAN_EXPLOSION:
- if(sd->homunculus.intimacy < battle_config.hvan_explosion_intimate)
+ if(hd->homunculus.intimacy < battle_config.hvan_explosion_intimate)
return 0;
break;
}
@@ -2752,6 +2746,11 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case KN_CHARGEATK:
flag = distance_bl(src, bl);
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ if (unit_movepos(src, bl->x, bl->y, 1, 1))
+ clif_slide(src,bl->x,bl->y);
+ break;
+
case TK_JUMPKICK:
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
if (unit_movepos(src, bl->x, bl->y, 0, 0))
@@ -5440,6 +5439,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
else if (sd)
clif_skill_fail(sd,skillid,0,0);
break;
+
+ case AM_CALLHOMUN: //[orn]
+ if (sd && !merc_call_homunculus(sd))
+ clif_skill_fail(sd,skillid,0,0);
+ break;
+
case AM_REST:
if (sd)
{
@@ -5557,7 +5562,6 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data)
case WE_CALLPARTNER:
case WE_CALLPARENT:
case WE_CALLBABY:
- case AM_CALLHOMUN:
case AM_RESURRECTHOMUN:
//Find a random spot to place the skill. [Skotlex]
inf2 = skill_get_splash(ud->skillid, ud->skilllv);
@@ -6088,7 +6092,7 @@ int skill_castend_pos2 (struct block_list *src, int x, int y, int skillid, int s
}
break;
- // Slim Pitcher [Celest] (normally Condensed Potion doesn't give SP (Heals party members))
+ // Slim Pitcher [Celest]
case CR_SLIMPITCHER:
if (sd) {
int i = skilllv%11 - 1;
@@ -6205,11 +6209,6 @@ int skill_castend_pos2 (struct block_list *src, int x, int y, int skillid, int s
sc_start(src,type,100,skilllv,skill_get_time2(skillid,skilllv));
break;
- case AM_CALLHOMUN: //[orn]
- if (sd && !merc_call_homunculus(sd, x, y))
- clif_skill_fail(sd,skillid,0,0);
- break;
-
case AM_RESURRECTHOMUN: //[orn]
if (sd)
{
@@ -8298,7 +8297,7 @@ int skill_check_condition (struct map_session_data *sd, int skill, int lv, int t
zeny = 0; //Zeny is reduced on skill_attack.
break;
case AM_CALLHOMUN: //Can't summon if a hom is already out
- if (sd->status.hom_id && !sd->homunculus.vaporize) {
+ if (sd->status.hom_id && sd->hd && !sd->hd->homunculus.vaporize) {
clif_skill_fail(sd,skill,0,0);
return 0;
}
@@ -8313,7 +8312,7 @@ int skill_check_condition (struct map_session_data *sd, int skill, int lv, int t
}
break;
case AM_RESURRECTHOMUN: // Can't resurrect homun if you don't have a dead homun
- if (!sd->status.hom_id || sd->homunculus.hp)
+ if (!sd->status.hom_id || !sd->hd || sd->hd->homunculus.hp)
{
clif_skill_fail(sd,skill,0,0);
return 0;
@@ -9286,10 +9285,8 @@ int skill_landprotector (struct block_list *bl, va_list ap)
}
//Delete the rest of types.
case HW_GANBANTEIN:
- //Update: It deletes everything except songs/dances/encores.
if(!unit->group->state.song_dance)
-// if(skill_get_type(unit->group->skill_id) == BF_MAGIC)
- { //Delete Magical effects
+ { //It deletes everything except songs/dances/encores.
skill_delunit(unit, 1);
return 1;
}
@@ -9320,10 +9317,8 @@ int skill_landprotector (struct block_list *bl, va_list ap)
break;
}
if (unit->group->skill_id == SA_LANDPROTECTOR &&
- //Update: It deletes everything except songs/dances/encores.
!(skill_get_inf2(skillid)&(UF_DANCE|UF_SONG|UF_ENSEMBLE)))
-// skill_get_type(skillid) == BF_MAGIC)
- { //Magic tile won't be activated
+ { //It deletes everything except songs/dances/encores.
(*alive) = 0;
return 1;
}
diff --git a/src/map/status.c b/src/map/status.c
index a31848e94..97c3cc6e3 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -2327,13 +2327,11 @@ int status_calc_pc(struct map_session_data* sd,int first)
int status_calc_homunculus(struct homun_data *hd, int first)
{
struct status_data b_status, *status;
- struct map_session_data *sd;
struct s_homunculus *hom;
int skill;
memcpy(&b_status, &hd->base_status, sizeof(struct status_data));
- sd = hd->master;
- hom = &sd->homunculus;
+ hom = &hd->homunculus;
status = &hd->base_status;
@@ -2351,8 +2349,8 @@ int status_calc_homunculus(struct homun_data *hd, int first)
status->size = hd->homunculusDB->size ;
status->rhw.range = 1 + status->size;
status->mode = MD_CANMOVE|MD_CANATTACK|MD_ASSIST|MD_AGGRESSIVE|MD_CASTSENSOR;
- if (battle_config.slaves_inherit_speed && sd)
- status->speed = status_get_speed(&sd->bl);
+ if (battle_config.slaves_inherit_speed && hd->master)
+ status->speed = status_get_speed(&hd->master->bl);
else
status->speed = DEFAULT_WALK_SPEED;
status->hp = 1;
@@ -2367,21 +2365,21 @@ int status_calc_homunculus(struct homun_data *hd, int first)
status->max_hp = hom->max_hp ;
status->max_sp = hom->max_sp ;
- merc_hom_calc_skilltree(sd);
+ merc_hom_calc_skilltree(hd);
- if((skill=merc_hom_checkskill(sd,HAMI_SKIN)) > 0)
+ if((skill=merc_hom_checkskill(hd,HAMI_SKIN)) > 0)
status->def += skill * 4;
- if((skill = merc_hom_checkskill(hd->master,HVAN_INSTRUCT)) > 0)
+ if((skill = merc_hom_checkskill(hd,HVAN_INSTRUCT)) > 0)
{
- status->int_ += 1 +skill/2 -skill/4 +skill/5;
- status->str += 1 +2*(skill/3) +skill/4;
+ status->int_ += 1 +skill/2 -skill/4 +skill/5;
+ status->str += 1 +2*(skill/3) +skill/4;
}
- if((skill=merc_hom_checkskill(sd,HAMI_SKIN)) > 0)
+ if((skill=merc_hom_checkskill(hd,HAMI_SKIN)) > 0)
status->max_hp += skill * 2 * status->max_hp / 100;
- if((skill = merc_hom_checkskill(hd->master,HLIF_BRAIN)) > 0)
+ if((skill = merc_hom_checkskill(hd,HLIF_BRAIN)) > 0)
status->max_sp += (1 +skill/2 -skill/4 +skill/5) * status->max_sp / 100 ;
if (first) {
@@ -2507,15 +2505,15 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
sregen->sp = cap_value(val, 0, SHRT_MAX);
}
- if(bl->type==BL_HOM && ((TBL_HOM*)bl)->master)
+ if(bl->type==BL_HOM)
{
- sd = ((TBL_HOM*)bl)->master;
- if((skill=merc_hom_checkskill(sd,HAMI_SKIN)) > 0)
+ struct homun_data *hd = (TBL_HOM*)bl;
+ if((skill=merc_hom_checkskill(hd,HAMI_SKIN)) > 0)
{
val = regen->hp*(100+5*skill)/100;
regen->hp = cap_value(val, 1, SHRT_MAX);
}
- if((skill = merc_hom_checkskill(sd,HLIF_BRAIN)) > 0)
+ if((skill = merc_hom_checkskill(hd,HLIF_BRAIN)) > 0)
{
val = regen->sp*(100+3*skill)/100;
regen->sp = cap_value(val, 1, SHRT_MAX);
@@ -2725,8 +2723,6 @@ void status_calc_bl_sub_pc(struct map_session_data *sd, unsigned long flag)
unit_walktoxy(&sd->bl, sd->ud.to_x, sd->ud.to_y, sd->ud.state.walk_easy);
}
- //Needs be done even when it was already done in status_calc_misc, because
- //int/vit max hp/sp could have changed due to skills.
if(flag&(SCB_INT|SCB_MAXSP|SCB_VIT|SCB_MAXHP))
status_calc_regen(&sd->bl, status, &sd->regen);
@@ -3931,9 +3927,7 @@ const char * status_get_name(struct block_list *bl)
case BL_PET:
return ((TBL_PET*)bl)->pet.name;
case BL_HOM:
- if (((TBL_HOM*)bl)->master)
- return ((TBL_HOM*)bl)->master->homunculus.name;
- break;
+ return ((TBL_HOM*)bl)->homunculus.name;
case BL_NPC:
return ((TBL_NPC*)bl)->name;
}
@@ -3955,7 +3949,7 @@ int status_get_class(struct block_list *bl)
if(bl->type==BL_PET)
return ((struct pet_data *)bl)->pet.class_;
if(bl->type==BL_HOM)
- return ((struct homun_data *)bl)->master->homunculus.class_;
+ return ((struct homun_data *)bl)->homunculus.class_;
return 0;
}
/*==========================================
@@ -3973,7 +3967,7 @@ int status_get_lv(struct block_list *bl)
if(bl->type==BL_PET)
return ((TBL_PET*)bl)->pet.level;
if(bl->type==BL_HOM)
- return ((TBL_HOM*)bl)->master->homunculus.level;
+ return ((TBL_HOM*)bl)->homunculus.level;
return 1;
}
diff --git a/src/map/unit.c b/src/map/unit.c
index b7f42447e..38589b8e0 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -666,6 +666,9 @@ int unit_can_move(struct block_list *bl)
if (DIFF_TICK(ud->canmove_tick, gettick()) > 0)
return 0;
+ if (status_isdead(bl))
+ return 0;
+
if (sd && (
pc_issit(sd) ||
sd->state.blockedmove
@@ -1633,7 +1636,7 @@ int unit_remove_map(struct block_list *bl, int clrtype) {
} else if (bl->type == BL_HOM) {
struct homun_data *hd = (struct homun_data *) bl;
struct map_session_data *sd = hd->master;
- if(!sd || !sd->homunculus.intimacy)
+ if(!sd || !hd->homunculus.intimacy)
{ //He's going to be deleted.
clif_emotion(bl, 28) ; //sob
clif_clearchar_area(bl,clrtype);
@@ -1818,17 +1821,14 @@ int unit_free(struct block_list *bl, int clrtype) {
struct map_session_data *sd = hd->master;
// Desactive timers
merc_hom_hungry_timer_delete(hd);
- if(sd) {
- if (sd->homunculus.intimacy > 0)
- merc_save(hd);
- else
- {
- intif_homunculus_requestdelete(sd->homunculus.hom_id) ;
- sd->status.hom_id = 0;
- sd->homunculus.hom_id = 0;
- }
- sd->hd = NULL;
+ 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;
}
skill_clear_unitgroup(bl);