📄 skill.c
字号:
// 僗僫僢僠儍乕
if(sd && sd->status.weapon != 11 && (skill=pc_checkskill(sd,RG_SNATCHER)) > 0)
if((skill*15 + 55) + (skill2 = pc_checkskill(sd,TF_STEAL))*10 > rand()%1000)
if(pc_steal_item(sd,bl))
clif_skill_nodamage(src,bl,TF_STEAL,skill2,1);
break;
case SM_BASH: /* 僶僢僔儏乮媫強峌寕乯 */
if( sd && (skill=pc_checkskill(sd,SM_FATALBLOW))>0 ){
if( rand()%100 < 6*(skilllv-5)*sc_def_vit/100 )
skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(SM_FATALBLOW,skilllv),0);
}
break;
case TF_POISON: /* 僀儞儀僫儉 */
if(rand()%100< (2*skilllv+10)*sc_def_vit/100 )
skill_status_change_start(bl,SC_POISON,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case AS_SONICBLOW: /* 僜僯僢僋僽儘乕 */
if( rand()%100 < (2*skilllv+10)*sc_def_vit/100 )
skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case WZ_FROSTNOVA: /* 僼儘僗僩僲償傽 */
case HT_FREEZINGTRAP: /* 僼儕乕僕儞僌僩儔僢僾 */
rate=skilllv*3+35;
if(rand()%100 < rate*sc_def_mdef/100)
skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case MG_FROSTDIVER: /* 僼儘僗僩僟僀僶乕 */
rate=skilllv*3+35;
if(rand()%100 < rate*sc_def_mdef/100)
skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
else if(sd)
clif_skill_fail(sd,skillid,0,0);
break;
case WZ_STORMGUST: /* 僗僩乕儉僈僗僩 */
{
struct status_change *sc_data = battle_get_sc_data(bl);
if(sc_data) {
sc_data[SC_FREEZE].val3++;
if(sc_data[SC_FREEZE].val3 >= 3)
skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
}
}
break;
case HT_LANDMINE: /* 儔儞僪儅僀儞 */
if( rand()%100 < (5*skilllv+30)*sc_def_vit/100 )
skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case HT_ANKLESNARE: /* 傾儞僋儖僗僱傾 */
{
int sec=skill_get_time2(skillid,skilllv);
if(battle_get_mode(bl)&0x20)
sec = sec/5;
battle_stopwalking(bl,1);
skill_status_change_start(bl,SC_ANKLE,skilllv,0,0,0,sec,0);
}
break;
case HT_SANDMAN: /* 僒儞僪儅儞 */
if( rand()%100 < (5*skilllv+30)*sc_def_int/100 )
skill_status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case TF_SPRINKLESAND: /* 嵒傑偒 */
if( rand()%100 < 15*sc_def_int/100 )
skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case TF_THROWSTONE: /* 愇搳偘 */
if( rand()%100 < 5*sc_def_vit/100 )
skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case CR_HOLYCROSS: /* 儂乕儕乕僋儘僗 */
if( rand()%100 < 3*skilllv*sc_def_int/100 )
skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case CR_GRANDCROSS: /* 僌儔儞僪僋儘僗 */
{
int race = battle_get_race(bl);
if( (battle_check_undead(race,battle_get_elem_type(bl)) || race == 6) && rand()%100 < sc_def_int)
skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
}
break;
case CR_SHIELDCHARGE: /* 僌儔儞僪僋儘僗 */
if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 )
skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case RG_RAID: /* 僒僾儔僀僘傾僞僢僋 */
if( rand()%100 < (10+3*skilllv)*sc_def_vit/100 )
skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
if( rand()%100 < (10+3*skilllv)*sc_def_int/100 )
skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case BA_FROSTJOKE:
if(rand()%100 < (15+5*skilllv)*sc_def_mdef/100)
skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case DC_SCREAM:
if( rand()%100 < (25+5*skilllv)*sc_def_vit/100 )
skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case BD_LULLABY: /* 巕庣塖 */
if( rand()%100 < 15*sc_def_int/100 )
skill_status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
/* MOB偺捛壛岠壥晅偒僗僉儖 */
case NPC_PETRIFYATTACK:
if(rand()%100 < sc_def_mdef)
skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case NPC_POISON:
case NPC_SILENCEATTACK:
case NPC_STUNATTACK:
if(rand()%100 < sc_def_vit)
skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case NPC_CURSEATTACK:
if(rand()%100 < sc_def_luk)
skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case NPC_SLEEPATTACK:
case NPC_BLINDATTACK:
if(rand()%100 < sc_def_int)
skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
break;
case NPC_MENTALBREAKER:
if(dstsd) {
int sp = dstsd->status.max_sp*(10+skilllv)/100;
if(sp < 1) sp = 1;
pc_heal(dstsd,0,-sp);
}
break;
}
if(sd && skillid != MC_CARTREVOLUTION && attack_type&BF_WEAPON){ /* 僇乕僪偵傛傞捛壛岠壥 */
int i;
int sc_def_card=100;
for(i=SC_STONE;i<=SC_BLIND;i++){
if(i==SC_STONE || i==SC_FREEZE)
sc_def_card=sc_def_mdef;
else if(i==SC_STAN || i==SC_POISON || i==SC_SILENCE)
sc_def_card=sc_def_vit;
else if(i==SC_SLEEP || i==SC_CONFUSION || i==SC_BLIND)
sc_def_card=sc_def_int;
else if(i==SC_CURSE)
sc_def_card=sc_def_luk;
if(!sd->state.arrow_atk) {
if(rand()%10000 < (sd->addeff[i-SC_STONE])*sc_def_card/100 ){
if(battle_config.battle_log)
printf("PC %d skill_addeff: card偵傛傞堎忢敪摦 %d %d\n",sd->bl.id,i,sd->addeff[i-SC_STONE]);
skill_status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0);
}
}
else {
if(rand()%10000 < (sd->addeff[i-SC_STONE]+sd->arrow_addeff[i-SC_STONE])*sc_def_card/100 ){
if(battle_config.battle_log)
printf("PC %d skill_addeff: card偵傛傞堎忢敪摦 %d %d\n",sd->bl.id,i,sd->addeff[i-SC_STONE]);
skill_status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0);
}
}
}
}
return 0;
}
/*=========================================================================
僗僉儖峌寕悂偒旘偽偟張棟
-------------------------------------------------------------------------*/
int skill_blown( struct block_list *src, struct block_list *target,int count)
{
int dx=0,dy=0,nx,ny;
int x=target->x,y=target->y;
int ret,prev_state=MS_IDLE;
int moveblock;
struct map_session_data *sd=NULL;
struct mob_data *md=NULL;
struct pet_data *pd=NULL;
if(target->type==BL_PC)
sd=(struct map_session_data *)target;
else if(target->type==BL_MOB)
md=(struct mob_data *)target;
else if(target->type==BL_PET)
pd=(struct pet_data *)target;
else return 0;
if(!(count&0x10000 && (sd||md||pd))){ /* 巜掕側偟側傜埵抲娭學偐傜曽岦傪媮傔傞 */
dx=target->x-src->x; dx=(dx>0)?1:((dx<0)?-1: 0);
dy=target->y-src->y; dy=(dy>0)?1:((dy<0)?-1: 0);
}
if(dx==0 && dy==0){
int dir=battle_get_dir(target);
if(dir>=0 && dir<8){
dx=-dirx[dir];
dy=-diry[dir];
}
}
ret=path_blownpos(target->m,x,y,dx,dy,count&0xffff);
nx=ret>>16;
ny=ret&0xffff;
moveblock=( x/BLOCK_SIZE != nx/BLOCK_SIZE || y/BLOCK_SIZE != ny/BLOCK_SIZE);
if(count&0x20000) {
battle_stopwalking(target,1);
if(sd){
sd->to_x=nx;
sd->to_y=ny;
sd->walktimer = 1;
clif_walkok(sd);
clif_movechar(sd);
}
else if(md) {
md->to_x=nx;
md->to_y=ny;
prev_state = md->state.state;
md->state.state = MS_WALK;
clif_fixmobpos(md);
}
else if(pd) {
pd->to_x=nx;
pd->to_y=ny;
prev_state = pd->state.state;
pd->state.state = MS_WALK;
clif_fixpetpos(pd);
}
}
else
battle_stopwalking(target,2);
dx = nx - x;
dy = ny - y;
if(sd) /* 夋柺奜偵弌偨偺偱徚嫀 */
map_foreachinmovearea(clif_pcoutsight,target->m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,0,sd);
else if(md)
map_foreachinmovearea(clif_moboutsight,target->m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,BL_PC,md);
else if(pd)
map_foreachinmovearea(clif_petoutsight,target->m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,BL_PC,pd);
if(moveblock) map_delblock(target);
target->x=nx;
target->y=ny;
if(moveblock) map_addblock(target);
if(sd) { /* 夋柺撪偵擖偭偰偒偨偺偱昞帵 */
map_foreachinmovearea(clif_pcinsight,target->m,nx-AREA_SIZE,ny-AREA_SIZE,nx+AREA_SIZE,ny+AREA_SIZE,-dx,-dy,0,sd);
if(count&0x20000)
sd->walktimer = -1;
}
else if(md) {
map_foreachinmovearea(clif_mobinsight,target->m,nx-AREA_SIZE,ny-AREA_SIZE,nx+AREA_SIZE,ny+AREA_SIZE,-dx,-dy,BL_PC,md);
if(count&0x20000)
md->state.state = prev_state;
}
else if(pd) {
map_foreachinmovearea(clif_petinsight,target->m,nx-AREA_SIZE,ny-AREA_SIZE,nx+AREA_SIZE,ny+AREA_SIZE,-dx,-dy,BL_PC,pd);
if(count&0x20000)
pd->state.state = prev_state;
}
skill_unit_move(target,gettick(),(count&0xffff)+7); /* 僗僉儖儐僯僢僩偺敾掕 */
return 0;
}
/*
* =========================================================================
* 僗僉儖峌寕岠壥張棟傑偲傔
* flag偺愢柧丅16恑恾
* 00XRTTff
* ff = magic偱寁嶼偵搉偝傟傞乯
* TT = 僷働僢僩偺type晹暘(0偱僨僼僅儖僩乯
* X = 僷働僢僩偺僗僉儖Lv
* R = 梊栺乮skill_area_sub偱巊梡偡傞乯
*-------------------------------------------------------------------------
*/
int skill_attack( int attack_type, struct block_list* src, struct block_list *dsrc,
struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag )
{
struct Damage dmg;
struct status_change *sc_data=battle_get_sc_data(bl);
int type,lv,damage;
rdamage = 0;
if(src == NULL || dsrc == NULL || bl == NULL)
return 0;
if(dsrc->m != bl->m) return 0;
if(src->prev == NULL || dsrc->prev == NULL || bl->prev == NULL)
return 0;
if(src->type == BL_PC && pc_isdead((struct map_session_data *)src))
return 0;
if(dsrc->type == BL_PC && pc_isdead((struct map_session_data *)dsrc))
return 0;
if(bl->type == BL_PC && pc_isdead((struct map_session_data *)bl))
return 0;
if(sc_data && sc_data[SC_HIDING].timer != -1) {
if(skill_get_pl(skillid) != 2)
return 0;
}
if(skillid == WZ_STORMGUST) {
struct status_change *sc_data = battle_get_sc_data(bl);
if(sc_data && sc_data[SC_FREEZE].timer != -1)
return 0;
}
if(skillid == WZ_FROSTNOVA && dsrc->x == bl->x && dsrc->y == bl->y)
return 0;
type=-1;
lv=(flag>>20)&0xf;
dmg=battle_calc_attack(attack_type,src,bl,skillid,skilllv,flag&0xff );
if(attack_type&BF_MAGIC && sc_data && sc_data[SC_MAGICROD].timer != -1 && src == dsrc) {
dmg.damage = dmg.damage2 = 0;
if(bl->type == BL_PC) {
int sp = skill_get_sp(skillid,skilllv);
sp = sp * sc_data[SC_MAGICROD].val2 / 100;
if(skillid == WZ_WATERBALL && skilllv > 1)
sp = sp/((skilllv|1)*(skilllv|1));
if(sp > 0x7fff) sp = 0x7fff;
else if(sp < 1) sp = 1;
if(((struct map_session_data *)bl)->status.sp + sp > ((struct map_session_data *)bl)->status.max_sp) {
sp = ((struct map_session_data *)bl)->status.max_sp - ((struct map_session_data *)bl)->status.sp;
((struct map_session_data *)bl)->status.sp = ((struct map_session_data *)bl)->status.max_sp;
}
else
((struct map_session_data *)bl)->status.sp += sp;
clif_heal(((struct map_session_data *)bl)->fd,SP_SP,sp);
((struct map_session_data *)bl)->canact_tick = tick + skill_delayfix(bl, skill_get_delay(SA_MAGICROD,sc_data[SC_MAGICROD].val1));
}
clif_skill_nodamage(bl,bl,SA_MAGICROD,sc_data[SC_MAGICROD].val1,1);
}
damage = dmg.damage + dmg.damage2;
if(lv==15)lv=-1;
if( flag&0xff00 )
type=(flag&0xff00)>>8;
if(damage <= 0 || damage < dmg.div_)
dmg.blewcount = 0;
if(skillid == CR_GRANDCROSS && src == bl)
dsrc = src;
if(src->type == BL_PC) {
struct map_session_data *sd = (struct map_session_data *)src;
if(skillid == MO_CHAINCOMBO) {
int delay = 300;
if(damage < battle_get_hp(bl)) {
delay = 1000 - 4 * battle_get_agi(src) - 2 * battle_get_dex(src);
if(delay < sd->aspd*2) delay = sd->aspd*2;
if(battle_config.combo_delay_rate != 100)
delay = delay * battle_config.combo_delay_rate /100;
if(pc_checkskill(sd, MO_COMBOFINISH) > 0)
delay += 300;
else
delay = 300;
skill_status_change_start(src,SC_COMBO,MO_CHAINCOMBO,skilllv,0,0,delay,0);
}
sd->attackabletime = sd->canmove_tick = tick + delay;
clif_combo_delay(src,delay);
}
else if(skillid == MO_COMBOFINISH) {
int delay = 300;
if(damage < battle_get_hp(bl)) {
delay = 1000 - 4 * battle_get_agi(src) - 2 * battle_get_dex(src);
if(delay < sd->aspd*2) delay = sd->aspd*2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -