summaryrefslogtreecommitdiff
path: root/src/map/battle.c
diff options
context:
space:
mode:
authorrud0lp20 <rud0lp20@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-07-23 15:00:12 +0000
committerrud0lp20 <rud0lp20@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-07-23 15:00:12 +0000
commit98cabc236656a475473c7b4c07a81210a1eb9541 (patch)
tree4fadf225f15bce90e3924f60da00997b0e5b28bc /src/map/battle.c
parent211a15e56f8ec2344790421930024d2eb401f291 (diff)
downloadhercules-98cabc236656a475473c7b4c07a81210a1eb9541.tar.gz
hercules-98cabc236656a475473c7b4c07a81210a1eb9541.tar.bz2
hercules-98cabc236656a475473c7b4c07a81210a1eb9541.tar.xz
hercules-98cabc236656a475473c7b4c07a81210a1eb9541.zip
Updated most Ranger skills to its official behavior and damage formula.(bugreport:5272, bugreport:6249, bugreport:5548, bugreport:5888)
Fixed issues with traps: (bugreport:5906) - if RA_REASERCHTRAP is learned Alloy Traps can now be used to Hunter traps. - if Hunter traps expire it will now return either Booby Trap or Alloy Trap depending on item used. - some traps should now give full damage to plants. - update list of skills that can hit/damage/affect traps. - damage through skills can now be shown when hitting traps. - proper knock back behaviors - proper animation when triggers and triggering of item bonus script 'bHPDrainRate' Fixed an issues where some skills cannot damage UNT_REVERBERATION/UNT_POEMOFNETHERWORLD and doesn't deal 1 damage Updated some official behavior where informational must shown when hitting, targeting, casting skills to targets. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16483 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/battle.c')
-rw-r--r--src/map/battle.c121
1 files changed, 96 insertions, 25 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index a9c8ba6ea..a04f3c328 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -1275,10 +1275,14 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
//Initial flag
flag.rh=1;
flag.weapon=1;
- flag.infdef=(tstatus->mode&MD_PLANT&&skill_num!=RA_CLUSTERBOMB?1:0);
+ flag.infdef=(tstatus->mode&MD_PLANT && skill_num != RA_CLUSTERBOMB
+#ifdef RENEWAL
+ && skill_num != HT_FREEZINGTRAP
+#endif
+ ?1:0);
if( target->type == BL_SKILL){
TBL_SKILL *su = (TBL_SKILL*)target;
- if( su->group && su->group->skill_id == WM_REVERBERATION)
+ if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
flag.infdef = 1;
}
@@ -1466,6 +1470,8 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if(flag.arrow)
cri += sd->bonus.arrow_cri;
}
+ if( sc && sc->data[SC_CAMOUFLAGE] )
+ cri += 10 * (10-sc->data[SC_CAMOUFLAGE]->val4);
//The official equation is *2, but that only applies when sd's do critical.
//Therefore, we use the old value 3 on cases when an sd gets attacked by a mob
cri -= tstatus->luk*(!sd&&tsd?3:2);
@@ -1782,10 +1788,12 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
case MA_CHARGEARROW:
skillratio += 50;
break;
+#ifndef RENEWAL
case HT_FREEZINGTRAP:
case MA_FREEZINGTRAP:
skillratio += -50+10*skill_lv;
break;
+#endif
case KN_PIERCE:
case ML_PIERCE:
skillratio += 10*skill_lv;
@@ -2162,13 +2170,13 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
skillratio += 400 + 50 * skill_lv;
RE_LVL_DMOD(100);
if( tsc && (tsc->data[SC_BITE] || tsc->data[SC_ANKLE] || tsc->data[SC_ELECTRICSHOCKER]) )
- wd.div_ = tstatus->size + 2 + rnd()%2;
+ wd.div_ = tstatus->size + 2 + ( (rnd()%100 < 50-tstatus->size*10) ? 1 : 0 );
break;
case RA_CLUSTERBOMB:
skillratio += 100 + 100 * skill_lv;
break;
- case RA_WUGDASH:
- skillratio = 500;
+ case RA_WUGDASH:// ATK 300%
+ skillratio += 200;
break;
case RA_WUGSTRIKE:
skillratio = 200 * skill_lv;
@@ -2495,7 +2503,13 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
case NJ_SYURIKEN:
ATK_ADD(4*skill_lv);
break;
- case RA_WUGDASH:
+ case HT_FREEZINGTRAP:
+ if(sd)
+ ATK_ADD( 40 * pc_checkskill(sd, RA_RESEARCHTRAP) );
+ break;
+ case RA_WUGDASH://(Caster�s Current Weight x 10 / 8)
+ if( sd && sd->weight )
+ ATK_ADD( sd->weight / 8 );
case RA_WUGSTRIKE:
case RA_WUGBITE:
if(sd)
@@ -2659,6 +2673,12 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if( tsc && tsc->data[SC_GT_REVITALIZE] && tsc->data[SC_GT_REVITALIZE]->val4 )
def2 += 2 * tsc->data[SC_GT_REVITALIZE]->val4;
+ if( tsc && tsc->data[SC_CAMOUFLAGE] ){
+ i = 5 * (10-tsc->data[SC_CAMOUFLAGE]->val4);
+ def1 -= def1 * i / 100;
+ def2 -= def2 * i / 100;
+ }
+
if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type ) {
unsigned char target_count; //256 max targets should be a sane max
target_count = unit_counttargeted(target);
@@ -2744,6 +2764,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if( (bl = map_id2bl(sc->data[SC_GT_CHANGE]->val2)) )
ATK_ADD( ( status_get_dex(bl)/4 + status_get_str(bl)/2 ) * sc->data[SC_GT_CHANGE]->val1 / 5 );
}
+
+ if(sc->data[SC_CAMOUFLAGE])
+ ATK_ADD(30 * (10-sc->data[SC_CAMOUFLAGE]->val4) );
}
//Refine bonus
@@ -3275,7 +3298,12 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
//Skill Range Criteria
ad.flag |= battle_range_type(src, target, skill_num, skill_lv);
flag.infdef=(tstatus->mode&MD_PLANT?1:0);
-
+ if( target->type == BL_SKILL){
+ TBL_SKILL *su = (TBL_SKILL*)target;
+ if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
+ flag.infdef = 1;
+ }
+
switch(skill_num)
{
case MG_FIREWALL:
@@ -3960,12 +3988,9 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
case MA_LANDMINE:
case HT_BLASTMINE:
case HT_CLAYMORETRAP:
- {
- int level = sd?sd->status.base_level:status_get_lv(src);
- md.damage = skill_lv*sstatus->dex*(3+level/100)*(1+sstatus->int_/35);
- md.damage+= md.damage*(rnd()%20-10)/100;
- md.damage+= 40*(sd?pc_checkskill(sd,RA_RESEARCHTRAP):0);
- }
+ md.damage = skill_lv * sstatus->dex * (3+status_get_lv(src)/100) * (1+sstatus->int_/35);
+ md.damage += md.damage * (rnd()%20-10) / 100;
+ md.damage += 40 * (sd?pc_checkskill(sd,RA_RESEARCHTRAP):0);
break;
#else
case HT_LANDMINE:
@@ -4071,10 +4096,10 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
case RA_CLUSTERBOMB:
case RA_FIRINGTRAP:
case RA_ICEBOUNDTRAP:
- md.damage = (2 * skill_lv * (sstatus->dex + 100));
- md.damage = md.damage * 2;// Without BaseLv Bonus
+ md.damage = skill_lv * sstatus->dex + sstatus->int_ * 5 ;
RE_LVL_TMDMOD();
- md.damage = md.damage + (5 * sstatus->int_) + (40 * ( sd ? pc_checkskill(sd,RA_RESEARCHTRAP) : 10 ) );
+ md.damage = md.damage * (20 * ( sd ? pc_checkskill(sd,RA_RESEARCHTRAP) : 10 ) );
+ md.damage = (md.damage?md.damage:1) / (skill_num == RA_CLUSTERBOMB?50:100);
break;
/**
* Mechanic
@@ -4185,8 +4210,24 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
if(md.damage < 0)
md.damage = 0;
- else if(md.damage && tstatus->mode&MD_PLANT)
- md.damage = 1;
+ else if(md.damage && tstatus->mode&MD_PLANT){
+ switch(skill_num){
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ case HT_BLASTMINE:
+ case HT_CLAYMORETRAP:
+ case RA_CLUSTERBOMB:
+#ifdef RENEWAL
+ break;
+#endif
+ default:
+ md.damage = 1;
+ }
+ }else if( target->type == BL_SKILL ){
+ TBL_SKILL *su = (TBL_SKILL*)target;
+ if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
+ md.damage = 1;
+ }
if(!(nk&NK_NO_ELEFIX))
md.damage=battle_attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
@@ -4198,9 +4239,10 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
md.damage=battle_calc_bg_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
switch( skill_num ) {
- case RA_CLUSTERBOMB:
case RA_FIRINGTRAP:
case RA_ICEBOUNDTRAP:
+ if( md.damage == 1 ) break;
+ case RA_CLUSTERBOMB:
{
struct Damage wd;
wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
@@ -4554,7 +4596,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if( sc->data[SC_GIANTGROWTH] && (wd.flag&BF_SHORT) && rnd()%100 < sc->data[SC_GIANTGROWTH]->val2 )
wd.damage *= 3; // Triple Damage
- if( sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0 && sd->status.inventory[sd->equip_index[EQI_AMMO]].amount >= sc->data[SC_FEARBREEZE]->val4 && battle_config.arrow_decrement){
+ if( sd && sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0 && sd->status.inventory[sd->equip_index[EQI_AMMO]].amount >= sc->data[SC_FEARBREEZE]->val4 && battle_config.arrow_decrement){
pc_delitem(sd,sd->equip_index[EQI_AMMO],sc->data[SC_FEARBREEZE]->val4,0,1,LOG_TYPE_CONSUME);
sc->data[SC_FEARBREEZE]->val4 = 0;
}
@@ -4592,7 +4634,11 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if (sd && sd->bonus.splash_range > 0 && damage > 0)
skill_castend_damage_id(src, target, 0, 1, tick, 0);
-
+ if ( target->type == BL_SKILL && damage > 0 ){
+ TBL_SKILL *su = (TBL_SKILL*)target;
+ if( su->group && su->group->skill_id == HT_BLASTMINE)
+ skill_blown(src, target, 3, -1, 0);
+ }
map_freeblock_lock();
battle_delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion);
@@ -4843,6 +4889,9 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
return 0;
if( skill_get_inf2(su->group->skill_id)&INF2_TRAP ) { //Only a few skills can target traps...
switch( battle_getcurrentskill(src) ) {
+ case RK_DRAGONBREATH:// it can only hit traps in pvp/gvg maps
+ if( !map[m].flag.pvp && !map[m].flag.gvg )
+ break;
case 0://you can hit them without skills
case MA_REMOVETRAP:
case HT_REMOVETRAP:
@@ -4855,15 +4904,37 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
case RA_DETONATOR:
case RA_SENSITIVEKEEN:
case GN_CRAZYWEED:
+ case RK_STORMBLAST:
+ case RK_PHANTOMTHRUST:
+ case SR_RAMPAGEBLASTER:
+ case NC_COLDSLOWER:
+ case NC_SELFDESTRUCTION:
+#ifdef RENEWAL
+ case KN_BOWLINGBASH:
+ case KN_SPEARSTAB:
+ case LK_SPIRALPIERCE:
+ case ML_SPIRALPIERCE:
+ case MO_FINGEROFFENSIVE:
+ case MO_INVESTIGATE:
+ case MO_TRIPLEATTACK:
+ case MO_EXTREMITYFIST:
+ case CR_HOLYCROSS:
+ case ASC_METEORASSAULT:
+ case RG_RAID:
+ case MC_CARTREVOLUTION:
+#endif
state |= BCT_ENEMY;
strip_enemy = 0;
break;
- default:
- return 0;
+ default:
+ if(su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD){
+ state |= BCT_ENEMY;
+ strip_enemy = 0;
+ }else
+ return 0;
}
} else if (su->group->skill_id==WZ_ICEWALL ||
- su->group->skill_id == GN_WALLOFTHORN ||
- su->group->skill_id == WM_REVERBERATION) {
+ su->group->skill_id == GN_WALLOFTHORN) {
state |= BCT_ENEMY;
strip_enemy = 0;
} else //Excepting traps and icewall, you should not be able to target skills.