summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-07-18 13:25:21 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-07-18 13:25:21 +0000
commitff6317b65b37c6439076afd810193baf893b3611 (patch)
tree90117e8581813a31fd9ffefa858fc1a0543debe0 /src
parent625630e64fe10dd9d46b87c742efbf47bff497da (diff)
downloadhercules-ff6317b65b37c6439076afd810193baf893b3611.tar.gz
hercules-ff6317b65b37c6439076afd810193baf893b3611.tar.bz2
hercules-ff6317b65b37c6439076afd810193baf893b3611.tar.xz
hercules-ff6317b65b37c6439076afd810193baf893b3611.zip
- 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@7727 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r--src/char_sql/int_homun.c15
-rw-r--r--src/common/mmo.h1
-rw-r--r--src/map/atcommand.c4
-rw-r--r--src/map/battle.c3
-rw-r--r--src/map/clif.c133
-rw-r--r--src/map/map.h13
-rw-r--r--src/map/mercenary.c26
-rw-r--r--src/map/mob.c6
-rw-r--r--src/map/skill.c2
-rw-r--r--src/map/status.c54
-rw-r--r--src/map/status.h5
-rw-r--r--src/map/unit.c17
12 files changed, 132 insertions, 147 deletions
diff --git a/src/char_sql/int_homun.c b/src/char_sql/int_homun.c
index 7023e5f98..9bfe42072 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 a61a2e321..bf33a6d09 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 9a333892b..29b055687 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 361d93ed3..777f75dfc 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 72798922c..81c43cb09 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))
+
+
+ if (skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE+MAX_HOMUNSKILL) {
+ clif_parse_UseSkillToId_homun(sd->hd, sd, tick, skillnum, skilllv, target_id);
return;
+ }
- if (sd->hd && skillnotok_hom(skillnum, sd->hd)) //[orn]
+ 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;
- }
+ return;
+ }
+
+ 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 == 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)
+ if (skillnum >= GD_SKILLBASE) {
+ if (sd->state.gmaster_flag)
skilllv = guild_checkskill(sd->state.gmaster_flag, skillnum);
-
- 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;
- }
- }
+ 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 fec279850..c6a7b168e 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 49ebbcde1..301a28955 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;i<MAX_STATUSCHANGE;i++) {
hd->sc.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 72d0a8aaa..1f70c6e5b 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 6bf357910..5334a328a 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 613471116..41a054f24 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;
-
- merc_hom_calc_skilltree(hd->master); //
-
- status_cpy(&b_status, status);
+ 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);
+
+ 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 2f35a5fbb..65e512ec5 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 9dd7b33fc..bf2091ff6 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);