diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 92a377dfcf..4ba745efe1 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 886c56f06a..c71cd77925 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 17b8ddc567..74ea3a9563 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 31a86fd373..9f5fd24d45 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;ihskill[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 f02296f588..249d260a67 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 82d1b4c9a9..b8f1c6cab9 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 da209b2a15..95a4ac49f8 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 516b909e48..a667b74be2 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 6dc5f15cd0..bab76b40b5 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); + ShowError("intif: homun data: data size error %d %d\n",sizeof(struct s_homunculus),len); + return 0; } - else{ - memcpy(&sh,RFIFOP(fd,9),sizeof(struct s_homunculus)); - merc_hom_recv_data(RFIFOL(fd,4),&sh,RFIFOB(fd,8)); - } - + 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 1c500a1cf6..6f0816c78a 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 24ced263b3..f027d92348 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); + if(i < 0) return 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; - 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; - - 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;ihomunculus.hskill[i].id = sd->homunculus.hskill[i].lv = sd->homunculus.hskill[i].flag = 0; - // 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 d116db77ed..73f791c68f 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 ee003a66a3..782b51d796 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 a8fbf454c1..eef5cac23b 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 b3c87ddaf6..d3bbb56174 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 a31848e94f..97c3cc6e3d 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 b7f42447e8..38589b8e0c 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);