From 97b00a11adc3db24728c4a149fa56c86a003071f Mon Sep 17 00:00:00 2001 From: skotlex Date: Tue, 18 Jul 2006 13:25:21 +0000 Subject: [PATCH] - Added a proper check to make aggressive mobs never override homun targets regardless of distance. - Removed a bunch of homun-related variables that are not needed at all. The alive condition is removed, now the code checks for the hp value to know if the homun is alive or not. - Cleaned up a bit the skill-id function, homun skill checks (such as delay and skill-lv learned) should be correct now. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@7727 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 9 +++ src/char_sql/int_homun.c | 15 ++--- src/common/mmo.h | 1 - src/map/atcommand.c | 4 +- src/map/battle.c | 3 +- src/map/clif.c | 141 +++++++++++++++++++++++---------------- src/map/map.h | 13 ---- src/map/mercenary.c | 26 +++----- src/map/mob.c | 6 +- src/map/skill.c | 2 +- src/map/status.c | 50 ++++---------- src/map/status.h | 5 +- src/map/unit.c | 17 ++--- 13 files changed, 143 insertions(+), 149 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 7e5c37d67f..ee970c85a6 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,15 @@ 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/07/18 + * Added a proper check to make aggressive mobs never override homun targets + regardless of distance. [Skotlex] + * Removed a bunch of homun-related variables that are not needed at all. + The alive condition is removed, now the code checks for the hp value to + know if the homun is alive or not. [Skotlex] + * Cleaned up a bit the skill-id function, homun skill checks (such as delay + and skill-lv learned) should be correct now. [Skotlex] + * Added a proper check to make aggressive mobs never override homun targets + regardless of distance. [Skotlex] * Fixed giving the 100% damage bonus when no-splash-targets are found in the blown path to Grandcross instead of Bowling Bash. Bowling Bash damage equation becomes then +50*lv% rather than +40*lv% when there's no diff --git a/src/char_sql/int_homun.c b/src/char_sql/int_homun.c index 7023e5f981..9bfe42072b 100644 --- a/src/char_sql/int_homun.c +++ b/src/char_sql/int_homun.c @@ -123,17 +123,17 @@ int mapif_save_homunculus(int fd, int account_id, struct s_homunculus *hd) ShowInfo("New homunculus name : %s\n",hd->name); sprintf(tmp_sql, "INSERT INTO `homunculus` " - "(`char_id`, `class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `alive`, `rename_flag`, `vaporize`) " + "(`char_id`, `class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) " "VALUES ('%d', '%d', '%s', '%d', '%lu', '%lu', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')", hd->char_id, hd->class_,hd->name,hd->level,hd->exp,hd->intimacy,hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk, - hd->hp,hd->max_hp,hd->sp,hd->max_sp, hd->skillpts, hd->alive, hd->rename_flag, hd->vaporize); + hd->hp,hd->max_hp,hd->sp,hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize); } else { - sprintf(tmp_sql, "UPDATE `homunculus` SET `char_id`='%d', `class`='%d',`name`='%s',`level`='%d',`exp`='%lu',`intimacy`='%lu',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `alive`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'", + sprintf(tmp_sql, "UPDATE `homunculus` SET `char_id`='%d', `class`='%d',`name`='%s',`level`='%d',`exp`='%lu',`intimacy`='%lu',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'", hd->char_id, hd->class_,hd->name,hd->level,hd->exp,hd->intimacy,hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk, - hd->hp,hd->max_hp,hd->sp,hd->max_sp, hd->skillpts, hd->alive, hd->rename_flag, hd->vaporize, hd->hom_id); + hd->hp,hd->max_hp,hd->sp,hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id); } if(mysql_query(&mysql_handle, tmp_sql)){ @@ -159,7 +159,7 @@ int mapif_load_homunculus(int fd){ int i; memset(homun_pt, 0, sizeof(struct s_homunculus)); - sprintf(tmp_sql,"SELECT `homun_id`,`char_id`,`class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`alive`,`rename_flag`, `vaporize` FROM `homunculus` WHERE `homun_id`='%lu'", RFIFOL(fd,6)); + sprintf(tmp_sql,"SELECT `homun_id`,`char_id`,`class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `homunculus` WHERE `homun_id`='%lu'", RFIFOL(fd,6)); if(mysql_query(&mysql_handle, tmp_sql) ) { ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); @@ -189,9 +189,8 @@ int mapif_load_homunculus(int fd){ homun_pt->sp = atoi(sql_row[16]); homun_pt->max_sp = atoi(sql_row[17]); homun_pt->skillpts = atoi(sql_row[18]); - homun_pt->alive = atoi(sql_row[19]); - homun_pt->rename_flag = atoi(sql_row[20]); - homun_pt->vaporize = atoi(sql_row[21]); + homun_pt->rename_flag = atoi(sql_row[19]); + homun_pt->vaporize = atoi(sql_row[20]); } if(homun_pt->hunger < 0) homun_pt->hunger = 0; diff --git a/src/common/mmo.h b/src/common/mmo.h index a61a2e321a..bf33a6d092 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -174,7 +174,6 @@ struct s_homunculus { //[orn] int char_id; short class_; int hp,max_hp,sp,max_sp; - short alive; //albator unsigned long intimacy; //[orn] short hunger; struct skill hskill[MAX_HOMUNSKILL]; //albator diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 9a333892bb..29b055687d 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -9460,7 +9460,7 @@ int atcommand_homlevel( if (!message || !*message) return -1; - if ( sd->status.hom_id == 0 || !sd->homunculus.alive || sd->homunculus.vaporize ) + if ( sd->status.hom_id == 0 || !sd->homunculus.hp || sd->homunculus.vaporize ) return 1 ; level = atoi(message); @@ -9587,7 +9587,7 @@ int atcommand_homtalk( nullpo_retr(-1, sd); - if(!sd->status.hom_id || !sd->hd || !sd->homunculus.alive ) + if(!sd->status.hom_id || !sd->hd || !sd->homunculus.hp) return -1; if (sscanf(message, "%99[^\n]", mes) < 1) diff --git a/src/map/battle.c b/src/map/battle.c index 361d93ed35..777f75dfcd 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2006,7 +2006,8 @@ static struct Damage battle_calc_weapon_attack( if (breakrate) skill_break_equip(src, EQP_WEAPON, breakrate, BCT_SELF); } - if (battle_config.equip_skill_break_rate) + //Cart Termination won't trigger breaking data. Why? No idea, go ask Gravity. + if (battle_config.equip_skill_break_rate && skill_num != WS_CARTTERMINATION) { // Target equipment breaking int breakrate[2] = {0,0}; // weapon = 0, armor = 1 if (sd) { // Break rate from equipment diff --git a/src/map/clif.c b/src/map/clif.c index 72798922ca..81c43cb095 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1466,10 +1466,10 @@ int clif_hominfo(struct map_session_data *sd, int flag) status = &hd->battle_status; memset(buf,0,71); //packet_len_table[0x22e]); WBUFW(buf,0)=0x22e; - memcpy(WBUFP(buf,2),hd->master->homunculus.name,NAME_LENGTH); - WBUFB(buf,26)=hd->master->homunculus.rename_flag * 2; - WBUFW(buf,27)=hd->master->homunculus.level; - WBUFW(buf,29)=hd->master->homunculus.hunger; + memcpy(WBUFP(buf,2),sd->homunculus.name,NAME_LENGTH); + WBUFB(buf,26)=sd->homunculus.rename_flag * 2; + WBUFW(buf,27)=sd->homunculus.level; + WBUFW(buf,29)=sd->homunculus.hunger; WBUFW(buf,31)=(unsigned short) (hd->master->homunculus.intimacy / 100) ; WBUFW(buf,33)=0; // equip id WBUFW(buf,35)=status->rhw.atk2; @@ -1484,10 +1484,10 @@ int clif_hominfo(struct map_session_data *sd, int flag) WBUFW(buf,53)=status->max_hp; WBUFW(buf,55)=status->sp; WBUFW(buf,57)=status->max_sp; - WBUFL(buf,59)=hd->master->homunculus.exp; + WBUFL(buf,59)=sd->homunculus.exp; WBUFL(buf,63)=hd->exp_next; - WBUFW(buf,67)=hd->master->homunculus.skillpts; - WBUFW(buf,69)=hd->attackable; + WBUFW(buf,67)=sd->homunculus.skillpts; + WBUFW(buf,69)=1; //hd->attackable; FIXME: Attackable? When exactly is a homun not attackable? [Skotlex] clif_send(buf,/*packet_len_table[0x22e]*/71,&sd->bl,SELF); return 0; } @@ -9669,6 +9669,32 @@ void clif_parse_SkillUp(int fd,struct map_session_data *sd) pc_skillup(sd,RFIFOW(fd,2)); } +static void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, int skillnum, int skilllv, int target_id) +{ + int lv; + + if (!hd) return; + + if (skillnotok_hom(skillnum, hd)) //[orn] + return; + + if (hd->bl.id != target_id && + skill_get_inf(skillnum)&INF_SELF_SKILL) + target_id = hd->bl.id; //What good is it to mess up the target in self skills? Wished I knew... [Skotlex] + + if (hd->ud.skilltimer != -1) { + if (skillnum != SA_CASTCANCEL) + return; + } + + lv = merc_hom_checkskill(sd, skillnum); + if (skilllv > lv) + skilllv = lv; + + if (skilllv) + unit_skilluse_id(&hd->bl, target_id, skillnum, skilllv); +} + /*========================================== * スキル使用(ID指定) *------------------------------------------ @@ -9690,11 +9716,14 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) { //Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex] sd->idletime = last_tick; - - if (skillnotok(skillnum, sd)) - return; - if (sd->hd && skillnotok_hom(skillnum, sd->hd)) //[orn] + + if (skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE+MAX_HOMUNSKILL) { + clif_parse_UseSkillToId_homun(sd->hd, sd, tick, skillnum, skilllv, target_id); + return; + } + + if (skillnotok(skillnum, sd)) return; if (sd->bl.id != target_id && @@ -9731,55 +9760,55 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) { if (skilllv != sd->skillitemlv) skilllv = sd->skillitemlv; unit_skilluse_id(&sd->bl, target_id, skillnum, skilllv); - } else { - sd->skillitem = sd->skillitemlv = -1; - if (skillnum == MO_EXTREMITYFIST) { - if ((sd->sc.data[SC_COMBO].timer == -1 || - (sd->sc.data[SC_COMBO].val1 != MO_COMBOFINISH && - sd->sc.data[SC_COMBO].val1 != CH_TIGERFIST && - sd->sc.data[SC_COMBO].val1 != CH_CHAINCRUSH))) { - if (!sd->state.skill_flag ) { - sd->state.skill_flag = 1; - clif_skillinfo(sd, MO_EXTREMITYFIST, INF_ATTACK_SKILL, -1); - return; - } else if (sd->bl.id == target_id) { - clif_skillinfo(sd, MO_EXTREMITYFIST, INF_ATTACK_SKILL, -1); - return; - } - } - } - if (skillnum == TK_JUMPKICK) { - if (sd->sc.data[SC_COMBO].timer == -1 || - sd->sc.data[SC_COMBO].val1 != TK_JUMPKICK) { - if (!sd->state.skill_flag ) { - sd->state.skill_flag = 1; - clif_skillinfo(sd, TK_JUMPKICK, INF_ATTACK_SKILL, -1); - return; - } else if (sd->bl.id == target_id) { - clif_skillinfo(sd, TK_JUMPKICK, INF_ATTACK_SKILL, -1); - return; - } - } - } - - if (skillnum >= GD_SKILLBASE && sd->state.gmaster_flag) - skilllv = guild_checkskill(sd->state.gmaster_flag, skillnum); + return; + } - if ( ( skillnum >= HM_SKILLBASE ) && sd->status.hom_id && sd->homunculus.alive && !sd->homunculus.vaporize ) { //[orn] - if ( ( lv = merc_hom_checkskill(sd, skillnum) ) > 0 ) - if (skilllv > lv) - skilllv = lv; - unit_skilluse_id(&sd->hd->bl, target_id, skillnum, skilllv); - } else { - if ((lv = pc_checkskill(sd, skillnum)) > 0) { - if (skilllv > lv) - skilllv = lv; - unit_skilluse_id(&sd->bl, target_id, skillnum, skilllv); - if (sd->state.skill_flag) - sd->state.skill_flag = 0; + sd->skillitem = sd->skillitemlv = -1; + if (skillnum == MO_EXTREMITYFIST) { + if ((sd->sc.data[SC_COMBO].timer == -1 || + (sd->sc.data[SC_COMBO].val1 != MO_COMBOFINISH && + sd->sc.data[SC_COMBO].val1 != CH_TIGERFIST && + sd->sc.data[SC_COMBO].val1 != CH_CHAINCRUSH))) { + if (!sd->state.skill_flag ) { + sd->state.skill_flag = 1; + clif_skillinfo(sd, MO_EXTREMITYFIST, INF_ATTACK_SKILL, -1); + return; + } else if (sd->bl.id == target_id) { + clif_skillinfo(sd, MO_EXTREMITYFIST, INF_ATTACK_SKILL, -1); + return; } } } + if (skillnum == TK_JUMPKICK) { + if (sd->sc.data[SC_COMBO].timer == -1 || + sd->sc.data[SC_COMBO].val1 != TK_JUMPKICK) { + if (!sd->state.skill_flag ) { + sd->state.skill_flag = 1; + clif_skillinfo(sd, TK_JUMPKICK, INF_ATTACK_SKILL, -1); + return; + } else if (sd->bl.id == target_id) { + clif_skillinfo(sd, TK_JUMPKICK, INF_ATTACK_SKILL, -1); + return; + } + } + } + + if (skillnum >= GD_SKILLBASE) { + if (sd->state.gmaster_flag) + skilllv = guild_checkskill(sd->state.gmaster_flag, skillnum); + else + skilllv = 0; + } else { + lv = pc_checkskill(sd, skillnum); + if (skilllv > lv) + skilllv = lv; + } + + if (skilllv) + unit_skilluse_id(&sd->bl, target_id, skillnum, skilllv); + + if (sd->state.skill_flag) + sd->state.skill_flag = 0; } /*========================================== diff --git a/src/map/map.h b/src/map/map.h index fec279850a..c6a7b168ef 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -940,25 +940,12 @@ struct homun_data { int hungry_timer; //[orn] - int target_id,attacked_id; - short attackable; int natural_heal_timer; //[orn] int hp_sub,sp_sub; int inchealhptick,inchealsptick; int nhealhp,nhealsp,nshealhp,nshealsp,nsshealhp,nsshealsp; - short hp_loss_value; - short sp_loss_value; - short hp_loss_type; - short sp_gain_value; - short hp_gain_value; - int hp_loss_tick; - int sp_loss_tick; - int hp_loss_rate; - int sp_loss_rate; - unsigned int canregen_tick; - unsigned short regenhp,regensp; unsigned long exp_next; diff --git a/src/map/mercenary.c b/src/map/mercenary.c index 49ebbcde1a..301a28955f 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -140,7 +140,7 @@ 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) { hd->master->homunculus.intimacy -= 100 ; - hd->master->homunculus.alive = 0 ; + hd->master->homunculus.hp = 0 ; if(hd->master->homunculus.intimacy <= 0) { merc_stop_walking(hd, 1); merc_stop_attack(hd); @@ -161,21 +161,14 @@ int merc_hom_delete(struct homun_data *hd, int flag) // Delete homunculus if ( flag&1 ) { //sabbath intif_homunculus_requestdelete(hd->master->homunculus.hom_id) ; - merc_stop_walking(hd, 1); - merc_stop_attack(hd); clif_emotion(&hd->bl, 28) ; //sob hd->master->status.hom_id = 0; hd->master->homunculus.hom_id = 0; chrif_save(hd->master,0); - } - else { + } else merc_save(hd) ; - } - if ( !unit_free(&hd->bl) ) - return 0 ; - aFree(hd); - - return 1; + + return unit_free(&hd->bl); } int merc_hom_calc_skilltree(struct map_session_data *sd) @@ -818,7 +811,6 @@ int merc_hom_data_init(struct map_session_data *sd) hd->ud.attacktimer=-1; hd->ud.attackabletime=gettick(); hd->target_id = 0 ; - hd->attackable = 1 ; for(i=0;isc.data[i].timer=-1; @@ -864,7 +856,7 @@ int merc_call_homunculus(struct map_session_data *sd) sd->homunculus.vaporize = 0; merc_hom_data_init(sd); - if ( sd->homunculus.alive && sd->hd && sd->bl.prev != NULL) { + if ( sd->homunculus.hp && sd->hd && sd->bl.prev != NULL) { map_addblock(&sd->hd->bl); clif_spawn(&sd->hd->bl); clif_send_homdata(sd,SP_ACK,0); @@ -906,9 +898,9 @@ int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag) if ( flag == 2 ) { sh->hp = 1 ; - sd->homunculus.alive = 1 ; + sd->homunculus.hp = 1 ; } - if(sd->homunculus.alive && sh->vaporize!=1) + if(sd->homunculus.hp && sh->vaporize!=1) { merc_hom_data_init(sd); @@ -949,7 +941,6 @@ int merc_create_homunculus(struct map_session_data *sd, int class_) sd->homunculus.skillpts = 0; sd->homunculus.char_id = sd->status.char_id; sd->homunculus.vaporize = 0; // albator - sd->homunculus.alive = 1 ; sd->homunculus.hp = 10 ; sd->homunculus.sp = 0 ; @@ -980,8 +971,7 @@ int merc_hom_revive(struct map_session_data *sd, int per) { nullpo_retr(0, sd); - sd->homunculus.alive = 1; - merc_hom_data_init(sd); + merc_hom_data_init(sd); if ( sd->hd && sd->bl.prev != NULL) { sd->homunculus.hp = sd->hd->base_status.hp = sd->hd->battle_status.hp = 1 ; diff --git a/src/map/mob.c b/src/map/mob.c index 72d0a8aaad..1f70c6e5be 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -789,8 +789,10 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap) !(status_get_mode(&md->bl)&MD_BOSS)) return 0; //Gangster paradise protection. } - case BL_HOMUNCULUS: //[orn] - case BL_MOB: + default: + if ((*target) && (*target)->type == BL_HOMUNCULUS && bl->type != BL_HOMUNCULUS) + return 0; //For some reason Homun targets are never overriden. + if((dist=distance_bl(&md->bl, bl)) < md->db->range2 && ((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) && battle_check_range(&md->bl,bl,md->db->range2) diff --git a/src/map/skill.c b/src/map/skill.c index 6bf3579106..5334a328aa 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -5615,7 +5615,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_fail(sd,skillid,0,0); break; } - if ( sd->homunculus.alive == 0 ) { + if ( sd->homunculus.hp == 0 ) { int per = 10 * skilllv; if (merc_hom_revive(sd, per) ) diff --git a/src/map/status.c b/src/map/status.c index 613471116b..41a054f24a 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2150,49 +2150,23 @@ int status_calc_homunculus(struct homun_data *hd, int first) memcpy(&b_status, &hd->base_status, sizeof(struct status_data)); status = &hd->base_status; - status->def_ele = b_status.def_ele = hd->homunculusDB->element ; //[orn] - status->ele_lv = b_status.ele_lv = 1 ; //[orn] - status->race = b_status.race = hd->homunculusDB->race ; //[orn] - status->size = b_status.size = hd->homunculusDB->size ; //[orn] - status->rhw.range = b_status.rhw.range = 1 + hd->homunculusDB->size ; //[orn] - status->mode = b_status.mode = MD_CANMOVE|MD_CANATTACK|MD_ASSIST|MD_AGGRESSIVE|MD_CASTSENSOR; //[orn] - status->speed = b_status.speed = DEFAULT_WALK_SPEED; - status->aspd_rate = b_status.aspd_rate = 1000; + status->def_ele = hd->homunculusDB->element ; //[orn] + status->ele_lv = 1 ; //[orn] + status->race = hd->homunculusDB->race ; //[orn] + status->size = hd->homunculusDB->size ; //[orn] + status->rhw.range = 1 + hd->homunculusDB->size ; //[orn] + status->mode = MD_CANMOVE|MD_CANATTACK|MD_ASSIST|MD_AGGRESSIVE|MD_CASTSENSOR; //[orn] + status->speed = DEFAULT_WALK_SPEED; + status->aspd_rate = 1000; - merc_hom_calc_skilltree(hd->master); // + merc_hom_calc_skilltree(hd->master); - status_cpy(&b_status, status); + status_cpy(&hd->battle_status, status); status_calc_misc(status, hd->master->homunculus.level); status_calc_bl(&hd->bl, SCB_ALL); //Status related changes. - if ( (b_status.str != status->str) || - (b_status.agi != status->agi) || - (b_status.vit != status->vit) || - (b_status.int_ != status->int_) || - (b_status.dex != status->dex) || - (b_status.luk != status->luk) || - (b_status.hit != status->hit) || - (b_status.flee != status->flee) || - (b_status.amotion != status->amotion) || - (b_status.rhw.atk != status->rhw.atk) || - (b_status.def != status->def) || - (b_status.rhw.atk2 != status->rhw.atk2) || - (b_status.def2 != status->def2) || - (b_status.flee2 != status->flee2) || - (b_status.cri != status->cri) || - (b_status.matk_max != status->matk_max) || - (b_status.matk_min != status->matk_min) || - (b_status.mdef != status->mdef) || - (b_status.mdef2 != status->mdef2) || - (b_status.rhw.range != status->rhw.range) || - (b_status.max_hp != status->max_hp) || - (b_status.max_sp != status->max_sp) || - (b_status.hp != status->hp) || - (b_status.sp != status->sp) - ) - { - clif_hominfo(hd->master,0) ; - } + if (memcmp(&b_status, status, sizeof(struct status_data))) + clif_hominfo(hd->master,0) ; return 1; } diff --git a/src/map/status.h b/src/map/status.h index 2f35a5fbbe..65e512ec58 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -514,13 +514,16 @@ enum { #define SCB_PC 0x80000000 #define SCB_ALL 0x7FFFFFFF +//Define to determine who gets HP/SP consumed on doing skills/etc. [Skotlex] +#define BL_CONSUME (BL_PC|BL_HOMUNCULUS) + int status_damage(struct block_list *src,struct block_list *target,int hp,int sp, int walkdelay, int flag); //Define for standard HP damage attacks. #define status_fix_damage(src, target, hp, walkdelay) status_damage(src, target, hp, 0, walkdelay, 0) //Define for standard HP/SP damage triggers. #define status_zap(bl, hp, sp) status_damage(NULL, bl, hp, sp, 0, 1) //Define for standard HP/SP skill-related cost triggers (mobs require no HP/SP to use skills) -#define status_charge(bl, hp, sp) ((bl)->type != BL_PC || status_damage(NULL, bl, hp, sp, 0, 3)) +#define status_charge(bl, hp, sp) (!((bl)->type&BL_CONSUME) || status_damage(NULL, bl, hp, sp, 0, 3)) int status_percent_change(struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag); //Easier handling of status_percent_change #define status_percent_heal(bl, hp_rate, sp_rate) status_percent_change(NULL, bl, -(hp_rate), -(sp_rate), 1) diff --git a/src/map/unit.c b/src/map/unit.c index 9dd7b33fca..bf2091ff6f 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -102,7 +102,6 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data) struct block_list *bl; struct map_session_data *sd = NULL; struct mob_data *md = NULL; - struct homun_data *hd = NULL; //[orn] struct unit_data *ud = NULL; bl=map_id2bl(id); @@ -112,8 +111,6 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data) ud = &sd->ud; } else if( BL_CAST( BL_MOB, bl, md ) ) { ud = &md->ud; - } else if( BL_CAST( BL_HOMUNCULUS, bl, hd ) ) { //[orn] - ud = &hd->ud; } else ud = unit_bl2ud(bl); @@ -715,7 +712,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int struct status_data *tstatus; struct status_change *sc; struct map_session_data *sd = NULL; - struct homun_data *hd = NULL; //[orn] struct block_list * target = NULL; unsigned int tick = gettick(); int temp; @@ -726,8 +722,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int if( BL_CAST( BL_PC, src, sd ) ) { ud = &sd->ud; - } else if( BL_CAST( BL_HOMUNCULUS, src, hd ) ) { //[orn] - ud = &hd->ud; } else ud = unit_bl2ud(src); @@ -770,6 +764,15 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int return 0; } break; + //TODO: here we should place and correct skills that should target homun automatically. However some work still needs be done as "dead homuns" are deleted from memory, and as such, you can't really target them. [Skotlex] + case AM_REST: +// case AM_RESURRECTHOMUN: + target = sd->hd; + if (!target) { + clif_skill_fail(sd,skill_num,0,0); + return 0; + } + break; } if (target) target_id = target->id; @@ -1195,7 +1198,6 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t struct status_data *sstatus; struct map_session_data *sd = NULL; struct mob_data *md = NULL; - struct homun_data *hd = NULL; //[orn] int range; if((ud=unit_bl2ud(src))==NULL) @@ -1207,7 +1209,6 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t } BL_CAST( BL_PC , src, sd); BL_CAST( BL_MOB, src, md); - BL_CAST( BL_HOMUNCULUS, src, hd); //[orn] ud->attacktimer=-1; target=map_id2bl(ud->target);