summaryrefslogtreecommitdiff
path: root/src/map/battle.c
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-02-23 21:55:18 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-02-23 21:55:18 +0000
commit93109355b4f0b7dcbf9aa827716590df9cd3f9cd (patch)
tree9b670782315d89cc05b2584b8c439010078eb50d /src/map/battle.c
parenteb0a137041d3a5ee6385762b8374e98b3867d5a0 (diff)
downloadhercules-93109355b4f0b7dcbf9aa827716590df9cd3f9cd.tar.gz
hercules-93109355b4f0b7dcbf9aa827716590df9cd3f9cd.tar.bz2
hercules-93109355b4f0b7dcbf9aa827716590df9cd3f9cd.tar.xz
hercules-93109355b4f0b7dcbf9aa827716590df9cd3f9cd.zip
- 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
Diffstat (limited to 'src/map/battle.c')
-rw-r--r--src/map/battle.c191
1 files changed, 48 insertions, 143 deletions
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);