From 93109355b4f0b7dcbf9aa827716590df9cd3f9cd Mon Sep 17 00:00:00 2001 From: skotlex Date: Fri, 23 Feb 2007 21:55:18 +0000 Subject: - The NK value of the skill_db has been made a hexadecimal value, and expanded to include more information about a skill's damage properties: 0x8 - ignore caster's cards, 0x10 ignore element adjustments, 0x20 ignore target's defense, 0x40 ignore target's flee. - Magic attacks always ignore flee, and misc attacks always ignore defense. - Autoguard will no longer work on skills that don't take in card adjustments - utsusemi & bunsinjyutsu no longer work on skills that don't take in card adjustments. - Corrected damage of the NPC elemental attack skills, Blood Drain and Energy Drain git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9906 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/battle.c | 191 ++++++++++++++----------------------------------------- 1 file changed, 48 insertions(+), 143 deletions(-) (limited to 'src/map/battle.c') diff --git a/src/map/battle.c b/src/map/battle.c index 6acee440e..5582a8f67 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -307,7 +307,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i } if(sc->data[SC_AUTOGUARD].timer != -1 && flag&BF_WEAPON && - skill_num != WS_CARTTERMINATION && // FIXME(?): Quick and dirty check, but HSCR really bypasses Guard [DracoRPG] + !(skill_get_nk(skill_num)&NK_NO_CARDFIX) && rand()%100 < sc->data[SC_AUTOGUARD].val2) { int delay; clif_skill_nodamage(bl,bl,CR_AUTOGUARD,sc->data[SC_AUTOGUARD].val1,1); @@ -363,19 +363,8 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i if ((sc->data[SC_UTSUSEMI].timer != -1 || sc->data[SC_BUNSINJYUTSU].timer != -1) && -// This check used instead, is 'aproximate' to what it can block. - (flag&BF_WEAPON || (flag&(BF_MISC|BF_SHORT)) == (BF_MISC|BF_SHORT)) -/* FIXME: This check is awful, there has to be some kind of logic behind this! - // there is no rule for that, only some exceptions.. which I listed according to many tests and says - && ( - skill_num != ASC_BREAKER && - skill_num != NJ_KUNAI && - skill_num != SN_FALCONASSAULT && - skill_num != MO_BALKYOUNG && - skill_num != HT_BLITZBEAT && - skill_num != NJ_SYURIKEN - ) -*/ + (flag&BF_WEAPON || (flag&(BF_MISC|BF_SHORT)) == (BF_MISC|BF_SHORT)) && + !(skill_get_nk(skill_num)&NK_NO_CARDFIX) ) { if (sc->data[SC_UTSUSEMI].timer != -1) { @@ -831,7 +820,7 @@ static struct Damage battle_calc_weapon_attack( unsigned short skillratio = 100; //Skill dmg modifiers. short skill=0; short s_ele, s_ele_, t_class; - short i; + short i, nk; struct map_session_data *sd, *tsd; struct Damage wd; @@ -851,7 +840,6 @@ static struct Damage battle_calc_weapon_attack( unsigned rh : 1; //Attack considers right hand (wd.damage) unsigned lh : 1; //Attack considers left hand (wd.damage2) unsigned weapon : 1; //It's a weapon attack (consider VVS, and all that) - unsigned cardfix : 1; } flag; memset(&wd,0,sizeof(wd)); @@ -865,7 +853,6 @@ static struct Damage battle_calc_weapon_attack( //Initial flag flag.rh=1; flag.weapon=1; - flag.cardfix=1; flag.infdef=(tstatus->mode&MD_PLANT?1:0); //Initial Values @@ -878,6 +865,9 @@ static struct Damage battle_calc_weapon_attack( wd.blewcount=skill_get_blewcount(skill_num,skill_lv); wd.flag=BF_SHORT|BF_WEAPON|BF_NORMAL; //Initial Flag wd.dmg_lv=ATK_DEF; //This assumption simplifies the assignation later + nk = skill_get_nk(skill_num); + flag.hit = nk&NK_IGNORE_FLEE?1:0; + flag.idef = flag.idef2 = nk&NK_IGNORE_DEF?1:0; if (sc && !sc->count) sc = NULL; //Skip checking as there are no status changes active. @@ -989,6 +979,9 @@ static struct Damage battle_calc_weapon_attack( if (skill_num == GS_GROUNDDRIFT) s_ele = s_ele_ = wflag; //element comes in flag. + if (s_ele != ELE_NEUTRAL && (battle_config.attack_attr_none&src->type)) + nk|=NK_NO_ELEFIX; + if(!skill_num) { //Skills ALWAYS use ONLY your right-hand weapon (tested on Aegis 10.2) if (sd && sd->weapontype1 == 0 && sd->weapontype2 > 0) @@ -1063,26 +1056,6 @@ static struct Damage battle_calc_weapon_attack( case AS_SPLASHER: //Reports say it always hits? if (wflag) //Only if you were the one exploding. break; - case NPC_GUIDEDATTACK: - case RG_BACKSTAP: - case HT_FREEZINGTRAP: - case AM_ACIDTERROR: - case MO_INVESTIGATE: - case MO_EXTREMITYFIST: - case CR_GRANDCROSS: - case NPC_GRANDDARKNESS: - case PA_SACRIFICE: - case TK_COUNTER: - case SG_SUN_WARM: - case SG_MOON_WARM: - case SG_STAR_WARM: - case NPC_BLOODDRAIN: - case NPC_ENERGYDRAIN: - case NPC_MENTALBREAKER: - case GS_GROUNDDRIFT: - case NJ_SYURIKEN: - case NJ_KUNAI: - case NJ_ISSEN: flag.hit = 1; break; case CR_SHIELDBOOMERANG: @@ -1363,11 +1336,6 @@ static struct Damage battle_calc_weapon_attack( case KN_BOWLINGBASH: skillratio+= 40*skill_lv; break; - case KN_AUTOCOUNTER: - case LK_SPIRALPIERCE: - case NPC_CRITICALSLASH: - flag.idef= flag.idef2= 1; - break; case AS_GRIMTOOTH: skillratio += 20*skill_lv; break; @@ -1377,9 +1345,6 @@ static struct Damage battle_calc_weapon_attack( case AS_SONICBLOW: skillratio += -50+5*skill_lv; break; - case AS_VENOMKNIFE: - flag.cardfix = 0; - break; case TF_SPRINKLESAND: skillratio += 30; break; @@ -1402,7 +1367,10 @@ static struct Damage battle_calc_weapon_attack( case NPC_DARKNESSATTACK: case NPC_UNDEADATTACK: case NPC_TELEKINESISATTACK: - skillratio += 25*skill_lv; + skillratio += 100*(skill_lv-1); + break; + case NPC_BLOODDRAIN: + skillratio += 100*skill_lv; break; case RG_BACKSTAP: if(sd && sd->status.weapon == W_BOW && battle_config.backstab_bow_penalty) @@ -1426,17 +1394,11 @@ static struct Damage battle_calc_weapon_attack( case CR_HOLYCROSS: skillratio += 35*skill_lv; break; - case CR_GRANDCROSS: - case NPC_GRANDDARKNESS: - flag.cardfix = 0; - break; case AM_DEMONSTRATION: skillratio += 20*skill_lv; - flag.cardfix = 0; break; case AM_ACIDTERROR: skillratio += 40*skill_lv; - flag.cardfix = 0; break; case MO_FINGEROFFENSIVE: skillratio+= 50 * skill_lv; @@ -1452,7 +1414,6 @@ static struct Damage battle_calc_weapon_attack( if (ratio > 60000) ratio = 60000; //We leave some room here in case skillratio gets further increased. skillratio = (unsigned short)ratio; status_set_sp(src, 0, 0); - flag.idef= flag.idef2= 1; } break; case MO_TRIPLEATTACK: @@ -1488,7 +1449,6 @@ static struct Damage battle_calc_weapon_attack( break; case ASC_METEORASSAULT: skillratio += 40*skill_lv-60; - flag.cardfix = 0; break; case SN_SHARPSHOOTING: skillratio += 50*skill_lv; @@ -1501,16 +1461,13 @@ static struct Damage battle_calc_weapon_attack( if (sd) i += 20*pc_checkskill(sd,AS_POISONREACT); if (wflag>1) i/=wflag; //Splash damage is half. skillratio += i; - flag.cardfix = 0; break; case ASC_BREAKER: skillratio += 100*skill_lv-100; - flag.cardfix = 0; break; case PA_SACRIFICE: //40% less effective on siege maps. [Skotlex] skillratio += 10*skill_lv-10; - flag.idef = flag.idef2 = 1; break; case PA_SHIELDCHAIN: skillratio += 30*skill_lv; @@ -1523,7 +1480,6 @@ static struct Damage battle_calc_weapon_attack( skillratio += sd->cart_weight/i * 80000/sd->cart_max_weight - 100; else if (!sd) skillratio += 80000 / i - 100; - flag.cardfix = 0; break; case TK_DOWNKICK: skillratio += 60 + 20*skill_lv; @@ -1546,19 +1502,16 @@ static struct Damage battle_calc_weapon_attack( skillratio += 50*skill_lv; break; case GS_BULLSEYE: + //Only works well against brute/demihumans non bosses. if((tstatus->race == RC_BRUTE || tstatus->race == RC_DEMIHUMAN) && !(tstatus->mode&MD_BOSS)) - { //Only works well against brute/demihumans non bosses. skillratio += 400; - flag.cardfix = 0; - } break; case GS_TRACKING: skillratio += 100 *(skill_lv+1); break; case GS_PIERCINGSHOT: skillratio += 20*skill_lv; - flag.idef = flag.idef2 = 1; break; case GS_RAPIDSHOWER: skillratio += 10*skill_lv; @@ -1848,7 +1801,7 @@ static struct Damage battle_calc_weapon_attack( if(skill_num==TF_POISON) ATK_ADD(15*skill_lv); - if (s_ele != ELE_NEUTRAL || !(battle_config.attack_attr_none&src->type)) + if (!(nk&NK_NO_ELEFIX)) { //Elemental attribute fix if (wd.damage > 0) { @@ -1869,9 +1822,6 @@ static struct Damage battle_calc_weapon_attack( } } - if ((!flag.rh || !wd.damage) && (!flag.lh || !wd.damage2)) - flag.cardfix = 0; //When the attack does no damage, avoid doing %bonuses - if (sd) { if (skill_num != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus. @@ -1883,14 +1833,15 @@ static struct Damage battle_calc_weapon_attack( } //Card Fix, sd side - if (flag.cardfix) + if ((wd.damage || wd.damage2) && !(nk&NK_NO_CARDFIX)) { short cardfix = 1000, cardfix_ = 1000; short t_race2 = status_get_race2(target); if(sd->state.arrow_atk) { cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->arrow_addrace[tstatus->race])/100; - cardfix=cardfix*(100+sd->right_weapon.addele[tstatus->def_ele]+sd->arrow_addele[tstatus->def_ele])/100; + if (!(nk&NK_NO_ELEFIX)) + cardfix=cardfix*(100+sd->right_weapon.addele[tstatus->def_ele]+sd->arrow_addele[tstatus->def_ele])/100; cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->arrow_addsize[tstatus->size])/100; cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100; cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->arrow_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100; @@ -1898,7 +1849,8 @@ static struct Damage battle_calc_weapon_attack( if(!battle_config.left_cardfix_to_right) { cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100; - cardfix=cardfix*(100+sd->right_weapon.addele[tstatus->def_ele])/100; + if (!(nk&NK_NO_ELEFIX)) + cardfix=cardfix*(100+sd->right_weapon.addele[tstatus->def_ele])/100; cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size])/100; cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100; cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100; @@ -1906,7 +1858,8 @@ static struct Damage battle_calc_weapon_attack( if (flag.lh) { cardfix_=cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100; - cardfix_=cardfix_*(100+sd->left_weapon.addele[tstatus->def_ele])/100; + if (!(nk&NK_NO_ELEFIX)) + cardfix_=cardfix_*(100+sd->left_weapon.addele[tstatus->def_ele])/100; cardfix_=cardfix_*(100+sd->left_weapon.addsize[tstatus->size])/100; cardfix_=cardfix_*(100+sd->left_weapon.addrace2[t_race2])/100; cardfix_=cardfix_*(100+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100; @@ -2142,7 +2095,7 @@ static struct Damage battle_calc_weapon_attack( struct Damage battle_calc_magic_attack( struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag) { - short i; + short i, nk; short s_ele; unsigned short skillratio = 100; //Skill dmg modifiers. @@ -2153,8 +2106,6 @@ struct Damage battle_calc_magic_attack( struct { unsigned imdef : 1; unsigned infdef : 1; - unsigned elefix : 1; - unsigned cardfix : 1; } flag; memset(&ad,0,sizeof(ad)); @@ -2165,10 +2116,6 @@ struct Damage battle_calc_magic_attack( nullpo_info(NLP_MARK); return ad; } - //Initial flag - flag.elefix=1; - flag.cardfix=1; - //Initial Values ad.damage = 1; ad.div_=skill_get_num(skill_num,skill_lv); @@ -2177,7 +2124,9 @@ struct Damage battle_calc_magic_attack( ad.blewcount = skill_get_blewcount(skill_num,skill_lv); ad.flag=BF_MAGIC|BF_SKILL; ad.dmg_lv=ATK_DEF; - + nk = skill_get_nk(skill_num); + flag.imdef = nk&NK_IGNORE_DEF?1:0; + BL_CAST(BL_PC, src, sd); BL_CAST(BL_PC, target, tsd); @@ -2232,28 +2181,6 @@ struct Damage battle_calc_magic_attack( case PR_SANCTUARY: ad.blewcount|=0x10000; ad.dmotion = 0; //No flinch animation. - case AL_HEAL: - case PR_BENEDICTIO: - case WZ_FIREPILLAR: - flag.imdef = 1; - break; - case HW_GRAVITATION: - flag.imdef = 1; - flag.elefix = 0; - break; - case PR_ASPERSIO: - flag.imdef = 1; - case PF_SOULBURN: //Does not ignores mdef - flag.elefix = 0; - flag.cardfix = 0; - break; - case PR_TURNUNDEAD: - flag.imdef = 1; - flag.cardfix = 0; - break; - case NPC_GRANDDARKNESS: - case CR_GRANDCROSS: - flag.cardfix = 0; break; } @@ -2386,6 +2313,7 @@ struct Damage battle_calc_magic_attack( skillratio += 60 + 40*skill_lv; break; case NJ_KAMAITACHI: + case NPC_ENERGYDRAIN: skillratio += 100*skill_lv; break; } @@ -2439,15 +2367,15 @@ struct Damage battle_calc_magic_attack( if(ad.damage<1) ad.damage=1; - if (flag.elefix) + if (!(nk&NK_NO_ELEFIX)) ad.damage=battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv); - if (sd && flag.cardfix) { + if (sd && !(nk&NK_NO_CARDFIX)) { short t_class = status_get_class(target); - short cardfix=100; + short cardfix=1000; cardfix=cardfix*(100+sd->magic_addrace[tstatus->race])/100; - if (flag.elefix) + if (!(nk&NK_NO_ELEFIX)) cardfix=cardfix*(100+sd->magic_addele[tstatus->def_ele])/100; cardfix=cardfix*(100+sd->magic_addsize[tstatus->size])/100; cardfix=cardfix*(100+sd->magic_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100; @@ -2457,17 +2385,17 @@ struct Damage battle_calc_magic_attack( continue; } } - - MATK_RATE(cardfix); + if (cardfix != 1000) + MATK_RATE(cardfix/10); } if (tsd && skill_num != HW_GRAVITATION && skill_num != PF_SOULBURN) { //Card fixes always apply on the target side. [Skotlex] short s_race2=status_get_race2(src); short s_class= status_get_class(src); - short cardfix=100; + short cardfix=1000; - if (flag.elefix) + if (!(nk&NK_NO_ELEFIX)) cardfix=cardfix*(100-tsd->subele[s_ele])/100; cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100; cardfix=cardfix*(100-tsd->subrace2[s_race2])/100; @@ -2487,7 +2415,8 @@ struct Damage battle_calc_magic_attack( cardfix=cardfix*(100-tsd->magic_def_rate)/100; - MATK_RATE(cardfix); + if (cardfix != 1000) + MATK_RATE(cardfix/10); } } @@ -2510,22 +2439,15 @@ struct Damage battle_calc_misc_attack( struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag) { int skill; - short i; + short i, nk; short s_ele; struct map_session_data *sd, *tsd; struct Damage md; //DO NOT CONFUSE with md of mob_data! struct status_data *sstatus = status_get_status_data(src); struct status_data *tstatus = status_get_status_data(target); - struct { - unsigned hit : 1; - unsigned idef : 1; - unsigned elefix : 1; - unsigned cardfix : 1; - } flag; memset(&md,0,sizeof(md)); - memset(&flag,0,sizeof(flag)); if( src == NULL || target == NULL ){ nullpo_info(NLP_MARK); @@ -2540,7 +2462,7 @@ struct Damage battle_calc_misc_attack( md.dmg_lv=ATK_DEF; md.flag=BF_MISC|BF_SKILL; - flag.cardfix = flag.elefix = flag.hit = 1; + nk = skill_get_nk(skill_num); BL_CAST(BL_PC, src, sd); BL_CAST(BL_PC, target, tsd); @@ -2559,24 +2481,6 @@ struct Damage battle_calc_misc_attack( if (s_ele < 0) //Attack that takes weapon's element for misc attacks? Make it neutral [Skotlex] s_ele = ELE_NEUTRAL; - //Misc Settings - switch(skill_num){ - case ASC_BREAKER: - flag.elefix = 0; - break; - case PA_PRESSURE: - case GS_FLING: - case NJ_ZENYNAGE: - case HVAN_EXPLOSION: - case NPC_SELFDESTRUCTION: - case NPC_SMOKING: - flag.elefix = flag.cardfix = 0; - break; - case NPC_DARKBREATH: - flag.hit = 0; - break; - } - //Skill Range Criteria if (battle_config.skillrange_by_distance && (src->type&battle_config.skillrange_by_distance) @@ -2674,11 +2578,12 @@ struct Damage battle_calc_misc_attack( damage_div_fix(md.damage, md.div_); - if (!flag.hit) + if (!(nk&NK_IGNORE_FLEE)) { + i = 0; //Temp for "hit or no hit" struct status_change *sc = status_get_sc(target); if(sc && sc->opt1 && sc->opt1 != OPT1_STONEWAIT) - flag.hit = 1; + i = 1; else { short flee = tstatus->flee, @@ -2707,18 +2612,18 @@ struct Damage battle_calc_misc_attack( hitrate = battle_config.min_hitrate; if(rand()%100 >= hitrate) - flag.hit = 1; + i = 1; } - if (!flag.hit) { + if (!i) { md.damage = 0; md.dmg_lv=ATK_FLEE; } } - if(md.damage && flag.cardfix && tsd){ + if(md.damage && tsd && !(nk&NK_NO_CARDFIX)){ int cardfix = 10000; int race2 = status_get_race2(src); - if (flag.elefix) + if (!(nk&NK_NO_ELEFIX)) cardfix=cardfix*(100-tsd->subele[s_ele])/100; cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100; cardfix=cardfix*(100-tsd->subrace2[race2])/100; @@ -2745,7 +2650,7 @@ struct Damage battle_calc_misc_attack( else if(md.damage && tstatus->mode&MD_PLANT && skill_num != PA_PRESSURE) //Pressure can vaporize plants md.damage = 1; - if(flag.elefix) + if(!(nk&NK_NO_ELEFIX)) md.damage=battle_attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv); md.damage=battle_calc_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag); -- cgit v1.2.3-70-g09d2