diff options
Diffstat (limited to 'src/map/battle.c')
-rw-r--r-- | src/map/battle.c | 204 |
1 files changed, 176 insertions, 28 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index b0e42a7c7..f338a50bb 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -361,7 +361,26 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag clif_skill_nodamage(bl, bl, LK_PARRYING, sce->val1,1); return 0; } - + + if((sce=sc->data[SC_MILLENNIUMSHIELD]) && damage > 0) { + if(sce->val2 > 0) + { + sce->val3 -= damage; + if( sce->val3 <= 0 ) + { // Reduce remaining shields and create new one. + sc_start(bl,SC_STUN,15,0,1000); + sce->val3 = 1000; + sce->val2--; + if( sd ) + clif_millenniumshield(sd,sce->val2); + } + + damage = 0; // Nullify damage even if shield is destroyed. + } + if(sce->val2 <= 0) + status_change_end(bl, SC_MILLENNIUMSHIELD, INVALID_TIMER); + } + if(sc->data[SC_DODGE] && !sc->opt1 && (flag&BF_LONG || sc->data[SC_SPURT]) && rand()%100 < 20) { @@ -415,7 +434,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag } //Finally damage reductions.... - if( sc->data[SC_ASSUMPTIO] ) + if( sc->data[SC_ASSUMPTIO] && skill_num != RK_DRAGONBREATH ) { if( map_flag_vs(bl->m) ) damage = damage*2/3; //Receive 66% damage @@ -428,10 +447,11 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag damage=damage*(100-sc->data[SC_DEFENDER]->val2)/100; if(sc->data[SC_ADJUSTMENT] && - (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON)) + (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON) && + skill_num != RK_DRAGONBREATH) damage -= 20*damage/100; - if(sc->data[SC_FOGWALL]) { + if(sc->data[SC_FOGWALL] && skill_num != RK_DRAGONBREATH) { if(flag&BF_SKILL) //25% reduction damage -= 25*damage/100; else if ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON)) @@ -493,7 +513,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag //Finally Kyrie because it may, or not, reduce damage to 0. if((sce = sc->data[SC_KYRIE]) && damage > 0){ sce->val2-=damage; - if(flag&BF_WEAPON || skill_num == TF_THROWSTONE){ + if(flag&BF_WEAPON || skill_num == TF_THROWSTONE || skill_num == RK_DRAGONBREATH){ if(sce->val2>=0) damage=0; else @@ -503,6 +523,13 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag status_change_end(bl, SC_KYRIE, INVALID_TIMER); } + if((sce = sc->data[SC_STONEHARDSKIN]) && damage > 0) + { + sce->val2-=damage; // Reduce Stone Skin's HP by damage taken. + if( sce->val2 <= 0 ) + status_change_end(bl, SC_STONEHARDSKIN, INVALID_TIMER); + } + if (!damage) return 0; //Probably not the most correct place, but it'll do here @@ -601,6 +628,7 @@ int battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int dam case PA_PRESSURE: case HW_GRAVITATION: case NJ_ZENYNAGE: + case RK_DRAGONBREATH: break; default: if( flag&BF_SKILL ) @@ -662,6 +690,7 @@ int battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int dama case PA_PRESSURE: case HW_GRAVITATION: case NJ_ZENYNAGE: + case RK_DRAGONBREATH: break; default: if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex] @@ -743,10 +772,13 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int case W_1HSPEAR: case W_2HSPEAR: if((skill = pc_checkskill(sd,KN_SPEARMASTERY)) > 0) { - if(!pc_isriding(sd)) + if(!pc_isriding(sd) && !pc_isdragon(sd)) damage += (skill * 4); else damage += (skill * 5); + // increase damage by level of KN_SPEARMASTERY * 10 + if (pc_checkskill(sd,RK_DRAGONTRAINING) > 0) + damage += (skill * 10); } break; case W_1HAXE: @@ -990,7 +1022,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo wd.type=0; //Normal attack wd.div_=skill_num?skill_get_num(skill_num,skill_lv):1; wd.amotion=(skill_num && skill_get_inf(skill_num)&INF_GROUND_SKILL)?0:sstatus->amotion; //Amotion should be 0 for ground skills. - if(skill_num == KN_AUTOCOUNTER) + if(skill_num == KN_AUTOCOUNTER || skill_num == RK_DEATHBOUND) wd.amotion >>= 1; wd.dmotion=tstatus->dmotion; wd.blewcount=skill_get_blewcount(skill_num,skill_lv); @@ -1063,6 +1095,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo break; case KN_AUTOCOUNTER: + case RK_DEATHBOUND: wd.flag=(wd.flag&~BF_SKILLMASK)|BF_NORMAL; break; @@ -1403,6 +1436,15 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if( (i = party_foreachsamemap(party_sub_count, sd, 0)) > 1 ) // exclude the player himself [Inkfish] ATK_ADDRATE(2*skill*i); } + if(sd->status.party_id && sc && sc->data[SC_FIGHTINGSPIRIT]) + { + i = party_foreachsamemap(party_sub_count, sd, 0); + if( (sc->data[SC_FIGHTINGSPIRIT]->val2) > 0){ + ATK_ADDRATE(7*i); //Caster gets full effect. + }else{ + ATK_ADDRATE(7*i/4); //Party members get 1/4. + } + } } break; } //End default case @@ -1725,6 +1767,62 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo case NPC_VAMPIRE_GIFT: skillratio += ((skill_lv-1)%5+1)*100; break; + case RK_SONICWAVE: + skillratio += ((skill_lv + 5) * 100) * (1 + (status_get_lv(src) -100) / 200); + break; + case RK_HUNDREDSPEAR: + { + int weight = 1, dmg = 0; + if (sd) { + short index = sd->equip_index[EQI_HAND_R]; + + if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON) + weight = sd->inventory_data[index]->weight; //80% of weight + } + + dmg = (600 + (skill_lv * 80) + (1000 - (weight>1000?1000:weight)) * ((1 + status_get_lv(src) - 100) / 200)); + + if(sd) // Add clashing spiral bonus damage (Skill level * 50% damage) + dmg += pc_checkskill(sd,LK_SPIRALPIERCE) * (dmg * 50 /100); + + skillratio = dmg; + break; + } + case RK_WINDCUTTER: + skillratio += ((skill_lv + 2) * 50) * status_get_lv(src) / 100; + break; + case RK_IGNITIONBREAK: + { + int dmg = 300; // Base maximum damage at less than 3 cells. + i = distance_bl(src,target); + if( i > 7 ) + dmg -= 100; // Greather than 7 cells. (200 damage) + else if( i > 3 ) + dmg -= 50; // Greater than 3 cells, less than 7. (250 damage) + + dmg = (dmg * skill_lv) * (1+ (status_get_lv(src) - 100) / 120); + + // Elemental check, +100% damage if your element is fire. + if( sstatus->rhw.ele == ELE_FIRE ) + dmg += skill_lv * 100 / 100; + + skillratio = dmg; + break; + } + case RK_CRUSHSTRIKE: + if(sd) + { + short index = sd->equip_index[EQI_HAND_R]; + if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON ) + skillratio = (sd->inventory_data[index]->wlv * (sd->status.inventory[index].refine + 6) * 100) + sd->inventory_data[index]->atk + sd->inventory_data[index]->weight; + } + break; + case RK_STORMBLAST: + skillratio = ((sd?pc_checkskill(sd,RK_RUNEMASTERY):1) + (sstatus->int_ / 8)) * 100; + break; + case RK_PHANTOMTHRUST: + skillratio = ((skill_lv * 50) + (sd?pc_checkskill(sd,KN_SPEARMASTERY):0) * 10) * status_get_lv(src) / 150; + break; case AB_DUPLELIGHT_MELEE: skillratio += 10 * skill_lv; break; @@ -2302,18 +2400,50 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo wd.damage += md.damage; } - //SG_FUSION hp penalty [Komurka] - if (sc && sc->data[SC_FUSION]) - { - int hp= sstatus->max_hp; - if (sd && tsd) { - hp = 8*hp/100; - if (100*sstatus->hp <= 20*sstatus->max_hp) - hp = sstatus->hp; - } else - hp = 2*hp/100; //2% hp loss per hit - status_zap(src, hp, 0); - } + if ( sc ) + { // I don't see the point in repeating the SC check now that there are more things that use it. [L0ne_W0lf] + if (sc->data[SC_FUSION]) + { //SG_FUSION hp penalty [Komurka] + int hp= sstatus->max_hp; + if (sd && tsd) { + hp = 8*hp/100; + if (100*sstatus->hp <= 20*sstatus->max_hp) + hp = sstatus->hp; + } else + hp = 2*hp/100; //2% hp loss per hit + status_zap(src, hp, 0); + } + + if(sc->data[SC_ENCHANTBLADE] && !skill_num && wd.flag&BF_SHORT ) + { + if (tsc && tsc->data[SC_SAFETYWALL]) + ; // Although this is suposed to be considered a magic atttack, Safety Wall still blocks it? May be impemented wrong. + else + { + struct Damage ebd = battle_calc_attack(BF_MAGIC,src,target,RK_ENCHANTBLADE,sc->data[SC_ENCHANTBLADE]->val1,wd.flag); + wd.damage += (sc->data[SC_ENCHANTBLADE]->val1 * 20 + 100) * (status_get_lv(src) / 150) + sstatus->int_ + ebd.damage; + } + } + + if(sc->data[SC_GIANTGROWTH] && !skill_num ) + { + int rate = battle_config.equip_natural_break_rate; + rate += 10; + skill_break_equip(src, EQP_WEAPON, rate, BCT_SELF); + if( rand() % 100 <= 10 ) + ATK_RATE(300); + } + + if(sc->data[SC_STONEHARDSKIN] && !skill_num) + { // SC_STRIPWEAPON will reduce damage by 25% so piggyback off that since there is no offensive status for this. + int rate = battle_config.equip_natural_break_rate; + rate += 300; //chance to break gear, or reduce attack by 25% in hte case of monsters. + if( sd ) + skill_break_equip(src,EQP_WEAPON,rate,BCT_ENEMY); + if (!sd && !(status_get_mode(src)&MD_BOSS)) + status_change_start(src,SC_STRIPWEAPON,rate,0,0,0,0,10000,0); + } + } return wd; } @@ -2526,17 +2656,13 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list skillratio += 100 +100*skill_lv +100*(skill_lv/2); break; case AB_JUDEX: - skillratio += ((skill_lv < 5)?180 + 20 * skill_lv:300); // Possible RE-Formula - if( status_get_lv(src) >= 100 ) - skillratio = skillratio * status_get_lv(src) / 100; + skillratio += ((skill_lv * 20) + 300) * status_get_lv(src) / 100; break; case AB_ADORAMUS: - skillratio += 100 * (skill_lv + 5); - if( status_get_lv(src) >= 100 ) - skillratio = skillratio * status_get_lv(src) / 100; + skillratio += ((skill_lv * 100) + 500) * status_get_lv(src) / 100; break; case AB_DUPLELIGHT_MAGIC: - skillratio += 100 + 20 * skill_lv; + skillratio = 200 + 20 * skill_lv; break; } @@ -2830,6 +2956,8 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * case NPC_EVILLAND: md.damage = skill_calc_heal(src,target,skill_num,skill_lv,false); break; + case RK_DRAGONBREATH: + md.damage = (sstatus->hp / 50 + sstatus->max_sp / 4) * (skill_lv * status_get_lv(src)/150) * (95 + 5 * (sd?pc_checkskill(sd,RK_DRAGONTRAINING):10)) / 100; } if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets @@ -3198,7 +3326,19 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t skill_addtimerskill(src,tick+status_get_adelay(src) / 2,target->id,0,0,AB_DUPLELIGHT_MAGIC,skilllv,BF_MAGIC,flag); } - rdamage = battle_calc_return_damage(target, damage, wd.flag); + if(tsc && tsc->data[SC_DEATHBOUND] && !is_boss(src) && map_check_dir(map_calc_dir(src,target->x,target->y),unit_getdir(target))) + { + int skilllv = tsc->data[SC_DEATHBOUND]->val1; + clif_skill_damage(src,src, tick, 0, 0, 0, 0, RK_DEATHBOUND,-1, 1); + rdamage = wd.damage * ((500 + 100*skilllv) / 100); + wd.damage = rdamage * 30 / 100; + status_zap(target, wd.damage, 0); + skill_blown(src, src, skill_get_blewcount(RK_DEATHBOUND,skilllv), unit_getdir(src), 0); + status_change_end(target,SC_DEATHBOUND,INVALID_TIMER); + } + else + rdamage = battle_calc_return_damage(target, damage, wd.flag); + if( rdamage > 0 ) { rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0); @@ -3259,6 +3399,11 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t } } } + if (sc && sc->data[SC_CRUSHSTRIKE]) + { + skill_castend_damage_id(src, target, RK_CRUSHSTRIKE, 1, tick, flag); + status_change_end(src,SC_CRUSHSTRIKE, INVALID_TIMER); + } if (sd) { if (wd.flag & BF_WEAPON && src != target && damage > 0) { if (battle_config.left_cardfix_to_right) @@ -4055,10 +4200,13 @@ static const struct _battle_data { { "bg_magic_attack_damage_rate", &battle_config.bg_magic_damage_rate, 60, 0, INT_MAX, }, { "bg_misc_attack_damage_rate", &battle_config.bg_misc_damage_rate, 60, 0, INT_MAX, }, { "bg_flee_penalty", &battle_config.bg_flee_penalty, 20, 0, INT_MAX, }, -//MVP Decrease AGI +// MVP Decrease AGI { "max_decagi_lv", &battle_config.max_decagi_lv, 11, 1, INT_MAX, }, { "max_decagi_dur", &battle_config.max_decagi_dur, 120000, 1, INT_MAX, }, { "max_decagi", &battle_config.max_decagi, 50, 0, INT_MAX, }, +// Third jobs + { "rune_block_by_skill", &battle_config.rune_block_by_skill, 1, 0, 1, }, + { "rune_block_by_status", &battle_config.rune_block_by_status, 0, 0, 1, }, }; |