* Fix homunc & code cleanup [Toms]

- Timer problems on delete_timer
  - Intimacy problem (overflow & new values)
  - Homunc deleted if intimacy < 0
  - base exp is now given to master
  - Homunc sometimes not saved

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@7913 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
toms 2006-07-27 11:56:22 +00:00
parent 6eb305c5a9
commit ee5ee4fcd0
7 changed files with 114 additions and 75 deletions

View File

@ -3,6 +3,13 @@ Date Added
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/07/27
* Fix homunc & code cleanup [Toms]
- Timer problems on delete_timer
- Intimacy problem (overflow & new values)
- Homunc deleted if intimacy < 0
- base exp is now given to master
- Homunc sometimes not saved
2006/07/26 2006/07/26
* Fixed a memory leak when reading the item_db txt. [Skotlex] * Fixed a memory leak when reading the item_db txt. [Skotlex]
* Applied the necessary changes to make @partyoption reflect it's changes * Applied the necessary changes to make @partyoption reflect it's changes

View File

@ -482,7 +482,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
(p->int_ != cp->int_) || (p->dex != cp->dex) || (p->luk != cp->luk) || (p->int_ != cp->int_) || (p->dex != cp->dex) || (p->luk != cp->luk) ||
(p->option != cp->option) || (p->option != cp->option) ||
(p->party_id != cp->party_id) || (p->guild_id != cp->guild_id) || (p->party_id != cp->party_id) || (p->guild_id != cp->guild_id) ||
(p->pet_id != cp->pet_id) || (p->weapon != cp->weapon) || (p->pet_id != cp->pet_id) || (p->weapon != cp->weapon) || (p->hom_id != cp->hom_id) ||
(p->shield != cp->shield) || (p->head_top != cp->head_top) || (p->shield != cp->shield) || (p->head_top != cp->head_top) ||
(p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) (p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom)
) )

View File

@ -174,7 +174,7 @@ struct s_homunculus { //[orn]
int char_id; int char_id;
short class_; short class_;
int hp,max_hp,sp,max_sp; int hp,max_hp,sp,max_sp;
int intimacy; //[orn] unsigned long intimacy; //[orn]
short hunger; short hunger;
struct skill hskill[MAX_HOMUNSKILL]; //albator struct skill hskill[MAX_HOMUNSKILL]; //albator
short skillpts; short skillpts;

View File

@ -104,6 +104,7 @@ void merc_load_exptables(void)
} }
void merc_damage(struct homun_data *hd,struct block_list *src,int hp,int sp) void merc_damage(struct homun_data *hd,struct block_list *src,int hp,int sp)
{ {
nullpo_retv(hd); nullpo_retv(hd);
@ -119,9 +120,9 @@ 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)
{ {
hd->master->homunculus.intimacy -= 100 ;
hd->master->homunculus.hp = 0 ; hd->master->homunculus.hp = 0 ;
if(hd->master->homunculus.intimacy <= 0) { clif_hominfo(hd->master, 0); // Send dead flag
if(!merc_hom_decrease_intimacy(hd, 100)) { // Intimacy was < 100
merc_stop_walking(hd, 1); merc_stop_walking(hd, 1);
merc_stop_attack(hd); merc_stop_attack(hd);
clif_emotion(&hd->master->bl, 23) ; //omg clif_emotion(&hd->master->bl, 23) ; //omg
@ -138,7 +139,6 @@ int merc_hom_dead(struct homun_data *hd, struct block_list *src)
int merc_hom_delete(struct homun_data *hd, int flag) int merc_hom_delete(struct homun_data *hd, int flag)
{ {
nullpo_retr(0, hd); nullpo_retr(0, hd);
// Delete homunculus // Delete homunculus
if ( flag&1 ) { //sabbath if ( flag&1 ) { //sabbath
intif_homunculus_requestdelete(hd->master->homunculus.hom_id) ; intif_homunculus_requestdelete(hd->master->homunculus.hom_id) ;
@ -358,6 +358,35 @@ int merc_hom_gainexp(struct homun_data *hd,int exp)
return 0; return 0;
} }
// Return then new value
int merc_hom_increase_intimacy(struct homun_data * hd, unsigned int value)
{
if (hd->master->homunculus.intimacy + value <= 100000)
{
hd->master->homunculus.intimacy += value;
}
else
{
hd->master->homunculus.intimacy = 100000;
}
return hd->master->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;
}
else
{
hd->master->homunculus.intimacy = 0;
}
return hd->master->homunculus.intimacy;
}
int merc_hom_heal(struct homun_data *hd,int hp,int sp) int merc_hom_heal(struct homun_data *hd,int hp,int sp)
{ {
nullpo_retr(0, hd); nullpo_retr(0, hd);
@ -469,6 +498,8 @@ int merc_natural_heal(int tid,unsigned int tick,int id,int data)
nullpo_retr(0, sd); nullpo_retr(0, sd);
sd->hd->natural_heal_timer = -1;
if(sd->homunculus.vaporize) if(sd->homunculus.vaporize)
return 1; return 1;
@ -573,7 +604,7 @@ int merc_menu(struct map_session_data *sd,int menunum)
int merc_hom_food(struct map_session_data *sd, struct homun_data *hd) int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
{ {
int i, k, intimacy, emotion; int i, k, emotion;
if(hd->master->homunculus.vaporize) if(hd->master->homunculus.vaporize)
return 1 ; return 1 ;
@ -587,28 +618,22 @@ 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 ( hd->master->homunculus.hunger >= 91 ) { if ( hd->master->homunculus.hunger >= 91 ) {
intimacy = -50; merc_hom_decrease_intimacy(hd, 50);
emotion = 16; emotion = 16;
} else if ( hd->master->homunculus.hunger >= 76 ) { } else if ( hd->master->homunculus.hunger >= 76 ) {
intimacy = -30; merc_hom_decrease_intimacy(hd, 5);
emotion = 19; emotion = 19;
} else if ( hd->master->homunculus.hunger >= 26 ) { } else if ( hd->master->homunculus.hunger >= 26 ) {
intimacy = 80; merc_hom_increase_intimacy(hd, 75);
emotion = 2; emotion = 2;
} else if ( hd->master->homunculus.hunger >= 11 ) { } else if ( hd->master->homunculus.hunger >= 11 ) {
intimacy = 100; merc_hom_increase_intimacy(hd, 100);
emotion = 2; emotion = 2;
} else { } else {
intimacy = 50; merc_hom_increase_intimacy(hd, 25);
emotion = 2; emotion = 2;
} }
hd->master->homunculus.intimacy += intimacy;
if(hd->master->homunculus.intimacy < 0)
hd->master->homunculus.intimacy = 0;
if(hd->master->homunculus.intimacy > 100000)
hd->master->homunculus.intimacy = 100000;
//emotion = 5 ; // FIXME: why the code above and now always set emotion to Thanks?
hd->master->homunculus.hunger += 10; //dunno increase value for each food hd->master->homunculus.hunger += 10; //dunno increase value for each food
if(hd->master->homunculus.hunger > 100) if(hd->master->homunculus.hunger > 100)
hd->master->homunculus.hunger = 100; hd->master->homunculus.hunger = 100;
@ -617,14 +642,17 @@ int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger); clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger);
clif_send_homdata(sd,SP_INTIMATE,sd->homunculus.intimacy / 100); clif_send_homdata(sd,SP_INTIMATE,sd->homunculus.intimacy / 100);
clif_hom_food(sd,hd->homunculusDB->foodID,1); clif_hom_food(sd,hd->homunculusDB->foodID,1);
if(hd->master->homunculus.intimacy == 0) { // Too much food :/
if(hd->master->homunculus.intimacy == 0) {
merc_stop_walking(hd, 1); merc_stop_walking(hd, 1);
merc_stop_attack(hd); merc_stop_attack(hd);
clif_emotion(&hd->master->bl, 23) ; //omg // Send homunculus_dead to client
merc_hom_delete(hd,1) ; sd->homunculus.hp = 0;
} clif_hominfo(sd, 0);
merc_hom_delete(hd,1);
clif_emotion(&hd->master->bl, 23); //omg
}
return 0; return 0;
} }
@ -646,37 +674,38 @@ static int merc_hom_hungry(int tid,unsigned int tick,int id,int data)
ShowError("merc_hom_hungry_timer %d != %d\n",hd->hungry_timer,tid); ShowError("merc_hom_hungry_timer %d != %d\n",hd->hungry_timer,tid);
return 0 ; return 0 ;
} }
hd->hungry_timer = -1;
hd->master->homunculus.hunger-- ; hd->master->homunculus.hunger-- ;
if(hd->master->homunculus.hunger >= 0 && hd->master->homunculus.hunger <= 10) { if(hd->master->homunculus.hunger <= 10) {
clif_emotion(&hd->bl, 6) ; //an clif_emotion(&hd->bl, 6) ; //an
} } else if(hd->master->homunculus.hunger == 25) {
if(hd->master->homunculus.hunger == 25) {
clif_emotion(&hd->bl, 20) ; //hmm clif_emotion(&hd->bl, 20) ; //hmm
} } else if(hd->master->homunculus.hunger == 75) {
if(hd->master->homunculus.hunger == 75) {
clif_emotion(&hd->bl, 33) ; //ok clif_emotion(&hd->bl, 33) ; //ok
} }
if(hd->master->homunculus.hunger < 0) { if(hd->master->homunculus.hunger < 0) {
hd->master->homunculus.hunger = 0; hd->master->homunculus.hunger = 0;
hd->master->homunculus.intimacy -= 100; // Delete the homunculus if intimacy <= 100
if(hd->master->homunculus.intimacy < 0) if ( !merc_hom_decrease_intimacy(hd, 100) ) {
hd->master->homunculus.intimacy = 0;
clif_send_homdata(sd,SP_INTIMATE,sd->homunculus.intimacy / 100);
if(hd->master->homunculus.intimacy == 0) {
merc_stop_walking(hd, 1); merc_stop_walking(hd, 1);
merc_stop_attack(hd); merc_stop_attack(hd);
// Send homunculus_dead to client
sd->homunculus.hp = 0;
clif_hominfo(sd, 0);
merc_hom_delete(hd,1);
clif_emotion(&hd->master->bl, 23) ; //omg clif_emotion(&hd->master->bl, 23) ; //omg
merc_hom_delete(hd,1) ; return 0 ;
} else {
clif_send_homdata(sd,SP_INTIMATE,sd->homunculus.intimacy / 100);
} }
return 0 ;
} else {
clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger);
hd->hungry_timer = add_timer(tick+hd->homunculusDB->hungryDelay,merc_hom_hungry,sd->bl.id,0); //simple Fix albator
return 1 ;
} }
clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger);
hd->hungry_timer = add_timer(tick+hd->homunculusDB->hungryDelay,merc_hom_hungry,sd->bl.id,0); //simple Fix albator
return 0;
} }
int merc_hom_hungry_timer_delete(struct homun_data *hd) int merc_hom_hungry_timer_delete(struct homun_data *hd)

View File

@ -76,3 +76,5 @@ int merc_natural_heal_timer_delete(struct homun_data *hd);
#define merc_stop_walking(hd, type) { if((hd)->ud.walktimer != -1) unit_stop_walking(&(hd)->bl, type); } #define merc_stop_walking(hd, type) { if((hd)->ud.walktimer != -1) unit_stop_walking(&(hd)->bl, type); }
#define merc_stop_attack(hd) { if((hd)->ud.attacktimer != -1) unit_stop_attack(&(hd)->bl); hd->ud.target = 0; } #define merc_stop_attack(hd) { if((hd)->ud.attacktimer != -1) unit_stop_attack(&(hd)->bl); hd->ud.target = 0; }
int read_homunculusdb(void); int read_homunculusdb(void);
int merc_hom_increase_intimacy(struct homun_data * hd, unsigned int value);
int merc_hom_decrease_intimacy(struct homun_data * hd, unsigned int value);

View File

@ -1893,8 +1893,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
pc_getzeny((struct map_session_data *)tmpbl[i], zeny); pc_getzeny((struct map_session_data *)tmpbl[i], zeny);
break ; break ;
case BL_HOMUNCULUS: case BL_HOMUNCULUS:
if(base_exp) if(base_exp) {
merc_hom_gainexp((struct homun_data *)tmpbl[i], base_exp); merc_hom_gainexp((struct homun_data *)tmpbl[i], base_exp);
//homunculus give base_exp to master
pc_gainexp(((struct homun_data *)tmpbl[i])->master, &md->bl, base_exp,0);
}
if(zeny) //homunculus give zeny to master if(zeny) //homunculus give zeny to master
pc_getzeny((struct map_session_data *)((struct homun_data *)tmpbl[i])->master, zeny); pc_getzeny((struct map_session_data *)((struct homun_data *)tmpbl[i])->master, zeny);
break ; break ;

View File

@ -5546,56 +5546,54 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case AM_CALLHOMUN: //[orn] case AM_CALLHOMUN: //[orn]
{ {
int i = 0; int i = 0;
if (sd && (sd->status.hom_id == 0 || sd->homunculus.vaporize == 1)) { if (sd)
if (sd->status.hom_id == 0) { {
i = pc_search_inventory(sd,7142); if ((sd->status.hom_id == 0 || sd->homunculus.vaporize == 1)) {
if(i < 0) { if (sd->status.hom_id == 0) {
clif_skill_fail(sd,skillid,0,0); i = pc_search_inventory(sd,7142);
break ; if(i < 0) {
clif_skill_fail(sd,skillid,0,0);
break ;
}
pc_delitem(sd,i,1,0);
} }
pc_delitem(sd,i,1,0); if (merc_call_homunculus(sd))
break;
} }
if (merc_call_homunculus(sd)) clif_skill_fail(sd,skillid,0,0);
break;
} }
clif_skill_fail(sd,skillid,0,0);
break; break;
} }
case AM_REST: //[orn] case AM_REST: //[orn]
{ {
if (sd && sd->hd && ( sd->hd->battle_status.hp >= (sd->hd->battle_status.max_hp * 80 / 100 ) ) ) { if (sd)
sd->homunculus.vaporize = 1;
clif_hominfo(sd, 0);
merc_hom_delete(sd->hd, 0) ;
} else if ( sd )
{ {
if (sd->hd && ( sd->hd->battle_status.hp >= (sd->hd->battle_status.max_hp * 80 / 100 ) ) ) {
sd->homunculus.vaporize = 1;
clif_hominfo(sd, 0);
merc_hom_delete(sd->hd, 0) ;
}
clif_skill_fail(sd,skillid,0,0); clif_skill_fail(sd,skillid,0,0);
} }
break; break;
} }
case AM_RESURRECTHOMUN: //[orn] case AM_RESURRECTHOMUN: //[orn]
{ {
if ( sd && sd->status.hom_id ) { if (sd)
if( map_flag_gvg(bl->m) ) {
{ //No reviving in WoE grounds! if (sd->status.hom_id && sd->homunculus.hp == 0)
clif_skill_fail(sd,skillid,0,0); {
break; if( map_flag_gvg(bl->m) )
} { //No reviving in WoE grounds!
if ( sd->homunculus.hp == 0 ) {
int per = 10 * skilllv;
if (merc_hom_revive(sd, per) )
{
clif_skill_nodamage(src,&sd->hd->bl,AM_RESURRECTHOMUN,skilllv,1);
} else {
clif_skill_fail(sd,skillid,0,0); clif_skill_fail(sd,skillid,0,0);
break;
} }
} else { if (merc_hom_revive(sd, 10 * skilllv) )
clif_skill_nodamage(src,&sd->hd->bl,AM_RESURRECTHOMUN,skilllv,1);
else
clif_skill_fail(sd,skillid,0,0);
} else
clif_skill_fail(sd,skillid,0,0); clif_skill_fail(sd,skillid,0,0);
}
} }
break; break;
} }