summaryrefslogtreecommitdiff
path: root/src/map/battle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/battle.c')
-rw-r--r--src/map/battle.c781
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;