diff options
Diffstat (limited to 'src/map/battle.c')
-rw-r--r-- | src/map/battle.c | 781 |
1 files changed, 579 insertions, 202 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index f338a50bb..8b0aa22fb 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -118,7 +118,7 @@ static int battle_getenemy_sub(struct block_list *bl, va_list ap) if (bl->id == target->id) return 0; - if (*c >= 24) + if (*c >= 23) return 0; if (status_isdead(bl)) return 0; @@ -136,8 +136,47 @@ struct block_list* battle_getenemy(struct block_list *target, int type, int rang int c = 0; memset(bl_list, 0, sizeof(bl_list)); map_foreachinrange(battle_getenemy_sub, target, range, type, bl_list, &c, target); - if (c == 0 || c > 24) + if (c == 0 ) return NULL; + if( c >= 24 ) + c = 23; + return bl_list[rand()%c]; +} +static int battle_getenemyarea_sub(struct block_list *bl, va_list ap) +{ + struct block_list **bl_list, *src; + int *c, ignore_id; + + bl_list = va_arg(ap, struct block_list **); + c = va_arg(ap, int *); + src = va_arg(ap, struct block_list *); + ignore_id = va_arg(ap, int); + + if( bl->id == src->id || bl->id == ignore_id ) + return 0; // Ignores Caster and a possible pre-target + if( *c >= 23 ) + return 0; + if( status_isdead(bl) ) + return 0; + if( battle_check_target(src, bl, BCT_ENEMY) > 0 ) + { // Is Enemy!... + bl_list[(*c)++] = bl; + return 1; + } + return 0; +} + +// Pick a random enemy +struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int range, int type, int ignore_id) +{ + struct block_list *bl_list[24]; + int c = 0; + memset(bl_list, 0, sizeof(bl_list)); + map_foreachinarea(battle_getenemyarea_sub, src->m, x - range, y - range, x + range, y + range, type, bl_list, &c, src, ignore_id); + if( c == 0 ) + return NULL; + if( c >= 24 ) + c = 23; return bl_list[rand()%c]; } @@ -212,7 +251,6 @@ int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, return 0; } - int battle_attr_ratio(int atk_elem,int def_type, int def_lv) { @@ -265,9 +303,6 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag if( tsc->data[SC_SPIDERWEB]->val2 == 0 ) status_change_end(target, SC_SPIDERWEB, INVALID_TIMER); } - if( atk_elem == ELE_HOLY && tsc && tsc->count && tsc->data[SC_ORATIO] ) - ratio += tsc->data[SC_ORATIO]->val2; - return damage*ratio/100; } @@ -319,6 +354,20 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag d->dmg_lv = ATK_BLOCK; return 0; } + if( sc->data[SC_WHITEIMPRISON] && skill_num != HW_GRAVITATION && skill_num != PA_PRESSURE ) { // Gravitation and Pressure do damage without removing the effect + if( skill_num == MG_NAPALMBEAT || + skill_num == MG_SOULSTRIKE || + skill_num == WL_SOULEXPANSION || + (skill_num && skill_get_ele(skill_num, skill_lv) == ELE_GHOST) || + (!skill_num && (status_get_status_data(src))->rhw.ele == ELE_GHOST) + ) + status_change_end(bl,SC_WHITEIMPRISON,-1); // Those skills do damage and removes effect + else + { + d->dmg_lv = ATK_BLOCK; + return 0; + } + } if( sc->data[SC_SAFETYWALL] && (flag&(BF_SHORT|BF_MAGIC))==BF_SHORT ) { @@ -337,7 +386,13 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag d->dmg_lv = ATK_BLOCK; return 0; } - + if( sc->data[SC_WEAPONBLOCKING] && flag&(BF_SHORT|BF_WEAPON) && rand()%100 < sc->data[SC_WEAPONBLOCKING]->val2 ) + { + clif_skill_nodamage(bl,src,GC_WEAPONBLOCKING,1,1); + d->dmg_lv = ATK_NONE; + sc_start2(bl,SC_COMBO,100,GC_WEAPONBLOCKING,src->id,2000); + return 0; + } if( (sce=sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON && !(skill_get_nk(skill_num)&NK_NO_CARDFIX_ATK) && rand()%100 < sce->val2 ) { int delay; @@ -361,26 +416,7 @@ 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) { @@ -434,7 +470,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag } //Finally damage reductions.... - if( sc->data[SC_ASSUMPTIO] && skill_num != RK_DRAGONBREATH ) + if( sc->data[SC_ASSUMPTIO] ) { if( map_flag_vs(bl->m) ) damage = damage*2/3; //Receive 66% damage @@ -447,11 +483,10 @@ 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) && - skill_num != RK_DRAGONBREATH) + (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON)) damage -= 20*damage/100; - if(sc->data[SC_FOGWALL] && skill_num != RK_DRAGONBREATH) { + if(sc->data[SC_FOGWALL]) { if(flag&BF_SKILL) //25% reduction damage -= 25*damage/100; else if ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON)) @@ -510,10 +545,18 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag status_change_end(bl, SC_REJECTSWORD, INVALID_TIMER); } + //Finally added to remove the status of immobile when aimedbolt is used. [Jobbie] + if( skill_num == RA_AIMEDBOLT && (sc->data[SC_BITE] || sc->data[SC_ANKLE] || sc->data[SC_ELECTRICSHOCKER]) ) + { + status_change_end(bl, SC_BITE, -1); + status_change_end(bl, SC_ANKLE, -1); + status_change_end(bl, SC_ELECTRICSHOCKER, -1); + } + //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 || skill_num == RK_DRAGONBREATH){ + if(flag&BF_WEAPON || skill_num == TF_THROWSTONE){ if(sce->val2>=0) damage=0; else @@ -523,13 +566,6 @@ 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 @@ -569,9 +605,11 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag break; } } + if( sc->data[SC_POISONINGWEAPON] && skill_num != GC_VENOMPRESSURE && (flag&BF_WEAPON) && damage > 0 && rand()%100 < sc->data[SC_POISONINGWEAPON]->val3 ) + sc_start(bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill_get_time2(GC_POISONINGWEAPON,sc->data[SC_POISONINGWEAPON]->val1)); } - if (battle_config.pk_mode && sd && bl->type == BL_PC && damage) + if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && !map_flag_gvg(sd->bl.m)) { if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex] if (flag&BF_WEAPON) @@ -628,7 +666,6 @@ 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 ) @@ -690,9 +727,13 @@ 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: + /* Uncomment if you want god-mode Emperiums at 100 defense. [Kisuka] + if (md && md->guardian_data) { + damage -= damage * (md->guardian_data->castle->defense/100) * battle_config.castle_defense_rate/100; + } + */ if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex] if (flag&BF_WEAPON) damage = damage * battle_config.gvg_weapon_damage_rate/100; @@ -747,6 +788,12 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int (battle_check_undead(status->race,status->def_ele) || status->race==RC_DEMON) ) damage += (skill*(int)(3+(sd->status.base_level+1)*0.05)); // submitted by orn //damage += (skill * 3); + if( (skill = pc_checkskill(sd, RA_RANGERMAIN)) > 0 && (status->race == RC_BRUTE || status->race == RC_PLANT || status->race == RC_FISH) ) + damage += (skill * 5); + if( (skill = pc_checkskill(sd,NC_RESEARCHFE)) > 0 && (status->def_ele == ELE_FIRE || status->def_ele == ELE_EARTH) ) + damage += (skill * 10); + if( (sd->sc.option&OPTION_MADOGEAR) ) + damage += 20 + 20 * pc_checkskill(sd, NC_MADOLICENCE); if((skill = pc_checkskill(sd,HT_BEASTBANE)) > 0 && (status->race==RC_BRUTE || status->race==RC_INSECT) ) { damage += (skill * 4); @@ -772,24 +819,25 @@ 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) && !pc_isdragon(sd)) + if(!pc_isriding(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: case W_2HAXE: if((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0) damage += (skill * 3); + if((skill = pc_checkskill(sd,NC_TRAININGAXE)) > 0) + damage += (skill * 5); break; case W_MACE: case W_2HMACE: if((skill = pc_checkskill(sd,PR_MACEMASTERY)) > 0) damage += (skill * 3); + if((skill = pc_checkskill(sd,NC_TRAININGAXE)) > 0) + damage += (skill * 5); break; case W_FIST: if((skill = pc_checkskill(sd,TK_RUN)) > 0) @@ -1022,7 +1070,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 || skill_num == RK_DEATHBOUND) + if(skill_num == KN_AUTOCOUNTER) wd.amotion >>= 1; wd.dmotion=tstatus->dmotion; wd.blewcount=skill_get_blewcount(skill_num,skill_lv); @@ -1095,7 +1143,6 @@ 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; @@ -1222,7 +1269,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if (flag.cri) { wd.type = 0x0a; - flag.hit = 1; + flag.idef = flag.idef2 = flag.hit = 1; } else { //Check for Perfect Hit if(sd && sd->perfect_hit > 0 && rand()%100 < sd->perfect_hit) flag.hit = 1; @@ -1309,6 +1356,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if(sd && pc_checkskill(sd,AS_SONICACCEL)>0) hitrate += hitrate * 50 / 100; break; + case GC_VENOMPRESSURE: + hitrate += 10 + 4 * skill_lv; + break; } // Weaponry Research hidden bonus @@ -1436,15 +1486,6 @@ 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 @@ -1767,65 +1808,160 @@ 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); + case RK_SONICWAVE: { + int level = status_get_lv(src); + skillratio += 400 + 100 * skill_lv; + if( level > 100 ) + skillratio += skillratio * (level - 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_HUNDREDSPEAR: { + int level = status_get_lv(src); + skillratio += 500 + 40 * skill_lv; + if( level > 100 ) + skillratio += skillratio * (level - 100) / 200; } - 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. + case RK_WINDCUTTER: { + int level = status_get_lv(src); + skillratio += 50 * skill_lv; + if( level > 100 ) + skillratio += skillratio * (level - 50) / 200; + } + break; + case RK_IGNITIONBREAK: { + int level = status_get_lv(src); 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; + if( i < 2 ) + skillratio = 200 + 200 * skill_lv; + else if( i < 4 ) + skillratio = 100 + 200 * skill_lv; + else + skillratio = 100 + 100 * skill_lv; + if( level > 100 ) + skillratio += skillratio * (level - 100) / 200; + if( sstatus->rhw.ele == ELE_FIRE ) + skillratio += skillratio / 2; } + 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; + 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 = sstatus->rhw.atk + 100 * sd->inventory_data[index]->wlv * (sd->status.inventory[index].refine + 6); + } + break; case RK_STORMBLAST: - skillratio = ((sd?pc_checkskill(sd,RK_RUNEMASTERY):1) + (sstatus->int_ / 8)) * 100; + skillratio = 100 * (sd ? pc_checkskill(sd,RK_RUNEMASTERY) : 1) + 100 * (sstatus->int_ / 4); break; case RK_PHANTOMTHRUST: - skillratio = ((skill_lv * 50) + (sd?pc_checkskill(sd,KN_SPEARMASTERY):0) * 10) * status_get_lv(src) / 150; + skillratio = 50 * skill_lv + 10 * ( sd ? pc_checkskill(sd,KN_SPEARMASTERY) : 10); + //if( s_level > 100 ) skillratio += skillratio * s_level / 150; // Base level bonus. This is official, but is disabled until I can confirm something with was changed or not. [Rytech] + //if( s_level > 100 ) skillratio += skillratio * (s_level - 100) / 200; // Base level bonus. + break; + /** + * GC Guilotine Cross + **/ + case GC_CROSSIMPACT: + skillratio += 1050 + 50 * skill_lv; break; + case GC_PHANTOMMENACE: + skillratio += 200; + break; + case GC_COUNTERSLASH: + skillratio += 200 + (100 * skill_lv) + sstatus->agi; + break; + case GC_ROLLINGCUTTER: + skillratio += 20 * skill_lv; + break; + case GC_CROSSRIPPERSLASHER: + skillratio += 60 + 40 * skill_lv; + if( sc && sc->data[SC_ROLLINGCUTTER] ) + skillratio += 25 * sc->data[SC_ROLLINGCUTTER]->val1; + break; + /** + * Arch Bishop + **/ case AB_DUPLELIGHT_MELEE: skillratio += 10 * skill_lv; break; + /** + * Ranger + **/ + case RA_ARROWSTORM: + skillratio += 100 + 50 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case RA_AIMEDBOLT: + skillratio += 400 + 50 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + if( tsc && (tsc->data[SC_BITE] || tsc->data[SC_ANKLE] || tsc->data[SC_ELECTRICSHOCKER]) ) + wd.div_ = tstatus->size + 2 + rand()%2; + break; + case RA_CLUSTERBOMB: + skillratio += 100 + 100 * skill_lv; + break; + case RA_WUGDASH: + skillratio = 500; + break; + case RA_WUGSTRIKE: + skillratio = 200 * skill_lv; + break; + case RA_WUGBITE: + skillratio += 300 + 200 * skill_lv; + if ( skill_lv == 5 ) skillratio += 100; + break; + case RA_SENSITIVEKEEN: + skillratio += 50 * skill_lv; + break; + /** + * Mechanic + **/ + case NC_BOOSTKNUCKLE: + skillratio += 100 + 100 * skill_lv + sstatus->dex; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case NC_PILEBUNKER: + skillratio += 200 + 100 * skill_lv + sstatus->str; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case NC_VULCANARM: + skillratio = 70 * skill_lv + sstatus->dex; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case NC_FLAMELAUNCHER: + case NC_COLDSLOWER: + skillratio += 200 + 300 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case NC_ARMSCANNON: + switch( tstatus->size ) { + case 0: skillratio += 100 + 500 * skill_lv; break;// Small + case 1: skillratio += 100 + 400 * skill_lv; break;// Medium + case 2: skillratio += 100 + 300 * skill_lv; break;// Large + } + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + //NOTE: Their's some other factors that affects damage, but not sure how exactly. Will recheck one day. [Rytech] + break; + case NC_AXEBOOMERANG: + skillratio += 60 + 40 * skill_lv; + 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]->weight / 10;// Weight is divided by 10 since 10 weight in coding make 1 whole actural weight. [Rytech] + } + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case NC_POWERSWING: + skillratio += 80 + 20 * skill_lv + sstatus->str + sstatus->dex; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case NC_AXETORNADO: + skillratio += 100 + 100 * skill_lv + sstatus->vit; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + } ATK_RATE(skillratio); @@ -1854,6 +1990,16 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo case NJ_SYURIKEN: ATK_ADD(4*skill_lv); break; + /** + * Ranger + **/ + case RA_WUGDASH: + case RA_WUGSTRIKE: + case RA_WUGBITE: + if(sd) + ATK_ADD(30*pc_checkskill(sd, RA_TOOTHOFWUG)); + break; + } } //Div fix. @@ -1863,14 +2009,17 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if (sc) { if(sc->data[SC_TRUESIGHT]) ATK_ADDRATE(2*sc->data[SC_TRUESIGHT]->val1); - + #if RE_EDP == 0 + /** + * In RE EDP doesn't affect your final damage but your atk and weapon atk + **/ if(sc->data[SC_EDP] && skill_num != ASC_BREAKER && skill_num != ASC_METEORASSAULT && skill_num != AS_SPLASHER && - skill_num != AS_VENOMKNIFE && - skill_num != AS_GRIMTOOTH) // RE disabled Grimtooth carrying EDP. + skill_num != AS_VENOMKNIFE) ATK_ADDRATE(sc->data[SC_EDP]->val3); + #endif } switch (skill_num) { @@ -1887,6 +2036,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo sc->data[SC_SPIRIT]->val2 == SL_CRUSADER) ATK_ADDRATE(100); break; + case NC_AXETORNADO: + if( (sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND ) + ATK_ADDRATE(50); + break; } if( sd ) @@ -1939,15 +2092,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if (!flag.idef || !flag.idef2) { //Defense reduction short vit_def; - signed short def1 = status_get_def(target); //Don't use tstatus->def1 due to skill timer reductions. + signed char def1 = status_get_def(target); //Don't use tstatus->def1 due to skill timer reductions. short def2 = (short)tstatus->def2; - if( sc && sc->data[SC_EXPIATIO] ) - { - def1 -= def1 * sc->data[SC_EXPIATIO]->val2 / 100; - def2 -= def2 * sc->data[SC_EXPIATIO]->val2 / 100; - } - if( sd ) { i = sd->ignore_def[is_boss(target)?RC_BOSS:RC_NONBOSS]; @@ -1987,6 +2134,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if((battle_check_undead(sstatus->race,sstatus->def_ele) || sstatus->race==RC_DEMON) && //This bonus already doesnt work vs players src->type == BL_MOB && (skill=pc_checkskill(tsd,AL_DP)) > 0) vit_def += skill*(int)(3 +(tsd->status.base_level+1)*0.04); // submitted by orn + if( src->type == BL_MOB && (skill=pc_checkskill(tsd,RA_RANGERMAIN))>0 && + (sstatus->race == RC_BRUTE || sstatus->race == RC_FISH || sstatus->race == RC_PLANT) ) + vit_def += skill*5; } else { //Mob-Pet vit-eq //VIT + rnd(0,[VIT/20]^2-1) vit_def = (def2/20)*(def2/20); @@ -2399,11 +2549,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo struct Damage md = battle_calc_misc_attack(src, target, skill_num, skill_lv, wflag); wd.damage += md.damage; } - - 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 ) { + //SG_FUSION hp penalty [Komurka] if (sc->data[SC_FUSION]) - { //SG_FUSION hp penalty [Komurka] + { int hp= sstatus->max_hp; if (sd && tsd) { hp = 8*hp/100; @@ -2413,38 +2562,21 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo 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); + /** + * affecting non-skills + **/ + if( !skill_num ) { + /** + * RK Enchant Blade + **/ + if( sc->data[SC_ENCHANTBLADE] && sd && ( (flag.rh && sd->weapontype1) || (flag.lh && sd->weapontype2) ) ) { + struct Damage md = battle_calc_magic_attack(src, target, RK_ENCHANTBLADE, pc_checkskill(sd,RK_ENCHANTBLADE), wflag); + wd.damage += md.damage; + wd.flag |= md.flag; } - } + } + } return wd; } @@ -2536,6 +2668,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list case AL_HEAL: case PR_BENEDICTIO: case PR_SANCTUARY: + /** + * Arch Bishop + **/ case AB_HIGHNESSHEAL: ad.damage = skill_calc_heal(src, target, skill_num, skill_lv, false); break; @@ -2556,17 +2691,31 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list case PF_SOULBURN: ad.damage = tstatus->sp * 2; break; + /** + * Arch Bishop + **/ case AB_RENOVATIO: + //Damage calculation from iRO wiki. [Jobbie] ad.damage = (int)((15 * status_get_lv(src)) + (1.5 * sstatus->int_)); break; default: { + #if RRMODE //Renewal MATK Appliance according to doddler (?title=Renewal_Changes#Upgrade_MATK) + /** + * min: (weaponMATK+upgradeMATK) * 2 + 1.5 * statusMATK + * max: [weaponMATK+upgradeMATK+(wMatk*wLvl)/10] * 2 + 1.5 * statusMATK + * yes this formula MATCHES their site: matk_max already holds weaponmatk+upgradematk, and + * -> statusMATK holds the %Matk modifier stuff from earlier and lastly: + * -> the mdef part is not applied at this point, but later. + **/ //1:bugreport:5101 //1:bugreport:5101 + MATK_ADD((1+sstatus->matk_max) * 2 + 15/10 * sstatus->matk_min + rand()% ( sstatus->matk_max + (1 + (sstatus->matk_max*sstatus->wlv) / 10 * 2 * 10/15 * sstatus->matk_min ) )); + #else //Ancient MATK Appliance if (sstatus->matk_max > sstatus->matk_min) { MATK_ADD(sstatus->matk_min+rand()%(1+sstatus->matk_max-sstatus->matk_min)); } else { MATK_ADD(sstatus->matk_min); } - + #endif if(nk&NK_SPLASHSPLIT){ // Divide MATK in case of multiple targets skill if(mflag>0) ad.damage/= mflag; @@ -2612,6 +2761,11 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list case WZ_SIGHTRASHER: skillratio += 20*skill_lv; break; +#if FIREIVY_ON + case WZ_FIREIVY: + skillratio += 20*skill_lv-15; + break; +#endif case WZ_VERMILION: skillratio += 20*skill_lv-20; break; @@ -2655,15 +2809,193 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list case NPC_EARTHQUAKE: skillratio += 100 +100*skill_lv +100*(skill_lv/2); break; + /** + * Arch Bishop + **/ case AB_JUDEX: - skillratio += ((skill_lv * 20) + 300) * status_get_lv(src) / 100; + skillratio += 180 + 20 * skill_lv; + if (skill_lv > 4) skillratio += 20; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. break; case AB_ADORAMUS: - skillratio += ((skill_lv * 100) + 500) * status_get_lv(src) / 100; + skillratio += 400 + 100 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. break; case AB_DUPLELIGHT_MAGIC: - skillratio = 200 + 20 * skill_lv; + skillratio += 100 + 20 * skill_lv; + break; + /** + * Warlock + **/ + case WL_SOULEXPANSION: + skillratio += 300 + 100 * skill_lv + sstatus->int_; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case WL_FROSTMISTY: + skillratio += 100 + 100 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case WL_JACKFROST: + { + struct status_change *tsc = status_get_sc(target); + if( tsc && tsc->data[SC_FREEZING] ) + { + skillratio += 900 + 300 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + } + else + skillratio += 400 + 100 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + } + break; + case WL_DRAINLIFE: + skillratio = 200 * skill_lv + sstatus->int_; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case WL_CRIMSONROCK: + skillratio += 1200 + 300 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case WL_HELLINFERNO: + if( status_get_element(target) == ELE_FIRE ) + skillratio = 60 * skill_lv; + else + skillratio = 240 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case WL_COMET: { + struct status_change * sc = status_get_sc(src); + if( sc ) + i = distance_xy(target->x, target->y, sc->comet_x, sc->comet_y); + else + i = 8; + if( i < 2 ) skillratio = 2500 + 500 * skill_lv; + else + if( i < 4 ) skillratio = 1600 + 400 * skill_lv; + else + if( i < 6 ) skillratio = 1200 + 300 * skill_lv; + else + skillratio = 800 + 200 * skill_lv; + } + break; + case WL_CHAINLIGHTNING_ATK: + skillratio += 100 + 300 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case WL_EARTHSTRAIN: + skillratio += 1900 + 100 * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case WL_TETRAVORTEX_FIRE: + case WL_TETRAVORTEX_WATER: + case WL_TETRAVORTEX_WIND: + case WL_TETRAVORTEX_GROUND: + skillratio += 400 + 500 * skill_lv; break; + case WL_SUMMON_ATK_FIRE: + case WL_SUMMON_ATK_WATER: + case WL_SUMMON_ATK_WIND: + case WL_SUMMON_ATK_GROUND: + skillratio = skill_lv * (status_get_lv(src) + ( sd ? sd->status.job_level : 50 ));// This is close to official, but lacking a little info to finalize. [Rytech] + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case LG_RAYOFGENESIS: + skillratio = (skillratio + 200) * skill_lv; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + break; + case WM_METALICSOUND: + skillratio += 120 * skill_lv + 60 * ( sd? pc_checkskill(sd, WM_LESSON) : 10 ) - 100; + break; + case WM_SEVERE_RAINSTORM: + skillratio += 50 * skill_lv; + break; + case WM_REVERBERATION_MAGIC: + skillratio += 100 * (sd ? pc_checkskill(sd, WM_REVERBERATION) : 1); + break; + case SO_FIREWALK: { + struct status_change * sc = status_get_sc(src); + skillratio = 300; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + if( sc && sc->data[SC_HEATER_OPTION] ) + skillratio += skillratio * sc->data[SC_HEATER_OPTION]->val3 / 100; + } + break; + case SO_ELECTRICWALK: { + struct status_change * sc = status_get_sc(src); + skillratio = 300; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + if( sc && sc->data[SC_BLAST_OPTION] ) + skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100; + } + break; + case SO_EARTHGRAVE: { + struct status_change * sc = status_get_sc(src); + skillratio = ( 200 * ( sd ? pc_checkskill(sd, SA_SEISMICWEAPON) : 10 ) + sstatus->int_ * skill_lv ); + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + if( sc && sc->data[SC_CURSED_SOIL_OPTION] ) + skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100; + } + break; + case SO_DIAMONDDUST: { + struct status_change * sc = status_get_sc(src); + skillratio = ( 200 * ( sd ? pc_checkskill(sd, SA_FROSTWEAPON) : 10 ) + sstatus->int_ * skill_lv ); + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + if( sc && sc->data[SC_COOLER_OPTION] ) + skillratio += skillratio * sc->data[SC_COOLER_OPTION]->val3 / 100; + } + break; + case SO_POISON_BUSTER: { + struct status_change * sc = status_get_sc(src); + skillratio += 1100 + 300 * skill_lv; + if( sc && sc->data[SC_CURSED_SOIL_OPTION] ) + skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100; + } + break; + case SO_PSYCHIC_WAVE: { + struct status_change * sc = status_get_sc(src); + skillratio += -100 + skill_lv * 70 + (sstatus->int_ * 3); + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + if( sc ){ + if( sc->data[SC_HEATER_OPTION] ) + skillratio += skillratio * sc->data[SC_HEATER_OPTION]->val3 / 100; + else if(sc->data[SC_COOLER_OPTION] ) + skillratio += skillratio * sc->data[SC_COOLER_OPTION]->val3 / 100; + else if(sc->data[SC_BLAST_OPTION] ) + skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100; + else if(sc->data[SC_CURSED_SOIL_OPTION] ) + skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val3 / 100; + } + } + break; + case SO_VARETYR_SPEAR: { + struct status_change * sc = status_get_sc(src); + skillratio += -100 + ( 100 * ( sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) : 10 ) + sstatus->int_ * skill_lv ); + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + if( sc && sc->data[SC_BLAST_OPTION] ) + skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100; + } + break; + case SO_CLOUD_KILL: { + struct status_change * sc = status_get_sc(src); + skillratio += -100 + skill_lv * 40; + if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus. + if( sc && sc->data[SC_CURSED_SOIL_OPTION] ) + skillratio += skillratio * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100; + } + break; + case GN_DEMONIC_FIRE: + if( skill_lv > 20) + { // Fire expansion Lv.2 + skillratio += 110 + 20 * (skill_lv - 20) + status_get_int(src) * 3; // Need official INT bonus. [LimitLine] + } + else if( skill_lv > 10 ) + { // Fire expansion Lv.1 + skillratio += 110 + 20 * (skill_lv - 10) / 2; + } + else + skillratio += 110 + 20 * skill_lv; + break; + } MATK_RATE(skillratio); @@ -2689,7 +3021,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list } if(!flag.imdef){ - short mdef = tstatus->mdef; + char mdef = tstatus->mdef; int mdef2= tstatus->mdef2; if(sd) { i = sd->ignore_mdef[is_boss(target)?RC_BOSS:RC_NONBOSS]; @@ -2701,10 +3033,19 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list //mdef2-= mdef2* i/100; } } + #if RRMODE + /** + * RE MDEF Reduction (from doddler:?title=Renewal_Changes#MDEF) + * Damage from magic = Magic Attack * 111.5/(111.5+eMDEF) + * Damage = Magic Attack * 111.5/(111.5+eMDEF) - sMDEF + **/ + ad.damage = ad.damage * ((1115/10) - mdef)/(1115/10) - mdef2; + #else if(battle_config.magic_defense_type) ad.damage = ad.damage - mdef*battle_config.magic_defense_type - mdef2; else ad.damage = ad.damage * (100-mdef)/100 - mdef2; + #endif } if (skill_num == NPC_EARTHQUAKE) @@ -2957,7 +3298,31 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * 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; + md.damage = ((status_get_hp(src) / 50) + (status_get_max_sp(src) / 4)) * skill_lv; + if (status_get_lv(src) > 100) md.damage = md.damage * status_get_lv(src) / 150; + if (sd) md.damage = md.damage * (100 + 5 * (pc_checkskill(sd,RK_DRAGONTRAINING) - 1)) / 100; + break; + /** + * Ranger + **/ + case RA_CLUSTERBOMB: + case RA_FIRINGTRAP: + case RA_ICEBOUNDTRAP: + md.damage = (2 * skill_lv * (sstatus->dex + 100)); + if (status_get_lv(src) > 100) md.damage += md.damage * (status_get_lv(src) - 50) / 200 + 15 / 10; + md.damage = md.damage * 2;// Without BaseLv Bonus + md.damage = md.damage + (5 * sstatus->int_) + (40 * ( sd ? pc_checkskill(sd,RA_RESEARCHTRAP) : 10 ) ); + break; + /** + * Mechanic + **/ + case NC_SELFDESTRUCTION: + md.damage = (sd?pc_checkskill(sd,NC_MAINFRAME):10) * skill_lv * (status_get_sp(src) + sstatus->vit); + if (status_get_lv(src) > 100) md.damage = md.damage * status_get_lv(src) / 150;// Base level bonus. + if (sd) md.damage = md.damage + status_get_hp(src); + status_set_sp(src, 0, 0); + break; + } if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets @@ -3059,11 +3424,23 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * else if( map[target->m].flag.battleground ) md.damage=battle_calc_bg_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag); - if (skill_num == NJ_ZENYNAGE && sd) - { //Time to Pay Up. - if ( md.damage > sd->status.zeny ) - md.damage=sd->status.zeny; - pc_payzeny(sd, md.damage); + switch( skill_num ) { + case RA_CLUSTERBOMB: + case RA_FIRINGTRAP: + case RA_ICEBOUNDTRAP: + { + struct Damage wd; + wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag); + md.damage += wd.damage; + } + break; + case NJ_ZENYNAGE: + if( sd ) { + if ( md.damage > sd->status.zeny ) + md.damage = sd->status.zeny; + pc_payzeny(sd, md.damage); + } + break; } return md; @@ -3096,10 +3473,10 @@ struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct bl } //Calculates BF_WEAPON returned damage. -int battle_calc_return_damage(struct block_list* bl, int damage, int flag) +int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int *dmg, int flag) { struct map_session_data* sd = NULL; - int rdamage = 0; + int rdamage = 0, damage = *dmg; sd = BL_CAST(BL_PC, bl); @@ -3112,10 +3489,24 @@ int battle_calc_return_damage(struct block_list* bl, int damage, int flag) if(rdamage < 1) rdamage = 1; } sc = status_get_sc(bl); - if (sc && sc->data[SC_REFLECTSHIELD]) - { - rdamage += damage * sc->data[SC_REFLECTSHIELD]->val2 / 100; - if (rdamage < 1) rdamage = 1; + if( sc && sc->count ) { + if (sc->data[SC_REFLECTSHIELD]) { + rdamage += damage * sc->data[SC_REFLECTSHIELD]->val2 / 100; + if (rdamage < 1) rdamage = 1; + } + if(sc->data[SC_DEATHBOUND] && !(src->type == BL_MOB && is_boss(src)) ) { + int dir = map_calc_dir(bl,src->x,src->y), + t_dir = unit_getdir(bl), rd1 = 0; + + if( distance_bl(src,bl) <= 0 || !map_check_dir(dir,t_dir) ) { + rd1 = min(damage,status_get_max_hp(bl)) * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage. + *dmg = rd1 * 30 / 100; // Received damge = 30% of amplifly damage. + clif_skill_damage(src,bl,gettick(), status_get_amotion(src), 0, -30000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1,6); + status_change_end(bl,SC_DEATHBOUND,-1); + rdamage += rd1; + if (rdamage < 1) rdamage = 1; + } + } } } else { if (sd && sd->long_weapon_damage_return) @@ -3318,27 +3709,17 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t damage = wd.damage + wd.damage2; if( damage > 0 && src != target ) { - if( sc && sc->data[SC_DUPLELIGHT] ) { - int skilllv = sc->data[SC_DUPLELIGHT]->val1; - if( rand()%100 < sc->data[SC_DUPLELIGHT]->val2 ) - skill_addtimerskill(src,tick+status_get_adelay(src) / 2,target->id,0,0,AB_DUPLELIGHT_MELEE,skilllv,BF_WEAPON,flag); - else if( rand()%100 < sc->data[SC_DUPLELIGHT]->val3 ) - skill_addtimerskill(src,tick+status_get_adelay(src) / 2,target->id,0,0,AB_DUPLELIGHT_MAGIC,skilllv,BF_MAGIC,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); + if( sc && sc->data[SC_DUPLELIGHT] && (wd.flag&BF_SHORT) && rand()%100 <= 10+2*sc->data[SC_DUPLELIGHT]->val1 ) + { // Activates it only from melee damage + int skillid; + if( rand()%2 == 1 ) + skillid = AB_DUPLELIGHT_MELEE; + else + skillid = AB_DUPLELIGHT_MAGIC; + skill_attack(skill_get_type(skillid), src, src, target, skillid, sc->data[SC_DUPLELIGHT]->val1, tick, SD_LEVEL); } - else - rdamage = battle_calc_return_damage(target, damage, wd.flag); + rdamage = battle_calc_return_damage(target,src, &damage, wd.flag); if( rdamage > 0 ) { rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0); @@ -3399,11 +3780,6 @@ 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) @@ -3551,6 +3927,8 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f case WZ_SIGHTBLASTER: case SM_MAGNUM: case MS_MAGNUM: + case RA_DETONATOR: + case RA_SENSITIVEKEEN: state |= BCT_ENEMY; strip_enemy = 0; break; @@ -3814,6 +4192,8 @@ static const struct _battle_data { { "enable_perfect_flee", &battle_config.enable_perfect_flee, BL_PC|BL_PET, BL_NUL, BL_ALL, }, { "casting_rate", &battle_config.cast_rate, 100, 0, INT_MAX, }, { "delay_rate", &battle_config.delay_rate, 100, 0, INT_MAX, }, + { "delay_dependon_dex", &battle_config.delay_dependon_dex, 0, 0, 1, }, + { "delay_dependon_agi", &battle_config.delay_dependon_agi, 0, 0, 1, }, { "skill_delay_attack_enable", &battle_config.sdelay_attack_enable, 0, 0, 1, }, { "left_cardfix_to_right", &battle_config.left_cardfix_to_right, 0, 0, 1, }, { "skill_add_range", &battle_config.skill_add_range, 0, 0, INT_MAX, }, @@ -3940,16 +4320,14 @@ static const struct _battle_data { { "arrow_decrement", &battle_config.arrow_decrement, 1, 0, 2, }, { "max_aspd", &battle_config.max_aspd, 199, 100, 199, }, { "max_walk_speed", &battle_config.max_walk_speed, 300, 100, 100*DEFAULT_WALK_SPEED, }, - { "max_lv", &battle_config.max_lv, 99, 0, 150, }, + { "max_lv", &battle_config.max_lv, 99, 0, 127, }, { "aura_lv", &battle_config.aura_lv, 99, 0, INT_MAX, }, { "max_hp", &battle_config.max_hp, 32500, 100, 1000000000, }, { "max_sp", &battle_config.max_sp, 32500, 100, 1000000000, }, { "max_cart_weight", &battle_config.max_cart_weight, 8000, 100, 1000000, }, { "max_parameter", &battle_config.max_parameter, 99, 10, 10000, }, { "max_baby_parameter", &battle_config.max_baby_parameter, 80, 10, 10000, }, - { "max_third_parameter", &battle_config.max_third_parameter, 120, 10, 10000, }, - { "max_baby_third_parameter", &battle_config.max_baby_third_parameter, 108, 10, 10000, }, - { "max_def", &battle_config.max_def, SHRT_MAX, 0, INT_MAX, }, + { "max_def", &battle_config.max_def, 99, 0, INT_MAX, }, { "over_def_bonus", &battle_config.over_def_bonus, 0, 0, 1000, }, { "skill_log", &battle_config.skill_log, BL_NUL, BL_NUL, BL_ALL, }, { "battle_log", &battle_config.battle_log, 0, 0, 1, }, @@ -4083,6 +4461,7 @@ static const struct _battle_data { { "min_cloth_color", &battle_config.min_cloth_color, 0, 0, INT_MAX, }, { "max_cloth_color", &battle_config.max_cloth_color, 4, 0, INT_MAX, }, { "pet_hair_style", &battle_config.pet_hair_style, 100, 0, INT_MAX, }, + { "castrate_dex_scale", &battle_config.castrate_dex_scale, 150, 1, INT_MAX, }, { "area_size", &battle_config.area_size, 14, 0, INT_MAX, }, { "zeny_from_mobs", &battle_config.zeny_from_mobs, 0, 0, 1, }, { "mobs_level_up", &battle_config.mobs_level_up, 0, 0, 1, }, @@ -4200,13 +4579,11 @@ 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 - { "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, }, + /** + * rAthena + **/ + { "max_third_parameter", &battle_config.max_third_parameter, 20, 0, INT_MAX, }, + { "atcommand_max_stat_bypass", &battle_config.atcommand_max_stat_bypass, 0, 0, 100, }, }; @@ -4253,8 +4630,8 @@ void battle_adjust_conf() battle_config.max_walk_speed = 100*DEFAULT_WALK_SPEED/battle_config.max_walk_speed; battle_config.max_cart_weight *= 10; - if(battle_config.max_def > SHRT_MAX && !battle_config.weapon_defense_type) // added by [Skotlex] - battle_config.max_def = SHRT_MAX; + if(battle_config.max_def > 100 && !battle_config.weapon_defense_type) // added by [Skotlex] + battle_config.max_def = 100; if(battle_config.min_hitrate > battle_config.max_hitrate) battle_config.min_hitrate = battle_config.max_hitrate; |