From 8304213efbff057813e058a588cfac7a8168dca1 Mon Sep 17 00:00:00 2001 From: skotlex Date: Thu, 23 Feb 2006 21:33:35 +0000 Subject: - 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5380 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/clif.c | 6 ++++-- src/map/mob.c | 43 ++++++++++++++++++++++++++----------------- src/map/mob.h | 2 ++ src/map/status.c | 6 ++++-- 4 files changed, 36 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index 9ccb2b2c8..4b2b8e099 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -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; diff --git a/src/map/mob.c b/src/map/mob.c index 48ed37475..a4f61b98c 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -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 }, diff --git a/src/map/mob.h b/src/map/mob.h index 7e011beac..a36aa10a4 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -67,7 +67,9 @@ enum { MSC_ALWAYS = 0x0000, MSC_MYHPLTMAXRATE, + MSC_MYHPINRATE, MSC_FRIENDHPLTMAXRATE, + MSC_FRIENDHPINRATE, MSC_MYSTATUSON, MSC_MYSTATUSOFF, MSC_FRIENDSTATUSON, diff --git a/src/map/status.c b/src/map/status.c index bf2f6024e..13fec7709 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -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 -- cgit v1.2.3-70-g09d2