summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt7
-rw-r--r--src/char/int_homun.c52
-rw-r--r--src/char/inter.c2
-rw-r--r--src/char_sql/int_homun.c63
-rw-r--r--src/char_sql/inter.c2
-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
17 files changed, 345 insertions, 490 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 92a377dfc..4ba745efe 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,13 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/10/20
+ * Fixed Charge Atk being able to go through chasm/pits. [Skotlex]
+ * 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. [Skotlex]
+ WARNING: This is yet untested! It's very possible something could had
+ broken after changing the format/size of the homunc creation packets.
* Added config setting "summon_flora_setting", which it you can decide now
two things: a. Whether or not players can harm your floras outside versus
grounds, and b. Whether or not you can summon out and mix different types
diff --git a/src/char/int_homun.c b/src/char/int_homun.c
index 886c56f06..c71cd7792 100644
--- a/src/char/int_homun.c
+++ b/src/char/int_homun.c
@@ -183,20 +183,15 @@ int inter_homun_delete(int hom_id)
return 1;
}
-int mapif_homun_created(int fd,int account_id, int char_id, struct s_homunculus *p)
+int mapif_homun_created(int fd,int account_id, struct s_homunculus *p)
{
+ WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
WFIFOW(fd, 0) =0x3890;
- WFIFOL(fd,2) = account_id;
- WFIFOL(fd,6) = char_id;
- if(p){
- WFIFOW(fd,10)=1;
- WFIFOL(fd,12)=p->hom_id;
- } else{
- WFIFOW(fd,10)=0;
- WFIFOL(fd,12)=0;
- }
- WFIFOSET(fd, 16);
-
+ WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
+ WFIFOL(fd,4) = account_id;
+ WFIFOB(fd,8)= p->hom_id?1:0;
+ memcpy(WFIFOP(fd,9), p, sizeof(struct s_homunculus));
+ WFIFOSET(fd, WFIFOW(fd,2));
return 0;
}
@@ -259,40 +254,17 @@ int mapif_rename_homun_ack(int fd, int account_id, int char_id, int flag, char *
int mapif_create_homun(int fd)
{
struct s_homunculus *p;
- int account_id = RFIFOL(fd,2);
- int char_id = RFIFOL(fd,6);
p= (struct s_homunculus *) aCalloc(sizeof(struct s_homunculus), 1);
if(p==NULL){
ShowFatalError("int_homun: out of memory !\n");
- mapif_homun_created(fd,account_id,char_id,NULL);
+ //Sending the received data will pass hom_id == 0 <- fail.
+ mapif_homun_created(fd,RFIFOL(fd,4),(struct s_homunculus*)RFIFOP(fd,8));
return 0;
}
- /* Data from packet */
- p->char_id = char_id;
- p->class_ = RFIFOW(fd,10);
- p->max_hp = RFIFOL(fd,12);
- p->max_sp = RFIFOL(fd,16);
- memcpy(p->name, (char*)RFIFOP(fd, 20), NAME_LENGTH-1);
- p->str = RFIFOL(fd,44);
- p->agi = RFIFOL(fd,48);
- p->vit = RFIFOL(fd,52);
- p->int_ = RFIFOL(fd,56);
- p->dex = RFIFOL(fd,60);
- p->luk = RFIFOL(fd,64);
-
- /* Const data for each creation*/
- p->hom_id = homun_newid++;
- p->exp = 0;
- p->hp = 10 ;
- p->sp = 0 ;
- p->rename_flag = 0;
- p->skillpts =0;
- p->hunger = 32;
- p->level=1;
- p->intimacy = 21;
-
+ memcpy(p, RFIFOP(fd,8), sizeof(struct s_homunculus));
+ p->hom_id = homun_newid++; //New ID
idb_put(homun_db,p->hom_id,p);
- mapif_homun_created(fd,account_id,char_id,p);
+ mapif_homun_created(fd,RFIFOL(fd,4),p);
return 0;
}
diff --git a/src/char/inter.c b/src/char/inter.c
index 17b8ddc56..74ea3a956 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -58,7 +58,7 @@ int inter_recv_packet_length[]={
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,
48,14,-1, 6, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3080-0x308f
- 68,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3090 - 0x309f Homunculus packets [albator]
+ -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3090 - 0x309f Homunculus packets [albator]
};
struct WisData {
diff --git a/src/char_sql/int_homun.c b/src/char_sql/int_homun.c
index 31a86fd37..9f5fd24d4 100644
--- a/src/char_sql/int_homun.c
+++ b/src/char_sql/int_homun.c
@@ -62,27 +62,15 @@ int mapif_homunculus_deleted(int fd, int flag)
}
int mapif_homunculus_created(int fd, int account_id, struct s_homunculus *sh, short flag)
{
- WFIFOW(fd, 0) =0x3890;
- WFIFOL(fd,2) = account_id;
- WFIFOL(fd,6) = sh->char_id;
- if(flag==1){
- WFIFOW(fd, 10)=1;
- WFIFOL(fd,12) = sh->hom_id;
- }
- else{
- WFIFOW(fd, 10)=0;
- WFIFOL(fd,12) = 0;
- }
- WFIFOSET(fd, 16);
-
+ WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
+ WFIFOW(fd,0) = 0x3890;
+ WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
+ WFIFOL(fd,4) = account_id;
+ WFIFOB(fd,8)= flag;
+ memcpy(WFIFOP(fd,9),sh,sizeof(struct s_homunculus));
+ WFIFOSET(fd, WFIFOW(fd,2));
return 0;
}
-void init_homun_skills(struct s_homunculus *hd)
-{
- int i;
- for(i=0;i<MAX_HOMUNSKILL;i++)
- hd->hskill[i].id = hd->hskill[i].lv = hd->hskill[i].flag = 0;
-}
// Save/Update Homunculus Skills
int mapif_save_homunculus_skills(struct s_homunculus *hd)
@@ -199,7 +187,7 @@ int mapif_load_homunculus(int fd){
mysql_free_result(sql_res);
// Load Homunculus Skill
- init_homun_skills(homun_pt); //bousille homun_pt !!!
+ memset(homun_pt->hskill, 0, sizeof(homun_pt->hskill));
sprintf(tmp_sql,"SELECT `id`,`lv` FROM `skill_homunculus` WHERE `homun_id`=%d",homun_pt->hom_id);
if(mysql_query(&mysql_handle, tmp_sql) ) {
@@ -279,39 +267,12 @@ int mapif_rename_homun(int fd, int account_id, int char_id, char *name){
int mapif_parse_CreateHomunculus(int fd)
{
- memset(homun_pt, 0, sizeof(struct s_homunculus));
-
- /* Data from packet */
- homun_pt->char_id = RFIFOL(fd,6);
- homun_pt->class_ = RFIFOW(fd,10);
- homun_pt->max_hp = RFIFOL(fd,12);
- homun_pt->max_sp = RFIFOL(fd,16);
- memcpy(homun_pt->name, (char*)RFIFOP(fd, 20), NAME_LENGTH-1);
- homun_pt->str = RFIFOL(fd,44);
- homun_pt->agi = RFIFOL(fd,48);
- homun_pt->vit = RFIFOL(fd,52);
- homun_pt->int_ = RFIFOL(fd,56);
- homun_pt->dex = RFIFOL(fd,60);
- homun_pt->luk = RFIFOL(fd,64);
-
- /* Const data for each creation*/
- homun_pt->hom_id = 0;
- homun_pt->exp =0;
- homun_pt->hp = 10 ;
- homun_pt->sp = 0 ;
- homun_pt->rename_flag = 0;
- homun_pt->skillpts =0;
- homun_pt->hunger = 32;
- homun_pt->level=1;
- homun_pt->intimacy = 21;
-
+ memcpy(homun_pt, RFIFOP(fd,8), sizeof(struct s_homunculus));
// Save in sql db
- if(mapif_save_homunculus(fd,RFIFOL(fd,2), homun_pt))
- return mapif_homunculus_created(fd, RFIFOL(fd,2), homun_pt, 1); // send homun_id
+ if(mapif_save_homunculus(fd,RFIFOL(fd,4), homun_pt))
+ return mapif_homunculus_created(fd, RFIFOL(fd,4), homun_pt, 1); // send homun_id
else
- return mapif_homunculus_created(fd, RFIFOL(fd,2), homun_pt, 0); // fail
-
-
+ return mapif_homunculus_created(fd, RFIFOL(fd,4), homun_pt, 0); // fail
}
diff --git a/src/char_sql/inter.c b/src/char_sql/inter.c
index f02296f58..249d260a6 100644
--- a/src/char_sql/inter.c
+++ b/src/char_sql/inter.c
@@ -74,7 +74,7 @@ int inter_recv_packet_length[]={
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,
48,14,-1, 6, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3080-0x308f
- 68,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3090 - 0x309f Homunculus packets [albator]
+ -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3090 - 0x309f Homunculus packets [albator]
};
struct WisData {
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);