- 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
This commit is contained in:
parent
4cb1768c78
commit
97b00a11ad
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
141
src/map/clif.c
141
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);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* ƒXƒLƒ‹Žg—p<EFBFBD>iIDŽw’è<EFBFBD>j
|
||||
*------------------------------------------
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
|
@ -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;
|
||||
|
@ -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 ;
|
||||
|
@ -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)
|
||||
|
@ -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) )
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user