|
@@ -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)
|
|
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;
|
|
struct map_session_data *sd = hd->master;
|
|
|
|
|
|
clif_emotion(&hd->bl, 16) ; //wah
|
|
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.
|
|
//Delete timers when dead.
|
|
merc_hom_hungry_timer_delete(hd);
|
|
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_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)
|
|
//Remove from map (if it has no intimacy, it is auto-removed from memory)
|
|
return 3;
|
|
return 3;
|
|
}
|
|
}
|
|
@@ -75,7 +77,7 @@ int merc_hom_vaporize(struct map_session_data *sd, int flag)
|
|
nullpo_retr(0, sd);
|
|
nullpo_retr(0, sd);
|
|
|
|
|
|
hd = sd->hd;
|
|
hd = sd->hd;
|
|
- if (!hd || sd->homunculus.vaporize)
|
|
|
|
|
|
+ if (!hd || hd->homunculus.vaporize)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
if (status_isdead(&hd->bl))
|
|
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.
|
|
hd->regen.state.block = 3; //Block regen while vaporized.
|
|
//Delete timers when vaporized.
|
|
//Delete timers when vaporized.
|
|
merc_hom_hungry_timer_delete(hd);
|
|
merc_hom_hungry_timer_delete(hd);
|
|
- sd->homunculus.vaporize = 1;
|
|
|
|
|
|
+ hd->homunculus.vaporize = 1;
|
|
clif_hominfo(sd, sd->hd, 0);
|
|
clif_hominfo(sd, sd->hd, 0);
|
|
merc_save(hd);
|
|
merc_save(hd);
|
|
return unit_remove_map(&hd->bl, 0);
|
|
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);
|
|
clif_emotion(&sd->bl, emote);
|
|
|
|
|
|
//This makes it be deleted right away.
|
|
//This makes it be deleted right away.
|
|
- sd->homunculus.intimacy = 0;
|
|
|
|
|
|
+ hd->homunculus.intimacy = 0;
|
|
// Send homunculus_dead to client
|
|
// Send homunculus_dead to client
|
|
- sd->homunculus.hp = 0;
|
|
|
|
|
|
+ hd->homunculus.hp = 0;
|
|
clif_hominfo(sd, hd, 0);
|
|
clif_hominfo(sd, hd, 0);
|
|
return unit_remove_map(&hd->bl,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 i,id=0 ;
|
|
int j,f=1;
|
|
int j,f=1;
|
|
int c=0;
|
|
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++)
|
|
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.
|
|
continue; //Skill already known.
|
|
if(!battle_config.skillfree)
|
|
if(!battle_config.skillfree)
|
|
{
|
|
{
|
|
for(j=0;j<5;j++)
|
|
for(j=0;j<5;j++)
|
|
{
|
|
{
|
|
if( hskill_tree[c][i].need[j].id &&
|
|
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;
|
|
f=0;
|
|
break;
|
|
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;
|
|
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;
|
|
int i = skill_id - HM_SKILLBASE - 1;
|
|
- if(!sd)
|
|
|
|
|
|
+ if(!hd)
|
|
return 0;
|
|
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;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -173,17 +174,17 @@ void merc_hom_skillup(struct homun_data *hd,int skillnum)
|
|
int i = 0 ;
|
|
int i = 0 ;
|
|
nullpo_retv(hd);
|
|
nullpo_retv(hd);
|
|
|
|
|
|
- if(!hd->master->homunculus.vaporize)
|
|
|
|
|
|
+ if(!hd->homunculus.vaporize)
|
|
{
|
|
{
|
|
i = skillnum - HM_SKILLBASE - 1 ;
|
|
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) ;
|
|
status_calc_homunculus(hd,0) ;
|
|
clif_homskillup(hd->master, skillnum) ;
|
|
clif_homskillup(hd->master, skillnum) ;
|
|
clif_hominfo(hd->master,hd,0) ;
|
|
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 ;
|
|
int growth_max_hp, growth_max_sp ;
|
|
char output[256] ;
|
|
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 ;
|
|
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 )
|
|
if ( hd->homunculusDB->gmaxHP <= hd->homunculusDB->gminHP )
|
|
growth_max_hp = hd->homunculusDB->gminHP ;
|
|
growth_max_hp = hd->homunculusDB->gminHP ;
|
|
@@ -241,14 +242,14 @@ int merc_hom_levelup(struct homun_data *hd)
|
|
else
|
|
else
|
|
growth_luk = rand(hd->homunculusDB->gminLUK, hd->homunculusDB->gmaxLUK) ;
|
|
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 ) {
|
|
if ( battle_config.homunculus_show_growth ) {
|
|
sprintf(output,
|
|
sprintf(output,
|
|
@@ -262,13 +263,12 @@ int merc_hom_change_class(struct homun_data *hd, short class_)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS);
|
|
i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS);
|
|
- if(i < 0) {
|
|
|
|
|
|
+ if(i < 0)
|
|
return 0;
|
|
return 0;
|
|
- }
|
|
|
|
hd->homunculusDB = &homunculus_db[i];
|
|
hd->homunculusDB = &homunculus_db[i];
|
|
- hd->master->homunculus.class_ = class_;
|
|
|
|
|
|
+ hd->homunculus.class_ = class_;
|
|
status_set_viewdata(&hd->bl, class_);
|
|
status_set_viewdata(&hd->bl, class_);
|
|
- merc_hom_calc_skilltree(hd->master);
|
|
|
|
|
|
+ merc_hom_calc_skilltree(hd);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -289,11 +289,11 @@ int merc_hom_evolution(struct homun_data *hd)
|
|
merc_hom_vaporize(sd, 0);
|
|
merc_hom_vaporize(sd, 0);
|
|
|
|
|
|
if (!merc_hom_change_class(hd, hd->homunculusDB->evo_class)) {
|
|
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;
|
|
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_emotion(&sd->bl, 21); //no1
|
|
clif_misceffect2(&hd->bl,568);
|
|
clif_misceffect2(&hd->bl,568);
|
|
return 1 ;
|
|
return 1 ;
|
|
@@ -301,17 +301,17 @@ int merc_hom_evolution(struct homun_data *hd)
|
|
|
|
|
|
int merc_hom_gainexp(struct homun_data *hd,int exp)
|
|
int merc_hom_gainexp(struct homun_data *hd,int exp)
|
|
{
|
|
{
|
|
- if(hd->master->homunculus.vaporize)
|
|
|
|
|
|
+ if(hd->homunculus.vaporize)
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
if( hd->exp_next == 0 ) {
|
|
if( hd->exp_next == 0 ) {
|
|
- hd->master->homunculus.exp = 0 ;
|
|
|
|
|
|
+ hd->homunculus.exp = 0 ;
|
|
return 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);
|
|
clif_hominfo(hd->master,hd,0);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -321,10 +321,10 @@ int merc_hom_gainexp(struct homun_data *hd,int exp)
|
|
{
|
|
{
|
|
merc_hom_levelup(hd) ;
|
|
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 )
|
|
if( hd->exp_next == 0 )
|
|
- hd->master->homunculus.exp = 0 ;
|
|
|
|
|
|
+ hd->homunculus.exp = 0 ;
|
|
|
|
|
|
clif_misceffect2(&hd->bl,568);
|
|
clif_misceffect2(&hd->bl,568);
|
|
status_calc_homunculus(hd,0);
|
|
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)
|
|
if (battle_config.homunculus_friendly_rate != 100)
|
|
value = (value * 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
|
|
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
|
|
// 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)
|
|
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
|
|
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)
|
|
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
|
|
//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
|
|
//to status changes/skills (they will be capped as needed upon stat
|
|
//calculation on login)
|
|
//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)
|
|
int merc_menu(struct map_session_data *sd,int menunum)
|
|
{
|
|
{
|
|
nullpo_retr(0, sd);
|
|
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;
|
|
int i, foodID, emotion;
|
|
|
|
|
|
- if(sd->homunculus.vaporize)
|
|
|
|
|
|
+ if(hd->homunculus.vaporize)
|
|
return 1 ;
|
|
return 1 ;
|
|
|
|
|
|
foodID = hd->homunculusDB->foodID;
|
|
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);
|
|
pc_delitem(sd,i,1,0);
|
|
|
|
|
|
- if ( sd->homunculus.hunger >= 91 ) {
|
|
|
|
|
|
+ if ( hd->homunculus.hunger >= 91 ) {
|
|
merc_hom_decrease_intimacy(hd, 50);
|
|
merc_hom_decrease_intimacy(hd, 50);
|
|
emotion = 16;
|
|
emotion = 16;
|
|
- } else if ( sd->homunculus.hunger >= 76 ) {
|
|
|
|
|
|
+ } else if ( hd->homunculus.hunger >= 76 ) {
|
|
merc_hom_decrease_intimacy(hd, 5);
|
|
merc_hom_decrease_intimacy(hd, 5);
|
|
emotion = 19;
|
|
emotion = 19;
|
|
- } else if ( sd->homunculus.hunger >= 26 ) {
|
|
|
|
|
|
+ } else if ( hd->homunculus.hunger >= 26 ) {
|
|
merc_hom_increase_intimacy(hd, 75);
|
|
merc_hom_increase_intimacy(hd, 75);
|
|
emotion = 2;
|
|
emotion = 2;
|
|
- } else if ( sd->homunculus.hunger >= 11 ) {
|
|
|
|
|
|
+ } else if ( hd->homunculus.hunger >= 11 ) {
|
|
merc_hom_increase_intimacy(hd, 100);
|
|
merc_hom_increase_intimacy(hd, 100);
|
|
emotion = 2;
|
|
emotion = 2;
|
|
} else {
|
|
} else {
|
|
@@ -484,17 +427,17 @@ int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
|
|
emotion = 2;
|
|
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_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);
|
|
clif_hom_food(sd,foodID,1);
|
|
|
|
|
|
// Too much food :/
|
|
// Too much food :/
|
|
- if(sd->homunculus.intimacy == 0)
|
|
|
|
|
|
+ if(hd->homunculus.intimacy == 0)
|
|
return merc_hom_delete(sd->hd, 23); //omg
|
|
return merc_hom_delete(sd->hd, 23); //omg
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -520,24 +463,24 @@ static int merc_hom_hungry(int tid,unsigned int tick,int id,int data)
|
|
|
|
|
|
hd->hungry_timer = -1;
|
|
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
|
|
clif_emotion(&hd->bl, 6) ; //an
|
|
- } else if(sd->homunculus.hunger == 25) {
|
|
|
|
|
|
+ } else if(hd->homunculus.hunger == 25) {
|
|
clif_emotion(&hd->bl, 20) ; //hmm
|
|
clif_emotion(&hd->bl, 20) ; //hmm
|
|
- } else if(sd->homunculus.hunger == 75) {
|
|
|
|
|
|
+ } else if(hd->homunculus.hunger == 75) {
|
|
clif_emotion(&hd->bl, 33) ; //ok
|
|
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
|
|
// Delete the homunculus if intimacy <= 100
|
|
if ( !merc_hom_decrease_intimacy(hd, 100) )
|
|
if ( !merc_hom_decrease_intimacy(hd, 100) )
|
|
return merc_hom_delete(sd->hd, 23); //omg
|
|
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
|
|
hd->hungry_timer = add_timer(tick+hd->homunculusDB->hungryDelay,merc_hom_hungry,sd->bl.id,0); //simple Fix albator
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -576,7 +519,7 @@ int search_homunculusDB_index(int key,int type)
|
|
}
|
|
}
|
|
|
|
|
|
// Create homunc structure
|
|
// 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;
|
|
struct homun_data *hd;
|
|
int i = 0;
|
|
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);
|
|
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) {
|
|
if(i < 0) {
|
|
|
|
+ ShowError("merc_hom_alloc: unknown homunculus class [%d]", hom->class_);
|
|
sd->status.hom_id = 0;
|
|
sd->status.hom_id = 0;
|
|
- ShowError("merc_hom_alloc: unknown homunculus class [%d]", sd->homunculus.class_);
|
|
|
|
|
|
+ intif_homunculus_requestdelete(hom->hom_id);
|
|
return 1;
|
|
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];
|
|
hd->homunculusDB = &homunculus_db[i];
|
|
|
|
+ memcpy(&hd->homunculus, hom, sizeof(struct s_homunculus));
|
|
hd->master = sd;
|
|
hd->master = sd;
|
|
|
|
|
|
- hd->bl.m = sd->bl.m;
|
|
|
|
-
|
|
|
|
// Find a random valid pos around the player
|
|
// Find a random valid pos around the player
|
|
|
|
+ hd->bl.m = sd->bl.m;
|
|
hd->bl.x = sd->bl.x;
|
|
hd->bl.x = sd->bl.x;
|
|
hd->bl.y = sd->bl.y;
|
|
hd->bl.y = sd->bl.y;
|
|
x = sd->bl.x + 1;
|
|
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.id = npc_get_new_npc_id();
|
|
hd->bl.prev = NULL;
|
|
hd->bl.prev = NULL;
|
|
hd->bl.next = 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);
|
|
status_change_init(&hd->bl);
|
|
unit_dataset(&hd->bl);
|
|
unit_dataset(&hd->bl);
|
|
hd->ud.dir = sd->ud.dir;
|
|
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.
|
|
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;
|
|
struct homun_data *hd;
|
|
|
|
|
|
if (!sd->status.hom_id) //Create a new homun.
|
|
if (!sd->status.hom_id) //Create a new homun.
|
|
return merc_create_homunculus_request(sd, HM_CLASS_BASE + rand(0, 7)) ;
|
|
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 homunc not yet loaded, load it
|
|
if (!sd->hd)
|
|
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;
|
|
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)
|
|
if (hd->bl.prev == NULL)
|
|
{ //Spawn him
|
|
{ //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;
|
|
hd->bl.m = sd->bl.m;
|
|
map_addblock(&hd->bl);
|
|
map_addblock(&hd->bl);
|
|
clif_spawn(&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);
|
|
merc_save(hd);
|
|
} else
|
|
} else
|
|
//Warp him to master.
|
|
//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;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
// Recv homunculus data from char server
|
|
// Recv homunculus data from char server
|
|
int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag)
|
|
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);
|
|
sd = map_id2sd(account_id);
|
|
if(!sd)
|
|
if(!sd)
|
|
return 0;
|
|
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
|
|
if(!flag) { // Failed to load
|
|
sd->status.hom_id = 0;
|
|
sd->status.hom_id = 0;
|
|
return 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_homskillinfoblock(sd);
|
|
- clif_hominfo(sd,sd->hd,0);
|
|
|
|
|
|
+ clif_hominfo(sd,hd,0);
|
|
clif_send_homdata(sd,SP_ACK,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
|
|
// Ask homunculus creation to char server
|
|
int merc_create_homunculus_request(struct map_session_data *sd, int class_)
|
|
int merc_create_homunculus_request(struct map_session_data *sd, int class_)
|
|
{
|
|
{
|
|
|
|
+ struct s_homunculus homun;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
nullpo_retr(1, sd);
|
|
nullpo_retr(1, sd);
|
|
|
|
|
|
i = search_homunculusDB_index(class_,HOMUNCULUS_CLASS);
|
|
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
|
|
// Request homunculus creation
|
|
- intif_homunculus_create(sd->status.account_id, &sd->homunculus);
|
|
|
|
|
|
+ intif_homunculus_create(sd->status.account_id, &homun);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -749,19 +703,22 @@ int merc_resurrect_homunculus(struct map_session_data *sd, unsigned char per, sh
|
|
{
|
|
{
|
|
struct homun_data *hd;
|
|
struct homun_data *hd;
|
|
nullpo_retr(0, sd);
|
|
nullpo_retr(0, sd);
|
|
- if (!sd->status.hom_id || sd->homunculus.vaporize)
|
|
|
|
|
|
+ if (!sd->status.hom_id)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
if (!sd->hd) //Load homun data;
|
|
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;
|
|
hd = sd->hd;
|
|
|
|
|
|
|
|
+ if (hd->homunculus.vaporize)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
if (!status_isdead(&hd->bl))
|
|
if (!status_isdead(&hd->bl))
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
+ merc_hom_init_timers(hd);
|
|
|
|
+
|
|
if (!hd->bl.prev)
|
|
if (!hd->bl.prev)
|
|
{ //Add it back to the map.
|
|
{ //Add it back to the map.
|
|
hd->bl.m = sd->bl.m;
|
|
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);
|
|
clif_spawn(&sd->hd->bl);
|
|
}
|
|
}
|
|
status_revive(&hd->bl, per, 0);
|
|
status_revive(&hd->bl, per, 0);
|
|
- sd->homunculus.hp = hd->battle_status.hp;
|
|
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
void merc_hom_revive(struct homun_data *hd, unsigned int hp, unsigned int sp)
|
|
void merc_hom_revive(struct homun_data *hd, unsigned int hp, unsigned int sp)
|
|
{
|
|
{
|
|
struct map_session_data *sd = hd->master;
|
|
struct map_session_data *sd = hd->master;
|
|
|
|
+ hd->homunculus.hp = hd->battle_status.hp;
|
|
if (!sd)
|
|
if (!sd)
|
|
return;
|
|
return;
|
|
clif_send_homdata(sd,SP_ACK,0);
|
|
clif_send_homdata(sd,SP_ACK,0);
|