- Added mob skill conditions myhpinrate and friendhpinrate for using HP ranges instead of a fixed "less than" condition.
- Added mob_ai condition &16, enables skills that are normally used on 'friends' to also pick up caster as target. - Fixed npc_shopid not being reset to 0 when buying/selling. FIXME: The client sends a packet when you cancel? It is required so that npc_shopid will be cleared and prevent the player from being stuck. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5380 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
d71c3fd5d1
commit
ada437dcaf
@ -59,6 +59,7 @@ monster_max_aspd: 199
|
||||
// 8: If set, when a mob loses track of their target, they stop walking inmediately. Otherwise, they continue
|
||||
// to their last target tile. When set mobs also scatter as soon as they lose their target. Use this mode to
|
||||
// make it much harder to mob-train by hiding and collecting them on a single spot (ie: GrimTooth training)
|
||||
//16: If set, mob skills defined for friends will also trigger on themselves.
|
||||
monster_ai: 0
|
||||
|
||||
// Allow monsters to be aggresive and attack first? (Note 1)
|
||||
|
@ -28,9 +28,13 @@
|
||||
// always unconditional
|
||||
// onspawn when the mob spawns/respawns.
|
||||
// myhpltmaxrate when the mob's hp drops to a certain %
|
||||
// myhpinrate when the mob's hp is in a certain % range ('a condition value'
|
||||
// is the lower cap, while 'a value 1' is the upper cap).
|
||||
// mystatuson If the mob has any abnormalities in status (condition value),
|
||||
// mystatusoff If the mob has ended any abnormalities in status (condition value),
|
||||
// friendhpltmaxrate when the mobs' friend's hp drops to a certain %
|
||||
// friendhpltmaxrate when the mob's friend's hp drops to a certain %
|
||||
// friendhpinrate when the mob's friend's hp is in a certain % range (range
|
||||
// defined the same way as in myhpinrate)
|
||||
// friendstatuson If the friend has any abnormalities in status (condition value),
|
||||
// friendstatusoff If the friend has ended any abnormalities in status (condition value),
|
||||
// attackpcgt Attack PC becomes more than the number of specification
|
||||
|
@ -9805,11 +9805,12 @@ void clif_parse_NpcBuyListSend(int fd,struct map_session_data *sd)
|
||||
n = (RFIFOW(fd,2)-4) /4;
|
||||
item_list = (unsigned short*)RFIFOP(fd,4);
|
||||
|
||||
if (sd->trade_partner != 0)
|
||||
if (sd->trade_partner || !sd->npc_shopid)
|
||||
fail = 1;
|
||||
else
|
||||
fail = npc_buylist(sd,n,item_list);
|
||||
|
||||
sd->npc_shopid = 0; //Clear shop data.
|
||||
WFIFOHEAD(fd,packet_len_table[0xca]);
|
||||
WFIFOW(fd,0)=0xca;
|
||||
WFIFOB(fd,2)=fail;
|
||||
@ -9829,10 +9830,11 @@ void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd)
|
||||
n = (RFIFOW(fd,2)-4) /4;
|
||||
item_list = (unsigned short*)RFIFOP(fd,4);
|
||||
|
||||
if (sd->trade_partner != 0)
|
||||
if (sd->trade_partner || !sd->npc_shopid)
|
||||
fail = 1;
|
||||
else
|
||||
fail = npc_selllist(sd,n,item_list);
|
||||
sd->npc_shopid = 0; //Clear shop data.
|
||||
|
||||
WFIFOHEAD(fd,packet_len_table[0xcb]);
|
||||
WFIFOW(fd,0)=0xcb;
|
||||
|
@ -3585,19 +3585,18 @@ int mobskill_use_pos( struct mob_data *md,
|
||||
* Friendly Mob whose HP is decreasing by a nearby MOB is looked for.
|
||||
*------------------------------------------
|
||||
*/
|
||||
int mob_getfriendhpltmaxrate_sub(struct block_list *bl,va_list ap)
|
||||
int mob_getfriendhprate_sub(struct block_list *bl,va_list ap)
|
||||
{
|
||||
int rate;
|
||||
int min_rate, max_rate,rate;
|
||||
struct block_list **fr;
|
||||
struct mob_data *md;
|
||||
|
||||
nullpo_retr(0, bl);
|
||||
nullpo_retr(0, ap);
|
||||
nullpo_retr(0, md=va_arg(ap,struct mob_data *));
|
||||
rate=va_arg(ap,int);
|
||||
md = va_arg(ap,struct mob_data *);
|
||||
min_rate=va_arg(ap,int);
|
||||
max_rate=va_arg(ap,int);
|
||||
fr=va_arg(ap,struct block_list **);
|
||||
|
||||
if( md->bl.id == bl->id )
|
||||
if( md->bl.id == bl->id && !(battle_config.mob_ai&16))
|
||||
return 0;
|
||||
|
||||
if ((*fr) != NULL) //A friend was already found.
|
||||
@ -3606,11 +3605,13 @@ int mob_getfriendhpltmaxrate_sub(struct block_list *bl,va_list ap)
|
||||
if (battle_check_target(&md->bl,bl,BCT_ENEMY)>0)
|
||||
return 0;
|
||||
|
||||
if (status_get_hp(bl) < status_get_max_hp(bl) * rate / 100)
|
||||
rate = 100*status_get_hp(bl)/status_get_max_hp(bl);
|
||||
|
||||
if (rate >= min_rate && rate <= max_rate)
|
||||
(*fr) = bl;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
struct block_list *mob_getfriendhpltmaxrate(struct mob_data *md,int rate)
|
||||
static struct block_list *mob_getfriendhprate(struct mob_data *md,int min_rate,int max_rate)
|
||||
{
|
||||
struct block_list *fr=NULL;
|
||||
int type = BL_MOB;
|
||||
@ -3620,7 +3621,7 @@ struct block_list *mob_getfriendhpltmaxrate(struct mob_data *md,int rate)
|
||||
if (md->special_state.ai) //Summoned creatures. [Skotlex]
|
||||
type = BL_PC;
|
||||
|
||||
map_foreachinrange(mob_getfriendhpltmaxrate_sub, &md->bl, 8, type,md,rate,&fr);
|
||||
map_foreachinrange(mob_getfriendhprate_sub, &md->bl, 8, type,md,min_rate,max_rate,&fr);
|
||||
return fr;
|
||||
}
|
||||
/*==========================================
|
||||
@ -3652,8 +3653,9 @@ int mob_getfriendstatus_sub(struct block_list *bl,va_list ap)
|
||||
nullpo_retr(0, md=(struct mob_data *)bl);
|
||||
nullpo_retr(0, mmd=va_arg(ap,struct mob_data *));
|
||||
|
||||
if( mmd->bl.id == bl->id )
|
||||
if( mmd->bl.id == bl->id && !(battle_config.mob_ai&16) )
|
||||
return 0;
|
||||
|
||||
if (battle_check_target(&mmd->bl,bl,BCT_ENEMY)>0)
|
||||
return 0;
|
||||
cond1=va_arg(ap,int);
|
||||
@ -3724,10 +3726,13 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event)
|
||||
case MSC_ALWAYS:
|
||||
flag = 1; break;
|
||||
case MSC_MYHPLTMAXRATE: // HP< maxhp%
|
||||
{
|
||||
int max_hp = status_get_max_hp(&md->bl);
|
||||
flag = (md->hp < max_hp * c2 / 100); break;
|
||||
}
|
||||
flag = 100*md->hp/status_get_max_hp(&md->bl);
|
||||
flag = (flag <= c2);
|
||||
break;
|
||||
case MSC_MYHPINRATE:
|
||||
flag = 100*md->hp/status_get_max_hp(&md->bl);
|
||||
flag = (flag >= c2 && flag <= ms[i].val[0]);
|
||||
break;
|
||||
case MSC_MYSTATUSON: // status[num] on
|
||||
case MSC_MYSTATUSOFF: // status[num] off
|
||||
if (!md->sc.count) {
|
||||
@ -3742,7 +3747,9 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event)
|
||||
}
|
||||
flag ^= (ms[i].cond1 == MSC_MYSTATUSOFF); break;
|
||||
case MSC_FRIENDHPLTMAXRATE: // friend HP < maxhp%
|
||||
flag = ((fbl = mob_getfriendhpltmaxrate(md, ms[i].cond2)) != NULL); break;
|
||||
flag = ((fbl = mob_getfriendhprate(md, 0, ms[i].cond2)) != NULL); break;
|
||||
case MSC_FRIENDHPINRATE :
|
||||
flag = ((fbl = mob_getfriendhprate(md, ms[i].cond2, ms[i].val[0])) != NULL); break;
|
||||
case MSC_FRIENDSTATUSON: // friend status[num] on
|
||||
case MSC_FRIENDSTATUSOFF: // friend status[num] off
|
||||
flag = ((fmd = mob_getfriendstatus(md, ms[i].cond1, ms[i].cond2)) != NULL); break;
|
||||
@ -4545,7 +4552,9 @@ static int mob_readskilldb(void)
|
||||
} cond1[] = {
|
||||
{ "always", MSC_ALWAYS },
|
||||
{ "myhpltmaxrate", MSC_MYHPLTMAXRATE },
|
||||
{ "myhpinrate", MSC_MYHPINRATE },
|
||||
{ "friendhpltmaxrate",MSC_FRIENDHPLTMAXRATE },
|
||||
{ "friendhpinrate", MSC_FRIENDHPINRATE },
|
||||
{ "mystatuson", MSC_MYSTATUSON },
|
||||
{ "mystatusoff", MSC_MYSTATUSOFF },
|
||||
{ "friendstatuson", MSC_FRIENDSTATUSON },
|
||||
|
@ -67,7 +67,9 @@ enum {
|
||||
|
||||
MSC_ALWAYS = 0x0000,
|
||||
MSC_MYHPLTMAXRATE,
|
||||
MSC_MYHPINRATE,
|
||||
MSC_FRIENDHPLTMAXRATE,
|
||||
MSC_FRIENDHPINRATE,
|
||||
MSC_MYSTATUSON,
|
||||
MSC_MYSTATUSOFF,
|
||||
MSC_FRIENDSTATUSON,
|
||||
|
@ -1364,7 +1364,8 @@ int status_calc_pc(struct map_session_data* sd,int first)
|
||||
|
||||
if(sd->status.max_hp > battle_config.max_hp)
|
||||
sd->status.max_hp = battle_config.max_hp;
|
||||
if(sd->status.max_hp <= 0) sd->status.max_hp = 1;
|
||||
else if(sd->status.max_hp <= 0)
|
||||
sd->status.max_hp = 1;
|
||||
if(sd->status.hp>sd->status.max_hp)
|
||||
sd->status.hp=sd->status.max_hp;
|
||||
|
||||
@ -1423,9 +1424,10 @@ int status_calc_pc(struct map_session_data* sd,int first)
|
||||
|
||||
if(sd->status.max_sp > battle_config.max_sp)
|
||||
sd->status.max_sp = battle_config.max_sp;
|
||||
else if(sd->status.max_sp <= 0)
|
||||
sd->status.max_sp = 1;
|
||||
if(sd->status.sp>sd->status.max_sp)
|
||||
sd->status.sp=sd->status.max_sp;
|
||||
if(sd->status.max_sp <= 0) sd->status.max_sp = 1;
|
||||
|
||||
if(sd->sc.data[SC_DANCING].timer==-1){
|
||||
// Basic natural SP regeneration value
|
||||
|
Loading…
x
Reference in New Issue
Block a user