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.c1212
1 files changed, 666 insertions, 546 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 0959ea858..f6fba5ca5 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -1,5 +1,6 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Portions Copyright (c) Athena Dev Teams
#include "../common/cbasetypes.h"
#include "../common/timer.h"
@@ -40,9 +41,6 @@ int attr_fix_table[4][ELE_MAX][ELE_MAX];
struct Battle_Config battle_config;
static struct eri *delay_damage_ers; //For battle delay damage structures.
-#define DAMAGE_RATE(a){damage = (int64)damage * (a)/100;}
-#define DAMAGE_SUBRATE(a){damage -= (int64)damage * (a)/100;}
-#define DAMAGE_ADDRATE(a){damage += (int64)damage * (a)/100;}
int battle_getcurrentskill(struct block_list *bl) { //Returns the current/last skill in use by this bl.
struct unit_data *ud;
@@ -59,7 +57,7 @@ int battle_getcurrentskill(struct block_list *bl) { //Returns the current/last s
/*==========================================
* Get random targetting enemy
*------------------------------------------*/
-static int battle_gettargeted_sub(struct block_list *bl, va_list ap) {
+int battle_gettargeted_sub(struct block_list *bl, va_list ap) {
struct block_list **bl_list;
struct unit_data *ud;
int target_id;
@@ -92,7 +90,7 @@ struct block_list* battle_gettargeted(struct block_list *target) {
nullpo_retr(NULL, target);
memset(bl_list, 0, sizeof(bl_list));
- map_foreachinrange(battle_gettargeted_sub, target, AREA_SIZE, BL_CHAR, bl_list, &c, target->id);
+ map_foreachinrange(battle->get_targeted_sub, target, AREA_SIZE, BL_CHAR, bl_list, &c, target->id);
if ( c == 0 )
return NULL;
if( c > 24 )
@@ -116,7 +114,7 @@ int battle_gettarget(struct block_list* bl) {
return 0;
}
-static int battle_getenemy_sub(struct block_list *bl, va_list ap) {
+int battle_getenemy_sub(struct block_list *bl, va_list ap) {
struct block_list **bl_list;
struct block_list *target;
int *c;
@@ -134,7 +132,7 @@ static int battle_getenemy_sub(struct block_list *bl, va_list ap) {
if (status_isdead(bl))
return 0;
- if (battle_check_target(target, bl, BCT_ENEMY) > 0) {
+ if (battle->check_target(target, bl, BCT_ENEMY) > 0) {
bl_list[(*c)++] = bl;
return 1;
}
@@ -148,7 +146,7 @@ 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);
+ map_foreachinrange(battle->get_enemy_sub, target, range, type, bl_list, &c, target);
if ( c == 0 )
return NULL;
@@ -158,7 +156,7 @@ struct block_list* battle_getenemy(struct block_list *target, int type, int rang
return bl_list[rnd()%c];
}
-static int battle_getenemyarea_sub(struct block_list *bl, va_list ap) {
+int battle_getenemyarea_sub(struct block_list *bl, va_list ap) {
struct block_list **bl_list, *src;
int *c, ignore_id;
@@ -176,7 +174,7 @@ static int battle_getenemyarea_sub(struct block_list *bl, va_list ap) {
if( status_isdead(bl) )
return 0;
- if( battle_check_target(src, bl, BCT_ENEMY) > 0 ) {// Is Enemy!...
+ if( battle->check_target(src, bl, BCT_ENEMY) > 0 ) {// Is Enemy!...
bl_list[(*c)++] = bl;
return 1;
}
@@ -190,7 +188,7 @@ struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int
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);
+ map_foreachinarea(battle->get_enemy_area_sub, src->m, x - range, y - range, x + range, y + range, type, bl_list, &c, src, ignore_id);
if( c == 0 )
return NULL;
@@ -211,6 +209,7 @@ struct delay_damage {
uint16 skill_id;
enum damage_lv dmg_lv;
unsigned short attack_type;
+ bool additional_effects;
};
int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) {
@@ -233,10 +232,10 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) {
{
map_freeblock_lock();
status_fix_damage(src, target, dat->damage, dat->delay);
- if( dat->attack_type && !status_isdead(target) )
- skill_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,dat->dmg_lv,tick);
+ if( dat->attack_type && !status_isdead(target) && dat->additional_effects )
+ skill->additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,dat->dmg_lv,tick);
if( dat->dmg_lv > ATK_BLOCK && dat->attack_type )
- skill_counter_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
+ skill->counter_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
map_freeblock_unlock();
} else if( !src && dat->skill_id == CR_REFLECTSHIELD ) {
/**
@@ -251,7 +250,7 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) {
return 0;
}
-int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int damage, enum damage_lv dmg_lv, int ddelay)
+int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects)
{
struct delay_damage *dat;
struct status_change *sc;
@@ -266,10 +265,10 @@ int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src,
if ( !battle_config.delay_battle_damage || amotion <= 1 ) {
map_freeblock_lock();
status_fix_damage(src, target, damage, ddelay); // We have to seperate here between reflect damage and others [icescope]
- if( attack_type && !status_isdead(target) )
- skill_additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, gettick());
+ if( attack_type && !status_isdead(target) && additional_effects )
+ skill->additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, gettick());
if( dmg_lv > ATK_BLOCK && attack_type )
- skill_counter_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());
+ skill->counter_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());
map_freeblock_unlock();
return 0;
}
@@ -283,10 +282,11 @@ int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src,
dat->dmg_lv = dmg_lv;
dat->delay = ddelay;
dat->distance = distance_bl(src, target)+10; //Attack should connect regardless unless you teleported.
+ dat->additional_effects = additional_effects;
if (src->type != BL_PC && amotion > 1000)
amotion = 1000; //Aegis places a damage-delay cap of 1 sec to non player attacks. [Skotlex]
- add_timer(tick+amotion, battle_delay_damage_sub, 0, (intptr_t)dat);
+ add_timer(tick+amotion, battle->delay_damage_sub, 0, (intptr_t)dat);
return 0;
}
@@ -334,20 +334,20 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
ratio += enchant_eff[sc->data[SC_DELUGE]->val1-1];
}
if( target && target->type == BL_SKILL ) {
- if( atk_elem == ELE_FIRE && battle_getcurrentskill(target) == GN_WALLOFTHORN ) {
+ if( atk_elem == ELE_FIRE && battle->get_current_skill(target) == GN_WALLOFTHORN ) {
struct skill_unit *su = (struct skill_unit*)target;
struct skill_unit_group *sg;
struct block_list *src;
- int x,y;
if( !su || !su->alive || (sg = su->group) == NULL || !sg || sg->val3 == -1 ||
(src = map_id2bl(sg->src_id)) == NULL || status_isdead(src) )
return 0;
if( sg->unit_id != UNT_FIREWALL ) {
+ int x,y;
x = sg->val3 >> 16;
y = sg->val3 & 0xffff;
- skill_unitsetting(src,su->group->skill_id,su->group->skill_lv,x,y,1);
+ skill->unitsetting(src,su->group->skill_id,su->group->skill_lv,x,y,1);
sg->val3 = -1;
sg->limit = DIFF_TICK(gettick(),sg->tick)+300;
}
@@ -366,7 +366,7 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
if( tsc->data[SC_THORNSTRAP])
status_change_end(target, SC_THORNSTRAP, INVALID_TIMER);
if( tsc->data[SC_FIRE_CLOAK_OPTION])
- DAMAGE_SUBRATE(tsc->data[SC_FIRE_CLOAK_OPTION]->val2)
+ damage -= damage * tsc->data[SC_FIRE_CLOAK_OPTION]->val2 / 100;
if( tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB)
status_change_end(target, SC_CRYSTALIZE, INVALID_TIMER);
if( tsc->data[SC_EARTH_INSIGNIA]) damage += damage/2;
@@ -406,9 +406,9 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
ARR_FIND(1, 6, t, tsd->talisman[t] > 0);
if( t < 5 && atk_elem == t )
- DAMAGE_SUBRATE(tsd->talisman[t] * 3) // -3% custom value
+ damage -= damage * ( tsd->talisman[t] * 3 ) / 100;// -3% custom value
}
- return (int64)damage*ratio/100;
+ return damage*ratio/100;
}
/*==========================================
@@ -431,7 +431,6 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
tstatus = status_get_status_data(target);
s_race2 = status_get_race2(src);
-#define bccDAMAGE_RATE(a){ damage = (int64)damage * (a)/1000;}
switch(attack_type){
case BF_MAGIC:
if ( sd && !(nk&NK_NO_CARDFIX_ATK) ) {
@@ -448,7 +447,7 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
}
}
if (cardfix != 1000)
- bccDAMAGE_RATE(cardfix)
+ damage = damage * cardfix / 1000;
}
if( tsd && !(nk&NK_NO_CARDFIX_DEF) )
@@ -492,7 +491,7 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
cardfix = cardfix * ( 100 - tsd->sc.data[SC_MDEF_RATE]->val1 ) / 100;
if (cardfix != 1000)
- bccDAMAGE_RATE(cardfix)
+ damage = damage * cardfix / 1000;
}
break;
case BF_WEAPON:
@@ -626,9 +625,9 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
}
#endif
if( (left&1) && cardfix_ != 1000 )
- bccDAMAGE_RATE(cardfix_)
+ damage = damage * cardfix_ / 1000;
else if( cardfix != 1000 )
- bccDAMAGE_RATE(cardfix)
+ damage = damage * cardfix / 1000;
}else if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
if( !(nk&NK_NO_ELEFIX) )
@@ -682,7 +681,7 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
cardfix = cardfix * ( 100 - tsd->sc.data[SC_DEF_RATE]->val1 ) / 100;
if( cardfix != 1000 )
- bccDAMAGE_RATE(cardfix)
+ damage = damage * cardfix / 1000;
}
break;
case BF_MISC:
@@ -716,7 +715,7 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
if (cardfix != 10000)
- bccDAMAGE_RATE(cardfix)
+ damage = damage * cardfix / 1000;
}
break;
}
@@ -747,13 +746,13 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
sd=(struct map_session_data *)bl;
//Special no damage states
if(flag&BF_WEAPON && sd->special_state.no_weapon_damage)
- DAMAGE_SUBRATE(sd->special_state.no_weapon_damage)
+ damage -= damage * sd->special_state.no_weapon_damage / 100;
if(flag&BF_MAGIC && sd->special_state.no_magic_damage)
- DAMAGE_SUBRATE(sd->special_state.no_magic_damage)
+ damage -= damage * sd->special_state.no_magic_damage / 100;
if(flag&BF_MISC && sd->special_state.no_misc_damage)
- DAMAGE_SUBRATE(sd->special_state.no_misc_damage)
+ damage -= damage * sd->special_state.no_misc_damage / 100;
if(!damage) return 0;
}
@@ -778,7 +777,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if( skill_id == MG_NAPALMBEAT ||
skill_id == MG_SOULSTRIKE ||
skill_id == WL_SOULEXPANSION ||
- (skill_id && skill_get_ele(skill_id, skill_lv) == ELE_GHOST) ||
+ (skill_id && skill->get_ele(skill_id, skill_lv) == ELE_GHOST) ||
(!skill_id && (status_get_status_data(src))->rhw.ele == ELE_GHOST)
){
if( skill_id == WL_SOULEXPANSION )
@@ -798,12 +797,12 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if( sc->data[SC_SAFETYWALL] && (flag&(BF_SHORT|BF_MAGIC))==BF_SHORT )
{
- struct skill_unit_group* group = skill_id2group(sc->data[SC_SAFETYWALL]->val3);
+ struct skill_unit_group* group = skill->id2group(sc->data[SC_SAFETYWALL]->val3);
uint16 skill_id = sc->data[SC_SAFETYWALL]->val2;
if (group) {
if(skill_id == MH_STEINWAND){
if (--group->val2<=0)
- skill_delunitgroup(group);
+ skill->del_unitgroup(group,ALC_MARK);
d->dmg_lv = ATK_BLOCK;
return 0;
}
@@ -811,16 +810,15 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
* in RE, SW possesses a lifetime equal to 3 times the caster's health
**/
#ifdef RENEWAL
+ d->dmg_lv = ATK_BLOCK;
if ( ( group->val2 - damage) > 0 ) {
group->val2 -= damage;
- d->dmg_lv = ATK_BLOCK;
- return 0;
} else
- damage -= group->val2;
- skill_delunitgroup(group);
+ skill->del_unitgroup(group,ALC_MARK);
+ return 0;
#else
if (--group->val2<=0)
- skill_delunitgroup(group);
+ skill->del_unitgroup(group,ALC_MARK);
d->dmg_lv = ATK_BLOCK;
return 0;
#endif
@@ -834,15 +832,15 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
}
if( sc->data[SC_WEAPONBLOCKING] && flag&(BF_SHORT|BF_WEAPON) && rnd()%100 < sc->data[SC_WEAPONBLOCKING]->val2 )
{
- clif_skill_nodamage(bl,src,GC_WEAPONBLOCKING,1,1);
+ clif->skill_nodamage(bl,src,GC_WEAPONBLOCKING,1,1);
d->dmg_lv = ATK_BLOCK;
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_id)&NK_NO_CARDFIX_ATK) && rnd()%100 < sce->val2 )
+ if( (sce=sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON && !(skill->get_nk(skill_id)&NK_NO_CARDFIX_ATK) && rnd()%100 < sce->val2 )
{
int delay;
- clif_skill_nodamage(bl,bl,CR_AUTOGUARD,sce->val1,1);
+ clif->skill_nodamage(bl,bl,CR_AUTOGUARD,sce->val1,1);
// different delay depending on skill level [celest]
if (sce->val1 <= 5)
delay = 300;
@@ -853,20 +851,20 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
unit_set_walkdelay(bl, gettick(), delay, 1);
if(sc->data[SC_SHRINK] && rnd()%100<5*sce->val1)
- skill_blown(bl,src,skill_get_blewcount(CR_SHRINK,1),-1,0);
+ skill->blown(bl,src,skill->get_blewcount(CR_SHRINK,1),-1,0);
return 0;
}
if( (sce = sc->data[SC_MILLENNIUMSHIELD]) && sce->val2 > 0 && damage > 0 ) {
- clif_skill_nodamage(bl, bl, RK_MILLENNIUMSHIELD, 1, 1);
+ clif->skill_nodamage(bl, bl, RK_MILLENNIUMSHIELD, 1, 1);
sce->val3 -= damage; // absorb damage
d->dmg_lv = ATK_BLOCK;
- sc_start(bl,SC_STUN,15,0,skill_get_time2(RK_MILLENNIUMSHIELD,sce->val1)); // There is a chance to be stuned when one shield is broken.
+ sc_start(bl,SC_STUN,15,0,skill->get_time2(RK_MILLENNIUMSHIELD,sce->val1)); // There is a chance to be stuned when one shield is broken.
if( sce->val3 <= 0 ) { // Shield Down
sce->val2--;
if( sce->val2 > 0 ) {
if( sd )
- clif_millenniumshield(sd,sce->val2);
+ clif->millenniumshield(sd,sce->val2);
sce->val3 = 1000; // Next Shield
} else
status_change_end(bl,SC_MILLENNIUMSHIELD,INVALID_TIMER); // All shields down
@@ -877,7 +875,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if( (sce=sc->data[SC_PARRYING]) && flag&BF_WEAPON && skill_id != WS_CARTTERMINATION && rnd()%100 < sce->val2 )
{ // attack blocked by Parrying
- clif_skill_nodamage(bl, bl, LK_PARRYING, sce->val1,1);
+ clif->skill_nodamage(bl, bl, LK_PARRYING, sce->val1,1);
return 0;
}
@@ -885,7 +883,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
(flag&BF_LONG || sc->data[SC_SPURT])
&& rnd()%100 < 20) {
if (sd && pc_issit(sd)) pc_setstand(sd); //Stand it to dodge.
- clif_skill_nodamage(bl,bl,TK_DODGE,1,1);
+ clif->skill_nodamage(bl,bl,TK_DODGE,1,1);
if (!sc->data[SC_COMBO])
sc_start4(bl, SC_COMBO, 100, TK_JUMPKICK, src->id, 1, 0, 2000);
return 0;
@@ -904,7 +902,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if((sce=sc->data[SC_KAUPE]) && rnd()%100 < sce->val2)
{ //Kaupe blocks damage (skill or otherwise) from players, mobs, homuns, mercenaries.
- clif_specialeffect(bl, 462, AREA);
+ clif->specialeffect(bl, 462, AREA);
//Shouldn't end until Breaker's non-weapon part connects.
if (skill_id != ASC_BREAKER || !(flag&BF_WEAPON))
if (--(sce->val3) <= 0) //We make it work like Safety Wall, even though it only blocks 1 time.
@@ -913,19 +911,19 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
}
if( flag&BF_MAGIC && (sce=sc->data[SC_PRESTIGE]) && rnd()%100 < sce->val2) {
- clif_specialeffect(bl, 462, AREA); // Still need confirm it.
+ clif->specialeffect(bl, 462, AREA); // Still need confirm it.
return 0;
}
if (((sce=sc->data[SC_UTSUSEMI]) || sc->data[SC_BUNSINJYUTSU])
- && flag&BF_WEAPON && !(skill_get_nk(skill_id)&NK_NO_CARDFIX_ATK)) {
+ && flag&BF_WEAPON && !(skill->get_nk(skill_id)&NK_NO_CARDFIX_ATK)) {
- skill_additional_effect (src, bl, skill_id, skill_lv, flag, ATK_BLOCK, gettick() );
+ skill->additional_effect (src, bl, skill_id, skill_lv, flag, ATK_BLOCK, gettick() );
if( !status_isdead(src) )
- skill_counter_additional_effect( src, bl, skill_id, skill_lv, flag, gettick() );
+ skill->counter_additional_effect( src, bl, skill_id, skill_lv, flag, gettick() );
if (sce) {
- clif_specialeffect(bl, 462, AREA);
- skill_blown(src,bl,sce->val3,-1,0);
+ clif->specialeffect(bl, 462, AREA);
+ skill->blown(src,bl,sce->val3,-1,0);
}
//Both need to be consumed if they are active.
if (sce && --(sce->val2) <= 0)
@@ -947,9 +945,8 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
}
#ifdef RENEWAL
- if( sc->data[SC_RAID] )
- {
- DAMAGE_ADDRATE(20)
+ if( sc->data[SC_RAID] ) {
+ damage += damage * 20 / 100;
if (--sc->data[SC_RAID]->val1 == 0)
status_change_end(bl, SC_RAID, INVALID_TIMER);
@@ -968,7 +965,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
case W_2HMACE:
case W_1HAXE:
case W_2HAXE:
- DAMAGE_RATE(150)
+ damage = damage * 150/100;
break;
case W_MUSICAL:
case W_WHIP:
@@ -983,7 +980,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
case W_DAGGER:
case W_1HSWORD:
case W_2HSWORD:
- DAMAGE_RATE(50)
+ damage = damage * 50/100;
break;
}
}
@@ -991,13 +988,12 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
status_change_end(bl,SC_VOICEOFSIREN,INVALID_TIMER);
}
-
//Finally damage reductions....
// Assumptio doubles the def & mdef on RE mode, otherwise gives a reduction on the final damage. [Igniz]
#ifndef RENEWAL
if( sc->data[SC_ASSUMPTIO] ) {
if( map_flag_vs(bl->m) )
- damage = (int64)damage*2/3; //Receive 66% damage
+ damage = damage*2/3; //Receive 66% damage
else
damage >>= 1; //Receive 50% damage
}
@@ -1005,15 +1001,15 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if(sc->data[SC_DEFENDER] &&
(flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
- DAMAGE_RATE(100-sc->data[SC_DEFENDER]->val2)
+ damage = damage * ( 100 - sc->data[SC_DEFENDER]->val2 ) / 100;
if(sc->data[SC_ADJUSTMENT] &&
(flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
- DAMAGE_SUBRATE(20)
+ damage -= damage * 20 / 100;
if(sc->data[SC_FOGWALL] && skill_id != RK_DRAGONBREATH) {
if(flag&BF_SKILL) //25% reduction
- DAMAGE_SUBRATE(25)
+ damage -= damage * 25 / 100;
else if ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
damage >>= 2; //75% reduction
}
@@ -1024,25 +1020,25 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if (sc->data[SC_MANU_DEF])
for (i=0;ARRAYLENGTH(mob_manuk)>i;i++)
if (mob_manuk[i]==((TBL_MOB*)src)->class_) {
- DAMAGE_SUBRATE(sc->data[SC_MANU_DEF]->val1)
+ damage -= damage * sc->data[SC_MANU_DEF]->val1 / 100;
break;
}
if (sc->data[SC_SPL_DEF])
for (i=0;ARRAYLENGTH(mob_splendide)>i;i++)
if (mob_splendide[i]==((TBL_MOB*)src)->class_) {
- DAMAGE_SUBRATE(sc->data[SC_SPL_DEF]->val1)
+ damage -= damage * sc->data[SC_SPL_DEF]->val1 / 100;
break;
}
}
if((sce=sc->data[SC_ARMOR]) && //NPC_DEFENDER
sce->val3&flag && sce->val4&flag)
- DAMAGE_SUBRATE(sc->data[SC_ARMOR]->val2)
+ damage -= damage * sc->data[SC_ARMOR]->val2 / 100;
#ifdef RENEWAL
if(sc->data[SC_ENERGYCOAT] && (flag&BF_WEAPON || flag&BF_MAGIC) && skill_id != WS_CARTTERMINATION)
#else
- if(sc->data[SC_ENERGYCOAT] && flag&BF_WEAPON && skill_id != WS_CARTTERMINATION)
+ if(sc->data[SC_ENERGYCOAT] && (flag&BF_WEAPON && skill_id != WS_CARTTERMINATION))
#endif
{
struct status_data *status = status_get_status_data(bl);
@@ -1052,16 +1048,31 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if (!status_charge(bl, 0, (10+5*per)*status->max_sp/1000))
status_change_end(bl, SC_ENERGYCOAT, INVALID_TIMER);
//Reduction: 6% + 6% every 20%
- DAMAGE_SUBRATE(6 * (1+per))
+ damage -= damage * (6 * (1+per)) / 100;
}
if(sc->data[SC_GRANITIC_ARMOR]){
- DAMAGE_SUBRATE(sc->data[SC_GRANITIC_ARMOR]->val2)
+ damage -= damage * sc->data[SC_GRANITIC_ARMOR]->val2 / 100;
}
if(sc->data[SC_PAIN_KILLER]){
- DAMAGE_SUBRATE(sc->data[SC_PAIN_KILLER]->val3)
+ damage -= damage * sc->data[SC_PAIN_KILLER]->val3 / 100;
}
if((sce=sc->data[SC_MAGMA_FLOW]) && (rnd()%100 <= sce->val2) ){
- skill_castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,gettick(),0);
+ skill->castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,gettick(),0);
+ }
+
+ if( (sce = sc->data[SC_STONEHARDSKIN]) && flag&BF_WEAPON && damage > 0 ) {
+ sce->val2 -= damage;
+ if( src->type == BL_PC ) {
+ TBL_PC *ssd = BL_CAST(BL_PC, src);
+ if (ssd && ssd->status.weapon != W_BOW)
+ skill->break_equip(src, EQP_WEAPON, 3000, BCT_SELF);
+ } else
+ skill->break_equip(src, EQP_WEAPON, 3000, BCT_SELF);
+ // 30% chance to reduce monster's ATK by 25% for 10 seconds.
+ if( src->type == BL_MOB )
+ sc_start(src, SC_STRIPWEAPON, 30, 0, skill->get_time2(RK_STONEHARDSKIN, sce->val1));
+ if( sce->val2 <= 0 )
+ status_change_end(bl, SC_STONEHARDSKIN, INVALID_TIMER);
}
/**
@@ -1105,7 +1116,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
int dy[8]={1,1,0,-1,-1,-1,0,1};
uint8 dir = map_calc_dir(bl, src->x, src->y);
if( unit_movepos(bl, src->x-dx[dir], src->y-dy[dir], 1, 1) ) {
- clif_slide(bl,src->x-dx[dir],src->y-dy[dir]);
+ clif->slide(bl,src->x-dx[dir],src->y-dy[dir]);
unit_setdir(bl, dir);
}
d->dmg_lv = ATK_DEF;
@@ -1117,13 +1128,13 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
//(since battle_drain is strictly for players currently)
if ((sce=sc->data[SC_BLOODLUST]) && flag&BF_WEAPON && damage > 0 &&
rnd()%100 < sce->val3)
- status_heal(src, (int64)damage*sce->val4/100, 0, 3);
+ status_heal(src, damage*sce->val4/100, 0, 3);
if( sd && (sce = sc->data[SC_FORCEOFVANGUARD]) && flag&BF_WEAPON && rnd()%100 < sce->val2 )
- pc_addspiritball(sd,skill_get_time(LG_FORCEOFVANGUARD,sce->val1),sce->val3);
+ pc_addspiritball(sd,skill->get_time(LG_FORCEOFVANGUARD,sce->val1),sce->val3);
if (sc->data[SC_STYLE_CHANGE] && rnd()%2) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
- if (hd) hom_addspiritball(hd, 10); //add a sphere
+ if (hd) homun->addspiritball(hd, 10); //add a sphere
}
if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
@@ -1131,9 +1142,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if( sc && sc->data[SC__SHADOWFORM] ) {
struct block_list *s_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2);
- if( !s_bl ) { // If the shadow form target is not present remove the sc.
+ if( !s_bl || s_bl->m != bl->m ) { // If the shadow form target is not present remove the sc.
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- } else if( status_isdead(s_bl) || !battle_check_target(src,s_bl,BCT_ENEMY)) { // If the shadow form target is dead or not your enemy remove the sc in both.
+ } else if( status_isdead(s_bl) || !battle->check_target(src,s_bl,BCT_ENEMY)) { // If the shadow form target is dead or not your enemy remove the sc in both.
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
if( s_bl->type == BL_PC )
((TBL_PC*)s_bl)->shadowform_id = 0;
@@ -1143,7 +1154,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if( s_bl->type == BL_PC )
((TBL_PC*)s_bl)->shadowform_id = 0;
} else {
- status_damage(bl, s_bl, damage, 0, clif_damage(s_bl, s_bl, gettick(), 500, 500, damage, -1, 0, 0), 0);
+ status_damage(bl, s_bl, damage, 0, clif->damage(s_bl, s_bl, gettick(), 500, 500, damage, -1, 0, 0), 0);
return ATK_NONE;
}
}
@@ -1154,13 +1165,11 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
//SC effects from caster side.
sc = status_get_sc(src);
- if (sc && sc->count)
- {
+ if (sc && sc->count) {
if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
- DAMAGE_ADDRATE(75)
+ damage += damage * 75 / 100;
// [Epoque]
- if (bl->type == BL_MOB)
- {
+ if (bl->type == BL_MOB) {
int i;
if ( ((sce=sc->data[SC_MANU_ATK]) && (flag&BF_WEAPON)) ||
@@ -1168,7 +1177,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
)
for (i=0;ARRAYLENGTH(mob_manuk)>i;i++)
if (((TBL_MOB*)bl)->class_==mob_manuk[i]) {
- DAMAGE_ADDRATE(sce->val1)
+ damage += damage * sce->val1 / 100;
break;
}
if ( ((sce=sc->data[SC_SPL_ATK]) && (flag&BF_WEAPON)) ||
@@ -1176,36 +1185,44 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
)
for (i=0;ARRAYLENGTH(mob_splendide)>i;i++)
if (((TBL_MOB*)bl)->class_==mob_splendide[i]) {
- DAMAGE_ADDRATE(sce->val1)
+ damage += damage * sce->val1 / 100;
break;
}
}
if( sc->data[SC_POISONINGWEAPON] && skill_id != GC_VENOMPRESSURE && (flag&BF_WEAPON) && damage > 0 && rnd()%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, 1));
+ sc_start(bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON, 1));
if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
status_change_spread(src, bl);
if (sc->data[SC_STYLE_CHANGE] && rnd()%2) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
- if (hd) hom_addspiritball(hd, 10);
+ if (hd) homun->addspiritball(hd, 10);
}
}
-
- if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && map[bl->m].flag.pvp)
- {
- if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex]
- if (flag&BF_WEAPON)
- DAMAGE_RATE(battle_config.pk_weapon_damage_rate)
- if (flag&BF_MAGIC)
- DAMAGE_RATE(battle_config.pk_magic_damage_rate)
- if (flag&BF_MISC)
- DAMAGE_RATE(battle_config.pk_misc_damage_rate)
- } else { //Normal attacks get reductions based on range.
- if (flag & BF_SHORT)
- DAMAGE_RATE(battle_config.pk_short_damage_rate)
- if (flag & BF_LONG)
- DAMAGE_RATE(battle_config.pk_long_damage_rate)
- }
- if(!damage) damage = 1;
+ /* no data claims these settings affect anything other than players */
+ if( damage && sd && bl->type == BL_PC ) {
+ switch( skill_id ) {
+ //case PA_PRESSURE: /* pressure also belongs to this list but it doesn't reach this area -- so dont worry about it */
+ case HW_GRAVITATION:
+ case NJ_ZENYNAGE:
+ case KO_MUCHANAGE:
+ break;
+ default:
+ if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex]
+ if (flag&BF_WEAPON)
+ damage = damage * map[bl->m].weapon_damage_rate / 100;
+ if (flag&BF_MAGIC)
+ damage = damage * map[bl->m].magic_damage_rate / 100;
+ if (flag&BF_MISC)
+ damage = damage * map[bl->m].misc_damage_rate / 100;
+ } else { //Normal attacks get reductions based on range.
+ if (flag & BF_SHORT)
+ damage = damage * map[bl->m].short_damage_rate / 100;
+ if (flag & BF_LONG)
+ damage = damage * map[bl->m].long_damage_rate / 100;
+ }
+ if(!damage) damage = 1;
+ break;
+ }
}
if(battle_config.skill_min_damage && damage > 0 && damage < div_)
@@ -1225,7 +1242,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
}
if( sd ) {
if( pc_ismadogear(sd) && rnd()%100 < 50 ) {
- short element = skill_get_ele(skill_id, skill_lv);
+ short element = skill->get_ele(skill_id, skill_lv);
if( !skill_id || element == -1 ) { //Take weapon's element
struct status_data *sstatus = NULL;
if( src->type == BL_PC && ((TBL_PC*)src)->bonus.arrow_ele )
@@ -1254,41 +1271,13 @@ int battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int dam
if( !damage )
return 0;
- if( bl->type == BL_MOB )
- {
+ if( bl->type == BL_MOB ) {
struct mob_data* md = BL_CAST(BL_MOB, bl);
- if( map[bl->m].flag.battleground && (md->class_ == MOBID_BLUE_CRYST || md->class_ == MOBID_PINK_CRYST) && flag&BF_SKILL )
+
+ if( flag&BF_SKILL && (md->class_ == MOBID_BLUE_CRYST || md->class_ == MOBID_PINK_CRYST) )
return 0; // Crystal cannot receive skill damage on battlegrounds
}
- switch( skill_id )
- {
- case PA_PRESSURE:
- case HW_GRAVITATION:
- case NJ_ZENYNAGE:
- case KO_MUCHANAGE:
- break;
- default:
- if( flag&BF_SKILL )
- { //Skills get a different reduction than non-skills. [Skotlex]
- if( flag&BF_WEAPON )
- DAMAGE_RATE(battle_config.bg_weapon_damage_rate)
- if( flag&BF_MAGIC )
- DAMAGE_RATE(battle_config.bg_magic_damage_rate)
- if( flag&BF_MISC )
- DAMAGE_RATE(battle_config.bg_misc_damage_rate)
- }
- else
- { //Normal attacks get reductions based on range.
- if( flag&BF_SHORT )
- DAMAGE_RATE(battle_config.bg_short_damage_rate)
- if( flag&BF_LONG )
- DAMAGE_RATE(battle_config.bg_long_damage_rate)
- }
-
- if( !damage ) damage = 1;
- }
-
return damage;
}
@@ -1317,56 +1306,42 @@ int battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int dama
}
}
if(src->type != BL_MOB) {
- struct guild *g = guild_search(status_get_guild_id(src));
+ struct guild *g = src->type == BL_PC ? ((TBL_PC *)src)->guild : guild->search(status_get_guild_id(src));
- if (class_ == MOBID_EMPERIUM && (!g || guild_checkskill(g,GD_APPROVAL) <= 0 ))
+ if (class_ == MOBID_EMPERIUM && (!g || guild->checkskill(g,GD_APPROVAL) <= 0 ))
return 0;
- if (g && battle_config.guild_max_castles && guild_checkcastles(g)>=battle_config.guild_max_castles)
+ if (g && battle_config.guild_max_castles && guild->checkcastles(g)>=battle_config.guild_max_castles)
return 0; // [MouseJstr]
}
}
switch (skill_id) {
- //Skills with no damage reduction.
- case PA_PRESSURE:
- case HW_GRAVITATION:
- case NJ_ZENYNAGE:
- case KO_MUCHANAGE:
- 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_RATE(battle_config.gvg_weapon_damage_rate)
- if (flag&BF_MAGIC)
- DAMAGE_RATE(battle_config.gvg_magic_damage_rate)
- if (flag&BF_MISC)
- DAMAGE_RATE(battle_config.gvg_misc_damage_rate)
- } else { //Normal attacks get reductions based on range.
- if (flag & BF_SHORT)
- DAMAGE_RATE(battle_config.gvg_short_damage_rate)
- if (flag & BF_LONG)
- DAMAGE_RATE(battle_config.gvg_long_damage_rate)
- }
- if(!damage) damage = 1;
+ case PA_PRESSURE:
+ case HW_GRAVITATION:
+ case NJ_ZENYNAGE:
+ case KO_MUCHANAGE:
+ 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;
+ }
+ */
+ break;
}
+
return damage;
}
/*==========================================
* HP/SP drain calculation
*------------------------------------------*/
-static int battle_calc_drain(int damage, int rate, int per)
-{
+int battle_calc_drain(int damage, int rate, int per) {
int diff = 0;
if (per && rnd()%1000 < rate) {
- diff = ((int64)damage * per) / 100;
+ diff = (damage * per) / 100;
if (diff == 0) {
if (per > 0)
diff = 1;
@@ -1380,8 +1355,7 @@ static int battle_calc_drain(int damage, int rate, int per)
/*==========================================
* Passif skill dammages increases
*------------------------------------------*/
-int battle_addmastery(struct map_session_data *sd,struct block_list *target,int dmg,int type)
-{
+int battle_addmastery(struct map_session_data *sd,struct block_list *target,int dmg,int type) {
int damage,skill;
struct status_data *status = status_get_status_data(target);
int weapon;
@@ -1391,7 +1365,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
if((skill = pc_checkskill(sd,AL_DEMONBANE)) > 0 &&
target->type == BL_MOB && //This bonus doesnt work against players.
- (battle_check_undead(status->race,status->def_ele) || status->race==RC_DEMON) )
+ (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) )
@@ -1495,8 +1469,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
* &8: Skip target size adjustment (Extremity Fist?)
*&16: Arrow attack but BOW, REVOLVER, RIFLE, SHOTGUN, GATLING or GRENADE type weapon not equipped (i.e. shuriken, kunai and venom knives not affected by DEX)
*/
-static int battle_calc_base_damage(struct status_data *status, struct weapon_atk *wa, struct status_change *sc, unsigned short t_size, struct map_session_data *sd, int flag)
-{
+int battle_calc_base_damage(struct status_data *status, struct weapon_atk *wa, struct status_change *sc, unsigned short t_size, struct map_session_data *sd, int flag) {
unsigned int atkmin=0, atkmax=0;
short type = 0;
int damage = 0;
@@ -1553,9 +1526,7 @@ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk
//SizeFix only for players
if (!(sd->special_state.no_sizefix || (flag&8)))
- DAMAGE_RATE(type==EQI_HAND_L?
- sd->left_weapon.atkmods[t_size]:
- sd->right_weapon.atkmods[t_size])
+ damage = damage * ( type == EQI_HAND_L ? sd->left_weapon.atkmods[t_size] : sd->right_weapon.atkmods[t_size] ) / 100;
}
//Finally, add baseatk
@@ -1571,12 +1542,12 @@ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk
if(sd->left_weapon.overrefine)
damage += rnd()%sd->left_weapon.overrefine+1;
if (sd->weapon_atk_rate[sd->weapontype2])
- DAMAGE_ADDRATE(sd->weapon_atk_rate[sd->weapontype2])
+ damage += damage * sd->weapon_atk_rate[sd->weapontype2] / 100;
} else { //Right hand
if(sd->right_weapon.overrefine)
damage += rnd()%sd->right_weapon.overrefine+1;
if (sd->weapon_atk_rate[sd->weapontype1])
- DAMAGE_ADDRATE(sd->weapon_atk_rate[sd->weapontype1])
+ damage += damage * sd->weapon_atk_rate[sd->weapontype1] / 100;
}
}
return damage;
@@ -1585,14 +1556,13 @@ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk
/*==========================================
* Consumes ammo for the given skill.
*------------------------------------------*/
-void battle_consume_ammo(TBL_PC*sd, int skill, int lv)
-{
+void battle_consume_ammo(TBL_PC*sd, int skill_id, int lv) {
int qty=1;
if (!battle_config.arrow_decrement)
return;
if (skill) {
- qty = skill_get_ammo_qty(skill, lv);
+ qty = skill->get_ammo_qty(skill_id, lv);
if (!qty) qty = 1;
}
@@ -1601,11 +1571,8 @@ void battle_consume_ammo(TBL_PC*sd, int skill, int lv)
sd->state.arrow_atk = 0;
}
-
-static int battle_range_type(
- struct block_list *src, struct block_list *target,
- uint16 skill_id, uint16 skill_lv)
-{ //Skill Range Criteria
+//Skill Range Criteria
+int battle_range_type(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv) {
if (battle_config.skillrange_by_distance &&
(src->type&battle_config.skillrange_by_distance)
) { //based on distance between src/target [Skotlex]
@@ -1614,13 +1581,25 @@ static int battle_range_type(
return BF_LONG;
}
//based on used skill's range
- if (skill_get_range2(src, skill_id, skill_lv) < 5)
+ if (skill->get_range2(src, skill_id, skill_lv) < 5)
return BF_SHORT;
return BF_LONG;
}
+int battle_adjust_skill_damage(int m, unsigned short skill_id) {
-static int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id)
-{
+ if( map[m].skill_count ) {
+ int i;
+ ARR_FIND(0, map[m].skill_count, i, map[m].skills[i]->skill_id == skill_id );
+
+ if( i < map[m].skill_count ) {
+ return map[m].skills[i]->modifier;
+ }
+
+ }
+
+ return 0;
+}
+int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id) {
int i;
if (!sd->skillblown[0].id)
return 0;
@@ -1632,18 +1611,15 @@ static int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id)
return 0;
}
-struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag);
-struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag);
-
//For quick div adjustment.
#define damage_div_fix(dmg, div) { if (div > 1) (dmg)*=div; else if (div < 0) (div)*=-1; }
/*==========================================
* battle_calc_weapon_attack (by Skotlex)
*------------------------------------------*/
-static struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int wflag)
+struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int wflag)
{
unsigned int skillratio = 100; //Skill dmg modifiers.
- short skill=0;
+ short temp=0;
short s_ele, s_ele_, t_class;
int i, nk;
bool n_ele = false; // non-elemental
@@ -1692,16 +1668,16 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
//Initial Values
wd.type=0; //Normal attack
- wd.div_=skill_id?skill_get_num(skill_id,skill_lv):1;
- wd.amotion=(skill_id && skill_get_inf(skill_id)&INF_GROUND_SKILL)?0:sstatus->amotion; //Amotion should be 0 for ground skills.
+ wd.div_=skill_id?skill->get_num(skill_id,skill_lv):1;
+ wd.amotion=(skill_id && skill->get_inf(skill_id)&INF_GROUND_SKILL)?0:sstatus->amotion; //Amotion should be 0 for ground skills.
if(skill_id == KN_AUTOCOUNTER)
wd.amotion >>= 1;
wd.dmotion=tstatus->dmotion;
- wd.blewcount=skill_get_blewcount(skill_id,skill_lv);
+ wd.blewcount=skill->get_blewcount(skill_id,skill_lv);
wd.flag = BF_WEAPON; //Initial Flag
wd.flag |= (skill_id||wflag)?BF_SKILL:BF_NORMAL; // Baphomet card's splash damage is counted as a skill. [Inkfish]
wd.dmg_lv=ATK_DEF; //This assumption simplifies the assignation later
- nk = skill_get_nk(skill_id);
+ nk = skill->get_nk(skill_id);
if( !skill_id && wflag ) //If flag, this is splash damage from Baphomet Card and it always hits.
nk |= NK_NO_CARDFIX_ATK|NK_IGNORE_FLEE;
flag.hit = nk&NK_IGNORE_FLEE?1:0;
@@ -1716,19 +1692,18 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
tsd = BL_CAST(BL_PC, target);
if(sd)
- wd.blewcount += battle_blewcount_bonus(sd, skill_id);
+ wd.blewcount += battle->blewcount_bonus(sd, skill_id);
//Set miscellaneous data that needs be filled regardless of hit/miss
if(
(sd && sd->state.arrow_atk) ||
- (!sd && ((skill_id && skill_get_ammotype(skill_id)) || sstatus->rhw.range>3))
+ (!sd && ((skill_id && skill->get_ammotype(skill_id)) || sstatus->rhw.range>3))
)
flag.arrow = 1;
- if(skill_id){
- wd.flag |= battle_range_type(src, target, skill_id, skill_lv);
- switch(skill_id)
- {
+ if(skill_id) {
+ wd.flag |= battle->range_type(src, target, skill_id, skill_lv);
+ switch(skill_id) {
case MO_FINGEROFFENSIVE:
if(sd) {
if (battle_config.finger_offensive_type)
@@ -1794,7 +1769,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
}
t_class = status_get_class(target);
- s_ele = s_ele_ = skill_get_ele(skill_id, skill_lv);
+ s_ele = s_ele_ = skill->get_ele(skill_id, skill_lv);
if( !skill_id || s_ele == -1 )
{ //Take weapon's element
s_ele = sstatus->rhw.ele;
@@ -1848,16 +1823,16 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
{ //Success chance is not added, the higher one is used [Skotlex]
if( rnd()%100 < ( 5*skill_lv > sd->bonus.double_rate ? 5*skill_lv : sc && sc->data[SC_KAGEMUSYA]?sc->data[SC_KAGEMUSYA]->val1*3:sd->bonus.double_rate ) )
{
- wd.div_ = skill_get_num(TF_DOUBLE,skill_lv?skill_lv:1);
+ wd.div_ = skill->get_num(TF_DOUBLE,skill_lv?skill_lv:1);
wd.type = 0x08;
}
}
else if( sd->weapontype1 == W_REVOLVER && (skill_lv = pc_checkskill(sd,GS_CHAINACTION)) > 0 && rnd()%100 < 5*skill_lv )
{
- wd.div_ = skill_get_num(GS_CHAINACTION,skill_lv);
+ wd.div_ = skill->get_num(GS_CHAINACTION,skill_lv);
wd.type = 0x08;
}
- else if(sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW
+ else if(sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW
&& (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->status.inventory[i].amount > 1){
int chance = rand()%100;
wd.type = 0x08;
@@ -1933,10 +1908,13 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if (rnd()%1000 < cri)
flag.cri = 1;
}
- if (flag.cri)
- {
+ if (flag.cri) {
wd.type = 0x0a;
+#ifdef RENEWAL
+ flag.hit = 1;
+#else
flag.idef = flag.idef2 = flag.hit = 1;
+#endif
} else { //Check for Perfect Hit
if(sd && sd->bonus.perfect_hit > 0 && rnd()%100 < sd->bonus.perfect_hit)
flag.hit = 1;
@@ -2041,12 +2019,12 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if( sd ) {
// Weaponry Research hidden bonus
- if ((skill = pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
- hitrate += hitrate * ( 2 * skill ) / 100;
+ if ((temp = pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
+ hitrate += hitrate * ( 2 * temp ) / 100;
if( (sd->status.weapon == W_1HSWORD || sd->status.weapon == W_DAGGER) &&
- (skill = pc_checkskill(sd, GN_TRAINING_SWORD))>0 )
- hitrate += 3 * skill;
+ (temp = pc_checkskill(sd, GN_TRAINING_SWORD))>0 )
+ hitrate += 3 * temp;
}
hitrate = cap_value(hitrate, battle_config.min_hitrate, battle_config.max_hitrate);
@@ -2064,8 +2042,8 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
//ATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc
#define ATK_RATE( a ) { wd.damage= wd.damage*(a)/100 ; if(flag.lh) wd.damage2= wd.damage2*(a)/100; }
#define ATK_RATE2( a , b ) { wd.damage= wd.damage*(a)/100 ; if(flag.lh) wd.damage2= wd.damage2*(b)/100; }
-#define ATK_RATER(a){ wd.damage = (int64)wd.damage*(a)/100;}
-#define ATK_RATEL(a){ wd.damage2 = (int64)wd.damage2*(a)/100;}
+#define ATK_RATER(a){ wd.damage = wd.damage*(a)/100;}
+#define ATK_RATEL(a){ wd.damage2 = wd.damage2*(a)/100;}
//Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage
#define ATK_ADDRATE( a ) { wd.damage+= wd.damage*(a)/100 ; if(flag.lh) wd.damage2+= wd.damage2*(a)/100; }
#define ATK_ADDRATE2( a , b ) { wd.damage+= wd.damage*(a)/100 ; if(flag.lh) wd.damage2+= wd.damage2*(b)/100; }
@@ -2076,7 +2054,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
switch (skill_id)
{ //Calc base damage according to skill
case PA_SACRIFICE:
- wd.damage = (int64)sstatus->max_hp* 9/100;
+ wd.damage = sstatus->max_hp* 9/100;
wd.damage2 = 0;
break;
#ifndef RENEWAL
@@ -2150,15 +2128,15 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
default:
i |= 16; // for ex. shuriken must not be influenced by DEX
}
- wd.damage = battle_calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, i);
+ wd.damage = battle->calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, i);
if (flag.lh)
- wd.damage2 = battle_calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, sd, i);
+ wd.damage2 = battle->calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, sd, i);
if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets
if(wflag>0)
wd.damage/= wflag;
else
- ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill_get_name(skill_id));
+ ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id));
}
//Add any bonuses that modify the base baseatk+watk (pre-skills)
@@ -2169,9 +2147,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if(flag.cri && sd->bonus.crit_atk_rate)
ATK_ADDRATE(sd->bonus.crit_atk_rate);
- if(sd->status.party_id && (skill=pc_checkskill(sd,TK_POWER)) > 0){
+ if(sd->status.party_id && (temp=pc_checkskill(sd,TK_POWER)) > 0){
if( (i = party_foreachsamemap(party_sub_count, sd, 0)) > 1 ) // exclude the player himself [Inkfish]
- ATK_ADDRATE(2*skill*i);
+ ATK_ADDRATE(2*temp*i);
}
}
break;
@@ -2787,11 +2765,11 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
break;
case SR_TIGERCANNON:// ATK [((Caster consumed HP + SP) / 4) x Caster Base Level / 100] %
{
- int hp = (int64)sstatus->max_hp * (10 + 2 * skill_lv) / 100,
- sp = (int64)sstatus->max_sp * (6 + skill_lv) / 100;
- skillratio = ((int64)hp+sp) / 4;
+ int hp = sstatus->max_hp * (10 + 2 * skill_lv) / 100,
+ sp = sstatus->max_sp * (6 + skill_lv) / 100;
+ skillratio = (hp+sp) / 4;
if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) // ATK [((Caster consumed HP + SP) / 2) x Caster Base Level / 100] %
- skillratio = (int64)hp+sp / 2;
+ skillratio = hp+sp / 2;
RE_LVL_DMOD(100);
}
break;
@@ -2853,7 +2831,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
skillratio += 800 + 100 * skill_lv;
if( sd ) { // Still need official value [pakpil]
short lv = (short)skill_lv;
- skillratio += 100 * skill_check_pc_partner(sd,skill_id,&lv,skill_get_splash(skill_id,skill_lv),0);
+ skillratio += 100 * skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),0);
}
break;
case WM_SOUND_OF_DESTRUCTION:
@@ -2955,7 +2933,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
skillratio += -100 + 100 * skill_lv;
break;
}
-
+#ifdef RENEWAL
+ if( sc && sc->data[SC_TRUESIGHT] )
+ skillratio += 2*sc->data[SC_TRUESIGHT]->val1;
+#endif
ATK_RATE(skillratio);
//Constant/misc additions from skills
@@ -3008,9 +2989,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
case SR_GATEOFHELL:
ATK_ADD (sstatus->max_hp - status_get_hp(src));
if(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE){
- ATK_ADD ( ((int64)sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status_get_lv(src) );
+ ATK_ADD ( (sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status_get_lv(src) );
}else{
- ATK_ADD ( ((int64)sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status_get_lv(src) );
+ ATK_ADD ( (sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status_get_lv(src) );
}
break;
case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40)
@@ -3050,8 +3031,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
//The following are applied on top of current damage and are stackable.
if ( sc ) {
+#ifndef RENEWAL
if( sc->data[SC_TRUESIGHT] )
ATK_ADDRATE(2*sc->data[SC_TRUESIGHT]->val1);
+#endif
if( sc->data[SC_GLOOMYDAY_SK] &&
( skill_id == LK_SPIRALPIERCE || skill_id == KN_BRANDISHSPEAR ||
skill_id == CR_SHIELDBOOMERANG || skill_id == PA_SHIELDCHAIN ||
@@ -3060,7 +3043,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if( sc->data[SC_EDP] ){
switch(skill_id){
case AS_SPLASHER: case AS_VENOMKNIFE:
+#ifndef RENEWAL_EDP
case AS_GRIMTOOTH:
+#endif
break;
#ifndef RENEWAL_EDP
case ASC_BREAKER: case ASC_METEORASSAULT: break;
@@ -3101,11 +3086,13 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
break;
}
- if( sd )
- {
+ if( (i = battle->adjust_skill_damage(src->m,skill_id)) )
+ ATK_RATE(i);
+
+ if( sd ) {
if (skill_id && (i = pc_skillatk_bonus(sd, skill_id)))
ATK_ADDRATE(i);
-
+
if( skill_id != PA_SACRIFICE && skill_id != MO_INVESTIGATE && skill_id != CR_GRANDCROSS && skill_id != NPC_GRANDDARKNESS && skill_id != PA_SHIELDCHAIN && !flag.cri )
{ //Elemental/Racial adjustments
if( sd->right_weapon.def_ratio_atk_ele & (1<<tstatus->def_ele) ||
@@ -3211,14 +3198,14 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
#else
vit_def = def2;
#endif
- 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 &&
+ if((battle->check_undead(sstatus->race,sstatus->def_ele) || sstatus->race==RC_DEMON) && //This bonus already doesnt work vs players
+ src->type == BL_MOB && (temp=pc_checkskill(tsd,AL_DP)) > 0)
+ vit_def += temp*(int)(3 +(tsd->status.base_level+1)*0.04); // submitted by orn
+ if( src->type == BL_MOB && (temp=pc_checkskill(tsd,RA_RANGERMAIN))>0 &&
(sstatus->race == RC_BRUTE || sstatus->race == RC_FISH || sstatus->race == RC_PLANT) )
- vit_def += skill*5;
+ vit_def += temp*5;
#ifdef RENEWAL
- if( skill == NJ_ISSEN ){//TODO: do better implementation if other skills(same func) are found [malufett]
+ if( temp == NJ_ISSEN ){//TODO: do better implementation if other skills(same func) are found [malufett]
vit_def += def1;
def1 = 0;
}
@@ -3246,6 +3233,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
* Pierce defence gains 1 atk per def/2
**/
+ if( def1 == -400 ) /* being hit by a gazillion units, you hit the jackpot and got -400 which creates a division by 0 and subsequently crashes */
+ def1 = -399;
+
ATK_ADD2(
flag.pdef ?(def1/2):0,
flag.pdef2?(def1/2):0
@@ -3258,8 +3248,8 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
#else
if (def1 > 100) def1 = 100;
ATK_RATE2(
- flag.idef ?100:(flag.pdef ? (int64)flag.pdef*(def1+vit_def) : (100-def1)),
- flag.idef2?100:(flag.pdef2? (int64)flag.pdef2*(def1+vit_def) : (100-def1))
+ flag.idef ?100:(flag.pdef ? flag.pdef*(def1+vit_def) : (100-def1)),
+ flag.idef2?100:(flag.pdef2? flag.pdef2*(def1+vit_def) : (100-def1))
);
ATK_ADD2(
flag.idef ||flag.pdef ?0:-vit_def,
@@ -3317,38 +3307,37 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
skill_id != CR_GRANDCROSS)
{ //Add mastery damage
if(skill_id != ASC_BREAKER && sd->status.weapon == W_KATAR &&
- (skill=pc_checkskill(sd,ASC_KATAR)) > 0)
+ (temp=pc_checkskill(sd,ASC_KATAR)) > 0)
{ //Adv Katar Mastery is does not applies to ASC_BREAKER,
// but other masteries DO apply >_>
- ATK_ADDRATE(10+ 2*skill);
+ ATK_ADDRATE(10+ 2*temp);
}
- wd.damage = battle_addmastery(sd,target,wd.damage,0);
+ wd.damage = battle->add_mastery(sd,target,wd.damage,0);
if (flag.lh)
- wd.damage2 = battle_addmastery(sd,target,wd.damage2,1);
+ wd.damage2 = battle->add_mastery(sd,target,wd.damage2,1);
if (sc && sc->data[SC_MIRACLE]) i = 2; //Star anger
else
ARR_FIND(0, MAX_PC_FEELHATE, i, t_class == sd->hate_mob[i]);
- if (i < MAX_PC_FEELHATE && (skill=pc_checkskill(sd,sg_info[i].anger_id)))
- {
+ if (i < MAX_PC_FEELHATE && (temp=pc_checkskill(sd,sg_info[i].anger_id))) {
skillratio = sd->status.base_level + sstatus->dex + sstatus->luk;
if (i == 2) skillratio += sstatus->str; //Star Anger
- if (skill<4)
- skillratio /= 12-3*skill;
+ if (temp<4)
+ skillratio /= 12-3*temp;
ATK_ADDRATE(skillratio);
}
- if (skill_id == NJ_SYURIKEN && (skill = pc_checkskill(sd,NJ_TOBIDOUGU)) > 0)
- ATK_ADD(3*skill);
- if (skill_id == NJ_KUNAI)
+ if (skill_id == NJ_SYURIKEN && (temp = pc_checkskill(sd,NJ_TOBIDOUGU)) > 0) {
+ ATK_ADD(3*temp);
+ } else if (skill_id == NJ_KUNAI)
ATK_ADD(60);
}
} //Here ends flag.hit section, the rest of the function applies to both hitting and missing attacks
else if(wd.div_ < 0) //Since the attack missed...
wd.div_ *= -1;
- if(sd && (skill=pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
- ATK_ADD(skill*2);
+ if(sd && (temp=pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
+ ATK_ADD(temp*2);
if(skill_id==TF_POISON)
ATK_ADD(15*skill_lv);
@@ -3357,23 +3346,22 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
{ //Elemental attribute fix
if( wd.damage > 0 )
{
- wd.damage=battle_attr_fix(src,target,wd.damage,s_ele,tstatus->def_ele, tstatus->ele_lv);
+ wd.damage=battle->attr_fix(src,target,wd.damage,s_ele,tstatus->def_ele, tstatus->ele_lv);
if( skill_id == MC_CARTREVOLUTION ) //Cart Revolution applies the element fix once more with neutral element
- wd.damage = battle_attr_fix(src,target,wd.damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
+ wd.damage = battle->attr_fix(src,target,wd.damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
if( skill_id== GS_GROUNDDRIFT ) //Additional 50*lv Neutral damage.
- wd.damage += battle_attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
+ wd.damage += battle->attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
}
if( flag.lh && wd.damage2 > 0 )
- wd.damage2 = battle_attr_fix(src,target,wd.damage2,s_ele_,tstatus->def_ele, tstatus->ele_lv);
+ wd.damage2 = battle->attr_fix(src,target,wd.damage2,s_ele_,tstatus->def_ele, tstatus->ele_lv);
if( sc && sc->data[SC_WATK_ELEMENT] )
{ // Descriptions indicate this means adding a percent of a normal attack in another element. [Skotlex]
- int damage = battle_calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, (flag.arrow?2:0)) * sc->data[SC_WATK_ELEMENT]->val2 / 100;
- wd.damage += battle_attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
+ int damage = battle->calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, (flag.arrow?2:0)) * sc->data[SC_WATK_ELEMENT]->val2 / 100;
+ wd.damage += battle->attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
- if( flag.lh )
- {
- damage = battle_calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, sd, (flag.arrow?2:0)) * sc->data[SC_WATK_ELEMENT]->val2 / 100;
- wd.damage2 += battle_attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
+ if( flag.lh ) {
+ damage = battle->calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, sd, (flag.arrow?2:0)) * sc->data[SC_WATK_ELEMENT]->val2 / 100;
+ wd.damage2 += battle->attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
}
}
#ifdef RENEWAL
@@ -3388,9 +3376,26 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if(skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS)
return wd; //Enough, rest is not needed.
-
- if (sd)
- {
+#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
+ if( target && skill_id ) {
+ for(i = 0; i < map[target->m].zone->capped_skills_count; i++) {
+ if( skill_id == map[target->m].zone->capped_skills[i]->nameid && (map[target->m].zone->capped_skills[i]->type & target->type) ) {
+ if( target->type == BL_MOB && map[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
+ if( (((TBL_MOB*)target)->status.mode&MD_BOSS) && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_BOSS) )
+ continue;
+ if( ((TBL_MOB*)target)->special_state.clone && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_CLONE) )
+ continue;
+ }
+ if( wd.damage > map[target->m].zone->capped_skills[i]->cap )
+ wd.damage = map[target->m].zone->capped_skills[i]->cap;
+ if( wd.damage2 > map[target->m].zone->capped_skills[i]->cap )
+ wd.damage2 = map[target->m].zone->capped_skills[i]->cap;
+ break;
+ }
+ }
+ }
+#endif
+ if (sd) {
if (skill_id != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus.
ATK_ADD2(wd.div_*sd->right_weapon.star, wd.div_*sd->left_weapon.star);
if (skill_id==MO_FINGEROFFENSIVE) { //The finger offensive spheres on moment of attack do count. [Skotlex]
@@ -3400,24 +3405,26 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
}
//Card Fix, sd side
- wd.damage = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, 2, wd.flag);
+ wd.damage = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, 2, wd.flag);
if( flag.lh )
- wd.damage2 = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage2, 3, wd.flag);
-
+ wd.damage2 = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage2, 3, wd.flag);
+#ifdef RENEWAL
+ if( flag.cri )
+ ATK_ADDRATE(sd->bonus.crit_atk_rate>=100?sd->bonus.crit_atk_rate-60:40);
+#endif
if( skill_id == CR_SHIELDBOOMERANG || skill_id == PA_SHIELDCHAIN )
{ //Refine bonus applies after cards and elements.
short index= sd->equip_index[EQI_HAND_L];
if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR )
ATK_ADD(10*sd->status.inventory[index].refine);
}
- } //if (sd)
+ }
//Card Fix, tsd side
- if(tsd)
- wd.damage = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, flag.lh, wd.flag);
+ if(tsd) //if player on player then it was already measured above
+ wd.damage = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, flag.lh, wd.flag);
- if( flag.infdef )
- { //Plants receive 1 damage when hit
+ if( flag.infdef ) { //Plants receive 1 damage when hit
short class_ = status_get_class(target);
if( flag.hit || wd.damage > 0 )
wd.damage = wd.div_; // In some cases, right hand no need to have a weapon to increase damage
@@ -3425,12 +3432,12 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
wd.damage2 = wd.div_;
if( flag.hit && class_ == MOBID_EMPERIUM ) {
if(wd.damage2 > 0) {
- wd.damage2 = battle_attr_fix(src,target,wd.damage2,s_ele_,tstatus->def_ele, tstatus->ele_lv);
- wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
+ wd.damage2 = battle->attr_fix(src,target,wd.damage2,s_ele_,tstatus->def_ele, tstatus->ele_lv);
+ wd.damage2 = battle->calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
}
else if(wd.damage > 0) {
- wd.damage = battle_attr_fix(src,target,wd.damage,s_ele_,tstatus->def_ele, tstatus->ele_lv);
- wd.damage = battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
+ wd.damage = battle->attr_fix(src,target,wd.damage,s_ele_,tstatus->def_ele, tstatus->ele_lv);
+ wd.damage = battle->calc_gvg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
}
return wd;
}
@@ -3447,22 +3454,22 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
flag.lh=0;
} else if(flag.rh && flag.lh) { //Dual-wield
if (wd.damage) {
- if( (skill = pc_checkskill(sd,AS_RIGHT)) )
- ATK_RATER(50 + (skill * 10))
- else if( (skill = pc_checkskill(sd,KO_RIGHT)) )
- ATK_RATER(70 + (skill * 10))
+ if( (temp = pc_checkskill(sd,AS_RIGHT)) )
+ ATK_RATER(50 + (temp * 10))
+ else if( (temp = pc_checkskill(sd,KO_RIGHT)) )
+ ATK_RATER(70 + (temp * 10))
if(wd.damage < 1) wd.damage = 1;
}
if (wd.damage2) {
- if( (skill = pc_checkskill(sd,AS_LEFT)) )
- ATK_RATEL(30 + (skill * 10))
- else if( (skill = pc_checkskill(sd,KO_LEFT)) )
- ATK_RATEL(50 + (skill * 10))
+ if( (temp = pc_checkskill(sd,AS_LEFT)) )
+ ATK_RATEL(30 + (temp * 10))
+ else if( (temp = pc_checkskill(sd,KO_LEFT)) )
+ ATK_RATEL(50 + (temp * 10))
if(wd.damage2 < 1) wd.damage2 = 1;
}
} else if(sd->status.weapon == W_KATAR && !skill_id) { //Katars (offhand damage only applies to normal attacks, tested on Aegis 10.2)
- skill = pc_checkskill(sd,TF_DOUBLE);
- wd.damage2 = (int64)wd.damage * (1 + (skill * 2))/100;
+ temp = pc_checkskill(sd,TF_DOUBLE);
+ wd.damage2 = wd.damage * (1 + (temp * 2))/100;
if(wd.damage && !wd.damage2) wd.damage2 = 1;
flag.lh = 1;
@@ -3479,29 +3486,29 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
{ //There is a total damage value
if(!wd.damage2)
{
- wd.damage = battle_calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv);
+ wd.damage = battle->calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv);
if( map_flag_gvg2(target->m) )
- wd.damage=battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
+ wd.damage=battle->calc_gvg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
else if( map[target->m].flag.battleground )
- wd.damage=battle_calc_bg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
+ wd.damage=battle->calc_bg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
}
else if(!wd.damage)
{
- wd.damage2 = battle_calc_damage(src,target,&wd,wd.damage2,skill_id,skill_lv);
+ wd.damage2 = battle->calc_damage(src,target,&wd,wd.damage2,skill_id,skill_lv);
if( map_flag_gvg2(target->m) )
- wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
+ wd.damage2 = battle->calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
else if( map[target->m].flag.battleground )
- wd.damage = battle_calc_bg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
+ wd.damage = battle->calc_bg_damage(src,target,wd.damage2,wd.div_,skill_id,skill_lv,wd.flag);
}
else
{
int d1 = wd.damage + wd.damage2,d2 = wd.damage2;
- wd.damage = battle_calc_damage(src,target,&wd,d1,skill_id,skill_lv);
+ wd.damage = battle->calc_damage(src,target,&wd,d1,skill_id,skill_lv);
if( map_flag_gvg2(target->m) )
- wd.damage = battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
+ wd.damage = battle->calc_gvg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
else if( map[target->m].flag.battleground )
- wd.damage = battle_calc_bg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
- wd.damage2 = (int64)d2*100/d1 * wd.damage/100;
+ wd.damage = battle->calc_bg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
+ wd.damage2 = d2*100/d1 * wd.damage/100;
if(wd.damage > 1 && wd.damage2 < 1) wd.damage2 = 1;
wd.damage-=wd.damage2;
}
@@ -3516,13 +3523,13 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
rnd()%100 < tsc->data[SC_REJECTSWORD]->val2
) {
ATK_RATER(50)
- status_fix_damage(target,src,wd.damage,clif_damage(target,src,gettick(),0,0,wd.damage,0,0,0));
- clif_skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_REJECTSWORD]->val1,1);
+ status_fix_damage(target,src,wd.damage,clif->damage(target,src,gettick(),0,0,wd.damage,0,0,0));
+ clif->skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_REJECTSWORD]->val1,1);
if( --(tsc->data[SC_REJECTSWORD]->val3) <= 0 )
status_change_end(target, SC_REJECTSWORD, INVALID_TIMER);
}
if(skill_id == ASC_BREAKER) { //Breaker's int-based damage (a misc attack?)
- struct Damage md = battle_calc_misc_attack(src, target, skill_id, skill_lv, wflag);
+ struct Damage md = battle->calc_misc_attack(src, target, skill_id, skill_lv, wflag);
wd.damage += md.damage;
}
if( sc ) {
@@ -3531,7 +3538,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
int hp= sstatus->max_hp;
if (sd && tsd) {
hp = 8*hp/100;
- if (((int64)sstatus->hp * 100) <= ((int64)sstatus->max_hp * 20))
+ if ((sstatus->hp * 100) <= (sstatus->max_hp * 20))
hp = sstatus->hp;
} else
hp = 2*hp/100; //2% hp loss per hit
@@ -3552,7 +3559,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);
}
if( skill_id == LG_RAYOFGENESIS ) {
- struct Damage md = battle_calc_magic_attack(src, target, skill_id, skill_lv, wflag);
+ struct Damage md = battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag);
wd.damage += md.damage;
}
@@ -3562,8 +3569,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
/*==========================================
* battle_calc_magic_attack [DracoRPG]
*------------------------------------------*/
-struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag)
-{
+struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) {
int i, nk;
short s_ele = 0;
unsigned int skillratio = 100; //Skill dmg modifiers.
@@ -3589,13 +3595,13 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
//Initial Values
ad.damage = 1;
- ad.div_=skill_get_num(skill_id,skill_lv);
- ad.amotion=skill_get_inf(skill_id)&INF_GROUND_SKILL?0:sstatus->amotion; //Amotion should be 0 for ground skills.
+ ad.div_=skill->get_num(skill_id,skill_lv);
+ ad.amotion=skill->get_inf(skill_id)&INF_GROUND_SKILL?0:sstatus->amotion; //Amotion should be 0 for ground skills.
ad.dmotion=tstatus->dmotion;
- ad.blewcount = skill_get_blewcount(skill_id,skill_lv);
+ ad.blewcount = skill->get_blewcount(skill_id,skill_lv);
ad.flag=BF_MAGIC|BF_SKILL;
ad.dmg_lv=ATK_DEF;
- nk = skill_get_nk(skill_id);
+ nk = skill->get_nk(skill_id);
flag.imdef = nk&NK_IGNORE_DEF?1:0;
sd = BL_CAST(BL_PC, src);
@@ -3604,7 +3610,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
tsc = status_get_sc(target);
//Initialize variables that will be used afterwards
- s_ele = skill_get_ele(skill_id, skill_lv);
+ s_ele = skill->get_ele(skill_id, skill_lv);
if (s_ele == -1){ // pl=-1 : the skill takes the weapon's element
s_ele = sstatus->rhw.ele;
@@ -3629,11 +3635,11 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
//Set miscellaneous data that needs be filled
if(sd) {
sd->state.arrow_atk = 0;
- ad.blewcount += battle_blewcount_bonus(sd, skill_id);
+ ad.blewcount += battle->blewcount_bonus(sd, skill_id);
}
//Skill Range Criteria
- ad.flag |= battle_range_type(src, target, skill_id, skill_lv);
+ ad.flag |= battle->range_type(src, target, skill_id, skill_lv);
flag.infdef=(tstatus->mode&MD_PLANT?1:0);
if( target->type == BL_SKILL){
TBL_SKILL *su = (TBL_SKILL*)target;
@@ -3646,7 +3652,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
case MG_FIREWALL:
case NJ_KAENSIN:
ad.dmotion = 0; //No flinch animation.
- if ( tstatus->def_ele == ELE_FIRE || battle_check_undead(tstatus->race, tstatus->def_ele) )
+ if ( tstatus->def_ele == ELE_FIRE || battle->check_undead(tstatus->race, tstatus->def_ele) )
ad.blewcount = 0; //No knockback
break;
case PR_SANCTUARY:
@@ -3675,7 +3681,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
* Arch Bishop
**/
case AB_HIGHNESSHEAL:
- ad.damage = skill_calc_heal(src, target, skill_id, skill_lv, false);
+ ad.damage = skill->calc_heal(src, target, skill_id, skill_lv, false);
break;
case PR_ASPERSIO:
ad.damage = 40;
@@ -3727,7 +3733,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if(mflag>0)
ad.damage/= mflag;
else
- ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill_get_name(skill_id));
+ ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id));
}
switch(skill_id){
@@ -3742,7 +3748,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
#endif
break;
case MG_SOULSTRIKE:
- if (battle_check_undead(tstatus->race,tstatus->def_ele))
+ if (battle->check_undead(tstatus->race,tstatus->def_ele))
skillratio += 5*skill_lv;
break;
case MG_FIREWALL:
@@ -3946,7 +3952,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
int16 lv = skill_lv;
int bandingBonus = 0;
if( sc && sc->data[SC_BANDING] )
- bandingBonus = 200 * (sd ? skill_check_pc_partner(sd,skill_id,&lv,skill_get_splash(skill_id,skill_lv),0) : 1);
+ bandingBonus = 200 * (sd ? skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),0) : 1);
skillratio = ((300 * skill_lv) + bandingBonus) * (sd ? sd->status.job_level : 1) / 25;
}
break;
@@ -4080,13 +4086,35 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
MATK_ADD(50);
}
}
+#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
+ if( target && skill_id ) {
+ for(i = 0; i < map[target->m].zone->capped_skills_count; i++) {
+ if( skill_id == map[target->m].zone->capped_skills[i]->nameid && (map[target->m].zone->capped_skills[i]->type & target->type) ) {
+ if( target->type == BL_MOB && map[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
+ if( (((TBL_MOB*)target)->status.mode&MD_BOSS) && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_BOSS) )
+ continue;
+ if( ((TBL_MOB*)target)->special_state.clone && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_CLONE) )
+ continue;
+ }
+ if( ad.damage > map[target->m].zone->capped_skills[i]->cap )
+ ad.damage = map[target->m].zone->capped_skills[i]->cap;
+ if( ad.damage2 > map[target->m].zone->capped_skills[i]->cap )
+ ad.damage2 = map[target->m].zone->capped_skills[i]->cap;
+ break;
+ }
+ }
+ }
+#endif
#ifdef RENEWAL
- ad.damage = battle_calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
+ ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
#endif
if(sd) {
//Damage bonuses
if ((i = pc_skillatk_bonus(sd, skill_id)))
- ad.damage += (int64)ad.damage*i/100;
+ ad.damage += ad.damage*i/100;
+
+ if( (i = battle->adjust_skill_damage(src->m,skill_id)) )
+ MATK_RATE(i);
//Ignore Defense?
if (!flag.imdef && (
@@ -4134,7 +4162,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if(mflag>0)
ad.damage+= (sstatus->rhw.atk2*skillratio/100)/mflag;
else
- ShowError("Zero range by %d:%s, divide per 0 avoided!\n", skill_id, skill_get_name(skill_id));
+ ShowError("Zero range by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id));
}
if(ad.damage<1)
@@ -4158,12 +4186,12 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
if (!(nk&NK_NO_ELEFIX))
- ad.damage=battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
+ ad.damage=battle->attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
if( skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS )
{ //Apply the physical part of the skill's damage. [Skotlex]
- struct Damage wd = battle_calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
- ad.damage = battle_attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv) * (100 + 40*skill_lv)/100;
+ struct Damage wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
+ ad.damage = battle->attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv) * (100 + 40*skill_lv)/100;
if( src == target )
{
if( src->type == BL_PC )
@@ -4174,7 +4202,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
#ifndef RENEWAL
- ad.damage = battle_calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
+ ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
#endif
}
@@ -4183,15 +4211,15 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if (flag.infdef && ad.damage)
ad.damage = ad.damage>0?1:-1;
- ad.damage=battle_calc_damage(src,target,&ad,ad.damage,skill_id,skill_lv);
+ ad.damage=battle->calc_damage(src,target,&ad,ad.damage,skill_id,skill_lv);
if( map_flag_gvg2(target->m) )
- ad.damage=battle_calc_gvg_damage(src,target,ad.damage,ad.div_,skill_id,skill_lv,ad.flag);
+ ad.damage=battle->calc_gvg_damage(src,target,ad.damage,ad.div_,skill_id,skill_lv,ad.flag);
else if( map[target->m].flag.battleground )
- ad.damage=battle_calc_bg_damage(src,target,ad.damage,ad.div_,skill_id,skill_lv,ad.flag);
+ ad.damage=battle->calc_bg_damage(src,target,ad.damage,ad.div_,skill_id,skill_lv,ad.flag);
switch( skill_id ) { /* post-calc modifiers */
case SO_VARETYR_SPEAR: { // Physical damage.
- struct Damage wd = battle_calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
+ struct Damage wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
if(!flag.infdef && ad.damage > 1)
ad.damage += wd.damage;
break;
@@ -4205,9 +4233,8 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
/*==========================================
* Calculate Misc dammage for skill_id
*------------------------------------------*/
-struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag)
-{
- int skill;
+struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) {
+ int temp;
short i, nk;
short s_ele;
@@ -4224,31 +4251,31 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
}
//Some initial values
- md.amotion=skill_get_inf(skill_id)&INF_GROUND_SKILL?0:sstatus->amotion;
+ md.amotion=skill->get_inf(skill_id)&INF_GROUND_SKILL?0:sstatus->amotion;
md.dmotion=tstatus->dmotion;
- md.div_=skill_get_num( skill_id,skill_lv );
- md.blewcount=skill_get_blewcount(skill_id,skill_lv);
+ md.div_=skill->get_num( skill_id,skill_lv );
+ md.blewcount=skill->get_blewcount(skill_id,skill_lv);
md.dmg_lv=ATK_DEF;
md.flag=BF_MISC|BF_SKILL;
- nk = skill_get_nk(skill_id);
+ nk = skill->get_nk(skill_id);
sd = BL_CAST(BL_PC, src);
tsd = BL_CAST(BL_PC, target);
if(sd) {
sd->state.arrow_atk = 0;
- md.blewcount += battle_blewcount_bonus(sd, skill_id);
+ md.blewcount += battle->blewcount_bonus(sd, skill_id);
}
- s_ele = skill_get_ele(skill_id, skill_lv);
+ s_ele = skill->get_ele(skill_id, skill_lv);
if (s_ele < 0 && s_ele != -3) //Attack that takes weapon's element for misc attacks? Make it neutral [Skotlex]
s_ele = ELE_NEUTRAL;
else if (s_ele == -3) //Use random element
s_ele = rnd()%ELE_MAX;
//Skill Range Criteria
- md.flag |= battle_range_type(src, target, skill_id, skill_lv);
+ md.flag |= battle->range_type(src, target, skill_id, skill_lv);
switch( skill_id )
{
@@ -4276,20 +4303,19 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
case HT_BLITZBEAT:
case SN_FALCONASSAULT:
//Blitz-beat Damage.
- if(!sd || (skill = pc_checkskill(sd,HT_STEELCROW)) <= 0)
- skill=0;
- md.damage=(sstatus->dex/10+sstatus->int_/2+skill*3+40)*2;
+ if(!sd || (temp = pc_checkskill(sd,HT_STEELCROW)) <= 0)
+ temp=0;
+ md.damage=(sstatus->dex/10+sstatus->int_/2+temp*3+40)*2;
if(mflag > 1) //Autocasted Blitz.
nk|=NK_SPLASHSPLIT;
- if (skill_id == SN_FALCONASSAULT)
- {
+ if (skill_id == SN_FALCONASSAULT) {
//Div fix of Blitzbeat
- skill = skill_get_num(HT_BLITZBEAT, 5);
- damage_div_fix(md.damage, skill);
+ temp = skill->get_num(HT_BLITZBEAT, 5);
+ damage_div_fix(md.damage, temp);
//Falcon Assault Modifier
- md.damage=(int64)md.damage*(150+70*skill_lv)/100;
+ md.damage=md.damage*(150+70*skill_lv)/100;
}
break;
case TF_THROWSTONE:
@@ -4318,7 +4344,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
break;
case CR_ACIDDEMONSTRATION: // updated the formula based on a Japanese formula found to be exact [Reddozen]
if(tstatus->vit+sstatus->int_) //crash fix
- md.damage = (int)((int64)7*tstatus->vit*sstatus->int_*sstatus->int_ / (10*(tstatus->vit+sstatus->int_)));
+ md.damage = (int)(7*tstatus->vit*sstatus->int_*sstatus->int_ / (10*(tstatus->vit+sstatus->int_)));
else
md.damage = 0;
if (tsd) md.damage>>=1;
@@ -4329,7 +4355,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
break;
case NJ_ZENYNAGE:
case KO_MUCHANAGE:
- md.damage = skill_get_zeny(skill_id ,skill_lv);
+ md.damage = skill->get_zeny(skill_id ,skill_lv);
if (!md.damage) md.damage = 2;
md.damage = rand()%md.damage + md.damage / (skill_id==NJ_ZENYNAGE?1:2) ;
if (is_boss(target))
@@ -4341,7 +4367,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
md.damage = sd?sd->status.job_level:status_get_lv(src);
break;
case HVAN_EXPLOSION: //[orn]
- md.damage = (int64)sstatus->max_hp * (50 + 50 * skill_lv) / 100;
+ md.damage = sstatus->max_hp * (50 + 50 * skill_lv) / 100;
break ;
case ASC_BREAKER:
md.damage = 500+rnd()%500 + 5*skill_lv * sstatus->int_;
@@ -4352,12 +4378,12 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
md.dmotion = 0; //No flinch animation.
break;
case NPC_EVILLAND:
- md.damage = skill_calc_heal(src,target,skill_id,skill_lv,false);
+ md.damage = skill->calc_heal(src,target,skill_id,skill_lv,false);
break;
case RK_DRAGONBREATH:
md.damage = ((status_get_hp(src) / 50) + (status_get_max_sp(src) / 4)) * skill_lv;
RE_LVL_MDMOD(150);
- if (sd) md.damage = (int64)md.damage * (100 + 5 * (pc_checkskill(sd,RK_DRAGONTRAINING) - 1)) / 100;
+ if (sd) md.damage = md.damage * (100 + 5 * (pc_checkskill(sd,RK_DRAGONTRAINING) - 1)) / 100;
md.flag |= BF_LONG|BF_WEAPON;
break;
/**
@@ -4372,11 +4398,11 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
{
int researchskill_lv = pc_checkskill(sd,RA_RESEARCHTRAP);
if(researchskill_lv)
- md.damage = (int64)md.damage * 20 * researchskill_lv / (skill_id == RA_CLUSTERBOMB?50:100);
+ md.damage = md.damage * 20 * researchskill_lv / (skill_id == RA_CLUSTERBOMB?50:100);
else
md.damage = 0;
}else
- md.damage = (int64)md.damage * 200 / (skill_id == RA_CLUSTERBOMB?50:100);
+ md.damage = md.damage * 200 / (skill_id == RA_CLUSTERBOMB?50:100);
break;
/**
@@ -4399,9 +4425,9 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
break;
case KO_HAPPOKUNAI:
{
- struct Damage wd = battle_calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
+ struct Damage wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
short totaldef = tstatus->def2 + (short)status_get_def(target);
- md.damage = (int64)wd.damage * 60 * (5 + skill_lv) / 100;
+ md.damage = wd.damage * 60 * (5 + skill_lv) / 100;
md.damage -= totaldef;
}
break;
@@ -4414,7 +4440,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
if(mflag>0)
md.damage/= mflag;
else
- ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill_get_name(skill_id));
+ ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id));
}
damage_div_fix(md.damage, md.div_);
@@ -4462,11 +4488,32 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
md.dmg_lv=ATK_FLEE;
}
}
-
- md.damage = battle_calc_cardfix(BF_MISC, src, target, nk, s_ele, 0, md.damage, 0, md.flag);
+#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
+ if( target && skill_id ) {
+ for(i = 0; i < map[target->m].zone->capped_skills_count; i++) {
+ if( skill_id == map[target->m].zone->capped_skills[i]->nameid && (map[target->m].zone->capped_skills[i]->type & target->type) ) {
+ if( target->type == BL_MOB && map[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
+ if( (((TBL_MOB*)target)->status.mode&MD_BOSS) && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_BOSS) )
+ continue;
+ if( ((TBL_MOB*)target)->special_state.clone && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_CLONE) )
+ continue;
+ }
+ if( md.damage > map[target->m].zone->capped_skills[i]->cap )
+ md.damage = map[target->m].zone->capped_skills[i]->cap;
+ if( md.damage2 > map[target->m].zone->capped_skills[i]->cap )
+ md.damage2 = map[target->m].zone->capped_skills[i]->cap;
+ break;
+ }
+ }
+ }
+#endif
+ md.damage = battle->calc_cardfix(BF_MISC, src, target, nk, s_ele, 0, md.damage, 0, md.flag);
if (sd && (i = pc_skillatk_bonus(sd, skill_id)))
- md.damage += (int64)md.damage*i/100;
+ md.damage += md.damage*i/100;
+
+ if( (i = battle->adjust_skill_damage(src->m,skill_id)) )
+ md.damage = md.damage * i / 100;
if(md.damage < 0)
md.damage = 0;
@@ -4490,13 +4537,13 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
}
if(!(nk&NK_NO_ELEFIX))
- md.damage=battle_attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
+ md.damage=battle->attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
- md.damage=battle_calc_damage(src,target,&md,md.damage,skill_id,skill_lv);
+ md.damage=battle->calc_damage(src,target,&md,md.damage,skill_id,skill_lv);
if( map_flag_gvg2(target->m) )
- md.damage=battle_calc_gvg_damage(src,target,md.damage,md.div_,skill_id,skill_lv,md.flag);
+ md.damage=battle->calc_gvg_damage(src,target,md.damage,md.div_,skill_id,skill_lv,md.flag);
else if( map[target->m].flag.battleground )
- md.damage=battle_calc_bg_damage(src,target,md.damage,md.div_,skill_id,skill_lv,md.flag);
+ md.damage=battle->calc_bg_damage(src,target,md.damage,md.div_,skill_id,skill_lv,md.flag);
switch( skill_id ) {
case RA_FIRINGTRAP:
@@ -4505,7 +4552,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
case RA_CLUSTERBOMB:
{
struct Damage wd;
- wd = battle_calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
+ wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
md.damage += wd.damage;
}
break;
@@ -4521,35 +4568,55 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
return md;
}
/*==========================================
- * Battle main entry, from skill_attack
+ * Battle main entry, from skill->attack
*------------------------------------------*/
struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,uint16 skill_id,uint16 skill_lv,int count)
{
struct Damage d;
switch(attack_type) {
- case BF_WEAPON: d = battle_calc_weapon_attack(bl,target,skill_id,skill_lv,count); break;
- case BF_MAGIC: d = battle_calc_magic_attack(bl,target,skill_id,skill_lv,count); break;
- case BF_MISC: d = battle_calc_misc_attack(bl,target,skill_id,skill_lv,count); break;
+ case BF_WEAPON: d = battle->calc_weapon_attack(bl,target,skill_id,skill_lv,count); break;
+ case BF_MAGIC: d = battle->calc_magic_attack(bl,target,skill_id,skill_lv,count); break;
+ case BF_MISC: d = battle->calc_misc_attack(bl,target,skill_id,skill_lv,count); break;
default:
ShowError("battle_calc_attack: unknown attack type! %d\n",attack_type);
memset(&d,0,sizeof(d));
break;
}
- if( d.damage + d.damage2 < 1 )
- { //Miss/Absorbed
+
+#ifdef HMAP_ZONE_DAMAGE_CAP_TYPE
+ if( target && skill_id ) {
+ int i;
+ for(i = 0; i < map[target->m].zone->capped_skills_count; i++) {
+ if( skill_id == map[target->m].zone->capped_skills[i]->nameid && (map[target->m].zone->capped_skills[i]->type & target->type) ) {
+ if( target->type == BL_MOB && map[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
+ if( (((TBL_MOB*)target)->status.mode&MD_BOSS) && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_BOSS) )
+ continue;
+ if( ((TBL_MOB*)target)->special_state.clone && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_CLONE) )
+ continue;
+ }
+ if( d.damage > map[target->m].zone->capped_skills[i]->cap )
+ d.damage = map[target->m].zone->capped_skills[i]->cap;
+ if( d.damage2 > map[target->m].zone->capped_skills[i]->cap )
+ d.damage2 = map[target->m].zone->capped_skills[i]->cap;
+ break;
+ }
+ }
+ }
+#endif
+
+ if( d.damage + d.damage2 < 1 ) { //Miss/Absorbed
//Weapon attacks should go through to cause additional effects.
if (d.dmg_lv == ATK_DEF /*&& attack_type&(BF_MAGIC|BF_MISC)*/) // Isn't it that additional effects don't apply if miss?
d.dmg_lv = ATK_MISS;
d.dmotion = 0;
- }
- else // Some skills like Weaponry Research will cause damage even if attack is dodged
+ } else // Some skills like Weaponry Research will cause damage even if attack is dodged
d.dmg_lv = ATK_DEF;
return d;
}
//Calculates BF_WEAPON returned damage.
int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int *dmg, int flag, uint16 skill_id){
- struct map_session_data* sd = NULL;
+ struct map_session_data* sd;
int rdamage = 0, damage = *dmg;
struct status_change* sc;
@@ -4557,40 +4624,40 @@ int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int
sc = status_get_sc(bl);
if( sc && sc->data[SC_REFLECTDAMAGE] ) {
- int max_damage = (int64)status_get_max_hp(bl) * status_get_lv(bl) / 100;
- rdamage = (int64)(*dmg) * sc->data[SC_REFLECTDAMAGE]->val2 / 100;
+ int max_damage = status_get_max_hp(bl) * status_get_lv(bl) / 100;
+ rdamage = (*dmg) * sc->data[SC_REFLECTDAMAGE]->val2 / 100;
if( rdamage > max_damage ) rdamage = max_damage;
}else if( sc && sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ){
//ATK [{(Target HP / 100) x Skill Level} x Caster Base Level / 125] % + [Received damage x {1 + (Skill Level x 0.2)}]
- int ratio = (int64)(status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * status_get_lv(bl) / 125;
+ int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * status_get_lv(bl) / 125;
if (ratio > 5000) ratio = 5000; // Maximum of 5000% ATK
- rdamage = (int64)rdamage * ratio / 100 + (*dmg) * (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10;
- skill_blown(bl, src, skill_get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit_getdir(src), 0);
- clif_skill_damage(bl, src, gettick(), status_get_amotion(src), 0, rdamage,
+ rdamage = rdamage * ratio / 100 + (*dmg) * (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10;
+ skill->blown(bl, src, skill->get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit_getdir(src), 0);
+ clif->skill_damage(bl, src, gettick(), status_get_amotion(src), 0, rdamage,
1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does
- clif_damage(src, bl, gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, 0, 0);
+ clif->damage(src, bl, gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, 0, 0);
status_damage(src, bl, status_damage(bl, src, rdamage, 0, 0, 1)/10, 0, 0, 1);
status_change_end(bl, SC_CRESCENTELBOW, INVALID_TIMER);
return 0; // Just put here to minimize redundancy
}else if (flag & BF_SHORT) {//Bounces back part of the damage.
if ( sd && sd->bonus.short_weapon_damage_return ) {
- rdamage += (int64)damage * sd->bonus.short_weapon_damage_return / 100;
+ rdamage += damage * sd->bonus.short_weapon_damage_return / 100;
if(rdamage < 1) rdamage = 1;
}
if( sc && sc->count ) {
if ( sc->data[SC_REFLECTSHIELD] && skill_id != WS_CARTTERMINATION ) {
- rdamage += (int64)damage * sc->data[SC_REFLECTSHIELD]->val2 / 100;
+ rdamage += damage * sc->data[SC_REFLECTSHIELD]->val2 / 100;
if (rdamage < 1) rdamage = 1;
}
if(sc->data[SC_DEATHBOUND] && skill_id != WS_CARTTERMINATION && !(src->type == BL_MOB && is_boss(src)) ) {
uint8 dir = map_calc_dir(bl,src->x,src->y),
t_dir = unit_getdir(bl);
- int rd1 = 0;
if( distance_bl(src,bl) <= 0 || !map_check_dir(dir,t_dir) ) {
- rd1 = (int64)min(damage,status_get_max_hp(bl)) * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage.
- *dmg = (int64)rd1 * 30 / 100; // Received damage = 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);
+ int rd1 = 0;
+ rd1 = min(damage,status_get_max_hp(bl)) * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage.
+ *dmg = rd1 * 30 / 100; // Received damage = 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,INVALID_TIMER);
rdamage += rd1;
if (rdamage < 1) rdamage = 1;
@@ -4599,7 +4666,7 @@ int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int
}
} else {
if (sd && sd->bonus.long_weapon_damage_return) {
- rdamage += (int64)damage * sd->bonus.long_weapon_damage_return / 100;
+ rdamage += damage * sd->bonus.long_weapon_damage_return / 100;
if (rdamage < 1) rdamage = 1;
}
}
@@ -4627,11 +4694,11 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int rdamage, int ldamage,
hp = wd->hp_drain[type].value;
if (wd->hp_drain[type].rate)
- hp += battle_calc_drain(*damage, wd->hp_drain[type].rate, wd->hp_drain[type].per);
+ hp += battle->calc_drain(*damage, wd->hp_drain[type].rate, wd->hp_drain[type].per);
sp = wd->sp_drain[type].value;
if (wd->sp_drain[type].rate)
- sp += battle_calc_drain(*damage, wd->sp_drain[type].rate, wd->sp_drain[type].per);
+ sp += battle->calc_drain(*damage, wd->sp_drain[type].rate, wd->sp_drain[type].per);
if (hp) {
if (wd->hp_drain[type].type)
@@ -4675,16 +4742,17 @@ int battle_damage_area( struct block_list *bl, va_list ap) {
damage=va_arg(ap,int);
if( bl->type == BL_MOB && ((TBL_MOB*)bl)->class_ == MOBID_EMPERIUM )
return 0;
- if( bl != src && battle_check_target(src,bl,BCT_ENEMY) > 0 ) {
+ if( bl != src && battle->check_target(src,bl,BCT_ENEMY) > 0 ) {
map_freeblock_lock();
if( src->type == BL_PC )
- battle_drain((TBL_PC*)src, bl, damage, damage, status_get_race(bl), is_boss(bl));
+ battle->drain((TBL_PC*)src, bl, damage, damage, status_get_race(bl), is_boss(bl));
if( amotion )
- battle_delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0);
+ battle->delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0,true);
else
status_fix_damage(src,bl,damage,0);
- clif_damage(bl,bl,tick,amotion,dmotion,damage,1,ATK_BLOCK,0);
- skill_additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
+ clif->damage(bl,bl,tick,amotion,dmotion,damage,1,ATK_BLOCK,0);
+ if( !(src && src->type == BL_PC && ((TBL_PC*)src)->state.autocast) )
+ skill->additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
map_freeblock_unlock();
}
@@ -4728,7 +4796,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
{
int index = sd->equip_index[EQI_AMMO];
if (index<0) {
- clif_arrow_fail(sd,0);
+ clif->arrow_fail(sd,0);
return ATK_NONE;
}
//Ammo check by Ishizu-chan
@@ -4736,7 +4804,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
switch (sd->status.weapon) {
case W_BOW:
if (sd->inventory_data[index]->look != A_ARROW) {
- clif_arrow_fail(sd,0);
+ clif->arrow_fail(sd,0);
return ATK_NONE;
}
break;
@@ -4745,13 +4813,13 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
case W_GATLING:
case W_SHOTGUN:
if (sd->inventory_data[index]->look != A_BULLET) {
- clif_arrow_fail(sd,0);
+ clif->arrow_fail(sd,0);
return ATK_NONE;
}
break;
case W_GRENADE:
if (sd->inventory_data[index]->look != A_GRENADE) {
- clif_arrow_fail(sd,0);
+ clif->arrow_fail(sd,0);
return ATK_NONE;
}
break;
@@ -4772,10 +4840,10 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if(dist <= 0 || (!map_check_dir(dir,t_dir) && dist <= tstatus->rhw.range+1))
{
uint16 skill_lv = tsc->data[SC_AUTOCOUNTER]->val1;
- clif_skillcastcancel(target); //Remove the casting bar. [Skotlex]
- clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
+ clif->skillcastcancel(target); //Remove the casting bar. [Skotlex]
+ clif->damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER);
- skill_attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skill_lv,tick,0);
+ skill->attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skill_lv,tick,0);
return ATK_BLOCK;
}
}
@@ -4783,12 +4851,12 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if( tsc && tsc->data[SC_BLADESTOP_WAIT] && !is_boss(src) && (src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->status.weapon == W_FIST ? 1 : 2)) )
{
uint16 skill_lv = tsc->data[SC_BLADESTOP_WAIT]->val1;
- int duration = skill_get_time2(MO_BLADESTOP,skill_lv);
+ int duration = skill->get_time2(MO_BLADESTOP,skill_lv);
status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER);
if(sc_start4(src, SC_BLADESTOP, 100, sd?pc_checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration))
{ //Target locked.
- clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
- clif_bladestop(target, src->id, 1);
+ clif->damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
+ clif->bladestop(target, src->id, 1);
sc_start4(target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration);
return ATK_BLOCK;
}
@@ -4801,7 +4869,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
}
if (rnd()%100 < triple_rate) {
- if( skill_attack(BF_WEAPON,src,src,target,MO_TRIPLEATTACK,skillv,tick,0) )
+ if( skill->attack(BF_WEAPON,src,src,target,MO_TRIPLEATTACK,skillv,tick,0) )
return ATK_DEF;
return ATK_MISS;
}
@@ -4819,7 +4887,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
* We need to calculate the DMG before the hp reduction, because it can kill the source.
* For futher information: bugreport:4950
**/
- ret_val = (damage_lv)skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,skill_lv,tick,0);
+ ret_val = (damage_lv)skill->attack(BF_WEAPON,src,src,target,PA_SACRIFICE,skill_lv,tick,0);
status_zap(src, sstatus->max_hp*9/100, 0);//Damage to self is always 9%
if( ret_val == ATK_NONE )
@@ -4827,35 +4895,35 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
return ret_val;
}
if (sc->data[SC_MAGICALATTACK]) {
- if( skill_attack(BF_MAGIC,src,src,target,NPC_MAGICALATTACK,sc->data[SC_MAGICALATTACK]->val1,tick,0) )
+ if( skill->attack(BF_MAGIC,src,src,target,NPC_MAGICALATTACK,sc->data[SC_MAGICALATTACK]->val1,tick,0) )
return ATK_DEF;
return ATK_MISS;
}
if( sc->data[SC_GT_ENERGYGAIN] ) {
if( sd && rnd()%100 < 10 + 5 * sc->data[SC_GT_ENERGYGAIN]->val1)
pc_addspiritball(sd,
- skill_get_time(MO_CALLSPIRITS, sc->data[SC_GT_ENERGYGAIN]->val1),
+ skill->get_time(MO_CALLSPIRITS, sc->data[SC_GT_ENERGYGAIN]->val1),
sc->data[SC_GT_ENERGYGAIN]->val1);
}
if( tsc && tsc->data[SC_GT_ENERGYGAIN] ) {
if( tsd && rnd()%100 < 10 + 5 * tsc->data[SC_GT_ENERGYGAIN]->val1)
pc_addspiritball(tsd,
- skill_get_time(MO_CALLSPIRITS, tsc->data[SC_GT_ENERGYGAIN]->val1),
+ skill->get_time(MO_CALLSPIRITS, tsc->data[SC_GT_ENERGYGAIN]->val1),
tsc->data[SC_GT_ENERGYGAIN]->val1);
}
if( sc && sc->data[SC_CRUSHSTRIKE] ){
uint16 skill_lv = sc->data[SC_CRUSHSTRIKE]->val1;
status_change_end(src, SC_CRUSHSTRIKE, INVALID_TIMER);
- if( skill_attack(BF_WEAPON,src,src,target,RK_CRUSHSTRIKE,skill_lv,tick,0) )
+ if( skill->attack(BF_WEAPON,src,src,target,RK_CRUSHSTRIKE,skill_lv,tick,0) )
return ATK_DEF;
return ATK_MISS;
}
}
if(tsc && tsc->data[SC_KAAHI] && tsc->data[SC_KAAHI]->val4 == INVALID_TIMER && tstatus->hp < tstatus->max_hp)
- tsc->data[SC_KAAHI]->val4 = add_timer(tick + skill_get_time2(SL_KAAHI,tsc->data[SC_KAAHI]->val1), kaahi_heal_timer, target->id, SC_KAAHI); //Activate heal.
+ tsc->data[SC_KAAHI]->val4 = add_timer(tick + skill->get_time2(SL_KAAHI,tsc->data[SC_KAAHI]->val1), kaahi_heal_timer, target->id, SC_KAAHI); //Activate heal.
- wd = battle_calc_attack(BF_WEAPON, src, target, 0, 0, flag);
+ wd = battle->calc_attack(BF_WEAPON, src, target, 0, 0, flag);
if( sc && sc->count ) {
if (sc->data[SC_EXEEDBREAK]) {
@@ -4864,7 +4932,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
if( sc->data[SC_SPELLFIST] ) {
if( --(sc->data[SC_SPELLFIST]->val1) >= 0 ){
- struct Damage ad = battle_calc_attack(BF_MAGIC,src,target,sc->data[SC_SPELLFIST]->val3,sc->data[SC_SPELLFIST]->val4,flag|BF_SHORT);
+ struct Damage ad = battle->calc_attack(BF_MAGIC,src,target,sc->data[SC_SPELLFIST]->val3,sc->data[SC_SPELLFIST]->val4,flag|BF_SHORT);
wd.damage = ad.damage;
}else
status_change_end(src,SC_SPELLFIST,INVALID_TIMER);
@@ -4878,46 +4946,46 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
}
if (sd && sd->state.arrow_atk) //Consume arrow.
- battle_consume_ammo(sd, 0, 0);
+ battle->consume_ammo(sd, 0, 0);
damage = wd.damage + wd.damage2;
- if( damage > 0 && src != target )
- {
- if( sc && sc->data[SC_DUPLELIGHT] && (wd.flag&BF_SHORT) && rnd()%100 <= 10+2*sc->data[SC_DUPLELIGHT]->val1 )
- { // Activates it only from melee damage
+ if( damage > 0 && src != target ) {
+ if( sc && sc->data[SC_DUPLELIGHT] && (wd.flag&BF_SHORT) && rnd()%100 <= 10+2*sc->data[SC_DUPLELIGHT]->val1 ){
+ // Activates it only from melee damage
uint16 skill_id;
if( rnd()%2 == 1 )
skill_id = AB_DUPLELIGHT_MELEE;
else
skill_id = AB_DUPLELIGHT_MAGIC;
- skill_attack(skill_get_type(skill_id), src, src, target, skill_id, sc->data[SC_DUPLELIGHT]->val1, tick, SD_LEVEL);
+ skill->attack(skill->get_type(skill_id), src, src, target, skill_id, sc->data[SC_DUPLELIGHT]->val1, tick, SD_LEVEL);
}
- rdamage = battle_calc_return_damage(target,src, &damage, wd.flag, 0);
+ rdamage = battle->calc_return_damage(target,src, &damage, wd.flag, 0);
if( rdamage > 0 ) {
if( tsc && tsc->data[SC_REFLECTDAMAGE] ) {
- if( src != target )// Don't reflect your own damage (Grand Cross)
- map_foreachinshootrange(battle_damage_area,target,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd.amotion,wd.dmotion,rdamage,tstatus->race,0);
+ if( src != target ) {// Don't reflect your own damage (Grand Cross)
+ map_foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd.amotion,wd.dmotion,rdamage,tstatus->race);
+ }
} else {
- rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0);
+ rdelay = clif->damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0);
//Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
- skill_additional_effect(target,src,CR_REFLECTSHIELD,1,BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
+ skill->additional_effect(target,src,CR_REFLECTSHIELD,1,BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
}
}
}
- wd.dmotion = clif_damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2);
+ wd.dmotion = clif->damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2);
if (sd && sd->bonus.splash_range > 0 && damage > 0)
- skill_castend_damage_id(src, target, 0, 1, tick, 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);
+ 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);
+ battle->delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion, true);
if( tsc ) {
if( tsc->data[SC_DEVOTION] ) {
struct status_change_entry *sce = tsc->data[SC_DEVOTION];
@@ -4928,7 +4996,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
(d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == target->id)
) && check_distance_bl(target, d_bl, sce->val3) )
{
- clif_damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, 0, 0);
+ clif->damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, 0, 0);
status_fix_damage(NULL, d_bl, damage, 0);
}
else
@@ -4936,16 +5004,16 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
} else if( tsc->data[SC_CIRCLE_OF_FIRE_OPTION] && (wd.flag&BF_SHORT) && target->type == BL_PC ) {
struct elemental_data *ed = ((TBL_PC*)target)->ed;
if( ed ) {
- clif_skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, 6);
- skill_attack(BF_MAGIC,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag);
+ clif->skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, 6);
+ skill->attack(BF_MAGIC,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag);
}
} else if( tsc->data[SC_WATER_SCREEN_OPTION] && tsc->data[SC_WATER_SCREEN_OPTION]->val1 ) {
struct block_list *e_bl = map_id2bl(tsc->data[SC_WATER_SCREEN_OPTION]->val1);
if( e_bl && !status_isdead(e_bl) ) {
- clif_damage(e_bl,e_bl,tick,wd.amotion,wd.dmotion,damage,wd.div_,wd.type,wd.damage2);
+ clif->damage(e_bl,e_bl,tick,wd.amotion,wd.dmotion,damage,wd.div_,wd.type,wd.damage2);
status_damage(target,e_bl,damage,0,0,0);
// Just show damage in target.
- clif_damage(src, target, tick, wd.amotion, wd.dmotion, damage, wd.div_, wd.type, wd.damage2 );
+ clif->damage(src, target, tick, wd.amotion, wd.dmotion, damage, wd.div_, wd.type, wd.damage2 );
map_freeblock_unlock();
return ATK_NONE;
}
@@ -4961,43 +5029,44 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if (i >= 50) skill_lv -= 2;
else if (i >= 15) skill_lv--;
if (skill_lv < 1) skill_lv = 1;
- sp = skill_get_sp(skill_id,skill_lv) * 2 / 3;
+ sp = skill->get_sp(skill_id,skill_lv) * 2 / 3;
if (status_charge(src, 0, sp)) {
- switch (skill_get_casttype(skill_id)) {
+ switch (skill->get_casttype(skill_id)) {
case CAST_GROUND:
- skill_castend_pos2(src, target->x, target->y, skill_id, skill_lv, tick, flag);
+ skill->castend_pos2(src, target->x, target->y, skill_id, skill_lv, tick, flag);
break;
case CAST_NODAMAGE:
- skill_castend_nodamage_id(src, target, skill_id, skill_lv, tick, flag);
+ skill->castend_nodamage_id(src, target, skill_id, skill_lv, tick, flag);
break;
case CAST_DAMAGE:
- skill_castend_damage_id(src, target, skill_id, skill_lv, tick, flag);
+ skill->castend_damage_id(src, target, skill_id, skill_lv, tick, flag);
break;
}
}
}
if (sd) {
if( wd.flag&BF_SHORT && sc && sc->data[SC__AUTOSHADOWSPELL] && rnd()%100 < sc->data[SC__AUTOSHADOWSPELL]->val3 &&
- sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id != 0 && sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].flag == SKILL_FLAG_PLAGIARIZED )
+ sd->status.skill[skill->get_index(sc->data[SC__AUTOSHADOWSPELL]->val1)].id != 0 && sd->status.skill[skill->get_index(sc->data[SC__AUTOSHADOWSPELL]->val1)].flag == SKILL_FLAG_PLAGIARIZED )
{
- int r_skill = sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id,
- r_lv = sc->data[SC__AUTOSHADOWSPELL]->val2, type;
+ int r_skill = sd->status.skill[skill->get_index(sc->data[SC__AUTOSHADOWSPELL]->val1)].id,
+ r_lv = sc->data[SC__AUTOSHADOWSPELL]->val2;
if (r_skill != AL_HOLYLIGHT && r_skill != PR_MAGNUS) {
- if( (type = skill_get_casttype(r_skill)) == CAST_GROUND ) {
+ int type;
+ if( (type = skill->get_casttype(r_skill)) == CAST_GROUND ) {
int maxcount = 0;
if( !(BL_PC&battle_config.skill_reiteration) &&
- skill_get_unit_flag(r_skill)&UF_NOREITERATION )
+ skill->get_unit_flag(r_skill)&UF_NOREITERATION )
type = -1;
if( BL_PC&battle_config.skill_nofootset &&
- skill_get_unit_flag(r_skill)&UF_NOFOOTSET )
+ skill->get_unit_flag(r_skill)&UF_NOFOOTSET )
type = -1;
if( BL_PC&battle_config.land_skill_limit &&
- (maxcount = skill_get_maxcount(r_skill, r_lv)) > 0
+ (maxcount = skill->get_maxcount(r_skill, r_lv)) > 0
) {
int v;
for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) {
@@ -5009,43 +5078,43 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
if( type != CAST_GROUND ){
- clif_skill_fail(sd,r_skill,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,r_skill,USESKILL_FAIL_LEVEL,0);
map_freeblock_unlock();
return wd.dmg_lv;
}
}
sd->state.autocast = 1;
- skill_consume_requirement(sd,r_skill,r_lv,3);
+ skill->consume_requirement(sd,r_skill,r_lv,3);
switch( type ) {
- case CAST_GROUND:
- skill_castend_pos2(src, target->x, target->y, r_skill, r_lv, tick, flag);
- break;
- case CAST_NODAMAGE:
- skill_castend_nodamage_id(src, target, r_skill, r_lv, tick, flag);
- break;
- case CAST_DAMAGE:
- skill_castend_damage_id(src, target, r_skill, r_lv, tick, flag);
- break;
+ case CAST_GROUND:
+ skill->castend_pos2(src, target->x, target->y, r_skill, r_lv, tick, flag);
+ break;
+ case CAST_NODAMAGE:
+ skill->castend_nodamage_id(src, target, r_skill, r_lv, tick, flag);
+ break;
+ case CAST_DAMAGE:
+ skill->castend_damage_id(src, target, r_skill, r_lv, tick, flag);
+ break;
}
sd->state.autocast = 0;
- sd->ud.canact_tick = tick + skill_delayfix(src, r_skill, r_lv);
- clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, r_skill, r_lv), 0, 0, 1);
+ sd->ud.canact_tick = tick + skill->delay_fix(src, r_skill, r_lv);
+ clif->status_change(src, SI_ACTIONDELAY, 1, skill->delay_fix(src, r_skill, r_lv), 0, 0, 1);
}
}
if (wd.flag & BF_WEAPON && src != target && damage > 0) {
if (battle_config.left_cardfix_to_right)
- battle_drain(sd, target, wd.damage, wd.damage, tstatus->race, is_boss(target));
+ battle->drain(sd, target, wd.damage, wd.damage, tstatus->race, is_boss(target));
else
- battle_drain(sd, target, wd.damage, wd.damage2, tstatus->race, is_boss(target));
+ battle->drain(sd, target, wd.damage, wd.damage2, tstatus->race, is_boss(target));
}
}
- if (rdamage > 0 && !(tsc && tsc->data[SC_REFLECTDAMAGE])) { //By sending attack type "none" skill_additional_effect won't be invoked. [Skotlex]
+ if (rdamage > 0 && !(tsc && tsc->data[SC_REFLECTDAMAGE])) { //By sending attack type "none" skill->additional_effect won't be invoked. [Skotlex]
if(tsd && src != target)
- battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
- battle_delay_damage(tick, wd.amotion, target, src, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay);
+ battle->drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
+ battle->delay_damage(tick, wd.amotion, target, src, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay, true);
}
if (tsc) {
@@ -5058,9 +5127,9 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
struct status_change_entry *sce = tsc->data[SC_POISONREACT];
if (sstatus->def_ele == ELE_POISON) {
sce->val2 = 0;
- skill_attack(BF_WEAPON,target,target,src,AS_POISONREACT,sce->val1,tick,0);
+ skill->attack(BF_WEAPON,target,target,src,AS_POISONREACT,sce->val1,tick,0);
} else {
- skill_attack(BF_WEAPON,target,target,src,TF_POISON, 5, tick, 0);
+ skill->attack(BF_WEAPON,target,target,src,TF_POISON, 5, tick, 0);
--sce->val2;
}
if (sce->val2 <= 0)
@@ -5148,10 +5217,10 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
//t_bl/s_bl hold the 'master' of the attack, while src/target are the actual
//objects involved.
- if( (t_bl = battle_get_master(target)) == NULL )
+ if( (t_bl = battle->get_master(target)) == NULL )
t_bl = target;
- if( (s_bl = battle_get_master(src)) == NULL )
+ if( (s_bl = battle->get_master(src)) == NULL )
s_bl = src;
if ( s_bl->type == BL_PC ) {
@@ -5183,7 +5252,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
case BL_MOB:
if(((((TBL_MOB*)target)->special_state.ai == 2 || //Marine Spheres
(((TBL_MOB*)target)->special_state.ai == 3 && battle_config.summon_flora&1)) && //Floras
- s_bl->type == BL_PC && src->type != BL_MOB) || ((TBL_MOB*)target)->special_state.ai == 4) //Zanzoe
+ s_bl->type == BL_PC && src->type != BL_MOB) || (((TBL_MOB*)target)->special_state.ai == 4 && t_bl->id != s_bl->id)) //Zanzoe
{ //Targettable by players
state |= BCT_ENEMY;
strip_enemy = 0;
@@ -5194,8 +5263,8 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
TBL_SKILL *su = (TBL_SKILL*)target;
if( !su->group )
return 0;
- if( skill_get_inf2(su->group->skill_id)&INF2_TRAP ) { //Only a few skills can target traps...
- switch( battle_getcurrentskill(src) ) {
+ if( skill->get_inf2(su->group->skill_id)&INF2_TRAP ) { //Only a few skills can target traps...
+ switch( battle->get_current_skill(src) ) {
case RK_DRAGONBREATH:// it can only hit traps in pvp/gvg maps
if( !map[m].flag.pvp && !map[m].flag.gvg )
break;
@@ -5300,7 +5369,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
return 0;
if (su->group->src_id == target->id) {
- int inf2 = skill_get_inf2(su->group->skill_id);
+ int inf2 = skill->get_inf2(su->group->skill_id);
if (inf2&INF2_NO_TARGET_SELF)
return -1;
if (inf2&INF2_TARGET_SELF)
@@ -5408,7 +5477,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
{
int s_guild = status_get_guild_id(s_bl);
int t_guild = status_get_guild_id(t_bl);
- if( !(map[m].flag.pvp && map[m].flag.pvp_noguild) && s_guild && t_guild && (s_guild == t_guild || guild_isallied(s_guild, t_guild)) && (!map[m].flag.battleground || sbg_id == tbg_id) )
+ if( !(map[m].flag.pvp && map[m].flag.pvp_noguild) && s_guild && t_guild && (s_guild == t_guild || guild->isallied(s_guild, t_guild)) && (!map[m].flag.battleground || sbg_id == tbg_id) )
state |= BCT_GUILD;
else
state |= BCT_ENEMY;
@@ -5441,7 +5510,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
{
int s_guild = status_get_guild_id(s_bl);
int t_guild = status_get_guild_id(t_bl);
- if(s_guild && t_guild && (s_guild == t_guild || guild_isallied(s_guild, t_guild)))
+ if(s_guild && t_guild && (s_guild == t_guild || guild->isallied(s_guild, t_guild)))
state |= BCT_GUILD;
}
} //end non pvp/gvg chk rivality
@@ -5613,6 +5682,7 @@ static const struct _battle_data {
{ "wedding_ignorepalette", &battle_config.wedding_ignorepalette, 0, 0, 1, },
{ "xmas_ignorepalette", &battle_config.xmas_ignorepalette, 0, 0, 1, },
{ "summer_ignorepalette", &battle_config.summer_ignorepalette, 0, 0, 1, },
+ { "hanbok_ignorepalette", &battle_config.hanbok_ignorepalette, 0, 0, 1, },
{ "natural_healhp_interval", &battle_config.natural_healhp_interval, 6000, NATURAL_HEAL_INTERVAL, INT_MAX, },
{ "natural_healsp_interval", &battle_config.natural_healsp_interval, 8000, NATURAL_HEAL_INTERVAL, INT_MAX, },
{ "natural_heal_skill_interval", &battle_config.natural_heal_skill_interval, 10000, NATURAL_HEAL_INTERVAL, INT_MAX, },
@@ -5653,17 +5723,7 @@ static const struct _battle_data {
{ "player_cloak_check_type", &battle_config.pc_cloak_check_type, 1, 0, 1|2|4, },
{ "monster_cloak_check_type", &battle_config.monster_cloak_check_type, 4, 0, 1|2|4, },
{ "sense_type", &battle_config.estimation_type, 1|2, 0, 1|2, },
- { "gvg_short_attack_damage_rate", &battle_config.gvg_short_damage_rate, 80, 0, INT_MAX, },
- { "gvg_long_attack_damage_rate", &battle_config.gvg_long_damage_rate, 80, 0, INT_MAX, },
- { "gvg_weapon_attack_damage_rate", &battle_config.gvg_weapon_damage_rate, 60, 0, INT_MAX, },
- { "gvg_magic_attack_damage_rate", &battle_config.gvg_magic_damage_rate, 60, 0, INT_MAX, },
- { "gvg_misc_attack_damage_rate", &battle_config.gvg_misc_damage_rate, 60, 0, INT_MAX, },
{ "gvg_flee_penalty", &battle_config.gvg_flee_penalty, 20, 0, INT_MAX, },
- { "pk_short_attack_damage_rate", &battle_config.pk_short_damage_rate, 80, 0, INT_MAX, },
- { "pk_long_attack_damage_rate", &battle_config.pk_long_damage_rate, 70, 0, INT_MAX, },
- { "pk_weapon_attack_damage_rate", &battle_config.pk_weapon_damage_rate, 60, 0, INT_MAX, },
- { "pk_magic_attack_damage_rate", &battle_config.pk_magic_damage_rate, 60, 0, INT_MAX, },
- { "pk_misc_attack_damage_rate", &battle_config.pk_misc_damage_rate, 60, 0, INT_MAX, },
{ "mob_changetarget_byskill", &battle_config.mob_changetarget_byskill, 0, 0, 1, },
{ "attack_direction_change", &battle_config.attack_direction_change, BL_ALL, BL_NUL, BL_ALL, },
{ "land_skill_limit", &battle_config.land_skill_limit, BL_ALL, BL_NUL, BL_ALL, },
@@ -5745,7 +5805,6 @@ static const struct _battle_data {
{ "night_at_start", &battle_config.night_at_start, 0, 0, 1, },
{ "show_mob_info", &battle_config.show_mob_info, 0, 0, 1|2|4, },
{ "ban_hack_trade", &battle_config.ban_hack_trade, 0, 0, INT_MAX, },
- { "packet_ver_flag", &battle_config.packet_ver_flag, 0xFFFFFF,0x0000,INT_MAX, },
{ "min_hair_style", &battle_config.min_hair_style, 0, 0, INT_MAX, },
{ "max_hair_style", &battle_config.max_hair_style, 23, 0, INT_MAX, },
{ "min_hair_color", &battle_config.min_hair_color, 0, 0, INT_MAX, },
@@ -5790,7 +5849,6 @@ static const struct _battle_data {
{ "show_hp_sp_gain", &battle_config.show_hp_sp_gain, 1, 0, 1, },
{ "mob_npc_event_type", &battle_config.mob_npc_event_type, 1, 0, 1, },
{ "character_size", &battle_config.character_size, 1|2, 0, 1|2, },
- { "mob_max_skilllvl", &battle_config.mob_max_skilllvl, MAX_SKILL_LEVEL, 1, MAX_SKILL_LEVEL, },
{ "retaliate_to_master", &battle_config.retaliate_to_master, 1, 0, 1, },
{ "rare_drop_announce", &battle_config.rare_drop_announce, 0, 0, 10000, },
{ "duel_allow_pvp", &battle_config.duel_allow_pvp, 0, 0, 1, },
@@ -5800,14 +5858,13 @@ static const struct _battle_data {
{ "duel_time_interval", &battle_config.duel_time_interval, 60, 0, INT_MAX, },
{ "duel_only_on_same_map", &battle_config.duel_only_on_same_map, 0, 0, 1, },
{ "skip_teleport_lv1_menu", &battle_config.skip_teleport_lv1_menu, 0, 0, 1, },
+ { "mob_max_skilllvl", &battle_config.mob_max_skilllvl, 100, 1, INT_MAX, },
{ "allow_skill_without_day", &battle_config.allow_skill_without_day, 0, 0, 1, },
{ "allow_es_magic_player", &battle_config.allow_es_magic_pc, 0, 0, 1, },
{ "skill_caster_check", &battle_config.skill_caster_check, 1, 0, 1, },
{ "status_cast_cancel", &battle_config.sc_castcancel, BL_NUL, BL_NUL, BL_ALL, },
{ "pc_status_def_rate", &battle_config.pc_sc_def_rate, 100, 0, INT_MAX, },
{ "mob_status_def_rate", &battle_config.mob_sc_def_rate, 100, 0, INT_MAX, },
- { "pc_luk_status_def", &battle_config.pc_luk_sc_def, 300, 1, INT_MAX, },
- { "mob_luk_status_def", &battle_config.mob_luk_sc_def, 300, 1, INT_MAX, },
{ "pc_max_status_def", &battle_config.pc_max_sc_def, 100, 0, INT_MAX, },
{ "mob_max_status_def", &battle_config.mob_max_sc_def, 100, 0, INT_MAX, },
{ "sg_miracle_skill_ratio", &battle_config.sg_miracle_skill_ratio, 1, 0, 10000, },
@@ -5855,11 +5912,6 @@ static const struct _battle_data {
{ "client_limit_unit_lv", &battle_config.client_limit_unit_lv, 0, 0, BL_ALL, },
// BattleGround Settings
{ "bg_update_interval", &battle_config.bg_update_interval, 1000, 100, INT_MAX, },
- { "bg_short_attack_damage_rate", &battle_config.bg_short_damage_rate, 80, 0, INT_MAX, },
- { "bg_long_attack_damage_rate", &battle_config.bg_long_damage_rate, 80, 0, INT_MAX, },
- { "bg_weapon_attack_damage_rate", &battle_config.bg_weapon_damage_rate, 60, 0, INT_MAX, },
- { "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, },
/**
* rAthena
@@ -5870,20 +5922,29 @@ static const struct _battle_data {
{ "skill_amotion_leniency", &battle_config.skill_amotion_leniency, 90, 0, 300 },
{ "mvp_tomb_enabled", &battle_config.mvp_tomb_enabled, 1, 0, 1 },
{ "feature.atcommand_suggestions", &battle_config.atcommand_suggestions_enabled, 0, 0, 1 },
- { "min_npc_vending_distance", &battle_config.min_npc_vending_distance, 3, 0, 100 },
+ { "min_npc_vendchat_distance", &battle_config.min_npc_vendchat_distance, 3, 0, 100 },
{ "atcommand_mobinfo_type", &battle_config.atcommand_mobinfo_type, 0, 0, 1 },
{ "homunculus_max_level", &battle_config.hom_max_level, 99, 0, MAX_LEVEL, },
{ "homunculus_S_max_level", &battle_config.hom_S_max_level, 150, 0, MAX_LEVEL, },
{ "mob_size_influence", &battle_config.mob_size_influence, 0, 0, 1, },
+ /**
+ * Hercules
+ **/
+ { "skill_trap_type", &battle_config.skill_trap_type, 0, 0, 1, },
+ { "item_restricted_consumption_type", &battle_config.item_restricted_consumption_type,1, 0, 1, },
+ { "max_walk_path", &battle_config.max_walk_path, 17, 1, MAX_WALKPATH, },
+ { "item_enabled_npc", &battle_config.item_enabled_npc, 1, 0, 1, },
+ { "gm_ignore_warpable_area", &battle_config.gm_ignore_warpable_area, 0, 2, 100, },
};
#ifndef STATS_OPT_OUT
/**
- * rAthena anonymous statistic usage report -- packet is built here, and sent to char server to report.
+ * Hercules anonymous statistic usage report -- packet is built here, and sent to char server to report.
**/
-void rAthena_report(char* date, char *time_c) {
- int i, rev = 0, bd_size = ARRAYLENGTH(battle_data);
+void Hercules_report(char* date, char *time_c) {
+ int i, bd_size = ARRAYLENGTH(battle_data);
unsigned int config = 0;
- const char* rev_str;
+ const char *svn = get_svn_revision();
+ const char *git = get_git_hash();
char timestring[25];
time_t curtime;
char* buf;
@@ -5891,7 +5952,7 @@ void rAthena_report(char* date, char *time_c) {
enum config_table {
C_CIRCULAR_AREA = 0x0001,
C_CELLNOSTACK = 0x0002,
- C_BETA_THREAD_TEST = 0x0004,
+ C_CONSOLE_INPUT = 0x0004,
C_SCRIPT_CALLFUNC_CHECK = 0x0008,
C_OFFICIAL_WALKPATH = 0x0010,
C_RENEWAL = 0x0020,
@@ -5904,16 +5965,16 @@ void rAthena_report(char* date, char *time_c) {
C_SECURE_NPCTIMEOUT = 0x1000,
C_SQL_DBS = 0x2000,
C_SQL_LOGS = 0x4000,
+ C_MEMWATCH = 0x8000,
+ C_DMALLOC = 0x10000,
+ C_GCOLLECT = 0x20000,
+ C_SEND_SHORTLIST = 0x40000,
};
- if( (rev_str = get_svn_revision()) != 0 )
- rev = atoi(rev_str);
-
/* we get the current time */
time(&curtime);
strftime(timestring, 24, "%Y-%m-%d %H:%M:%S", localtime(&curtime));
-
-
+
#ifdef CIRCULAR_AREA
config |= C_CIRCULAR_AREA;
#endif
@@ -5922,10 +5983,10 @@ void rAthena_report(char* date, char *time_c) {
config |= C_CELLNOSTACK;
#endif
-#ifdef BETA_THREAD_TEST
- config |= C_BETA_THREAD_TEST;
+#ifdef CONSOLE_INPUT
+ config |= C_CONSOLE_INPUT;
#endif
-
+
#ifdef SCRIPT_CALLFUNC_CHECK
config |= C_SCRIPT_CALLFUNC_CHECK;
#endif
@@ -5962,51 +6023,65 @@ void rAthena_report(char* date, char *time_c) {
config |= C_RENEWAL_ASPD;
#endif
-/* not a ifdef because SECURE_NPCTIMEOUT is always defined, but either as 0 or higher */
-#if SECURE_NPCTIMEOUT
+#ifdef SECURE_NPCTIMEOUT
config |= C_SECURE_NPCTIMEOUT;
#endif
+
/* non-define part */
if( db_use_sqldbs )
config |= C_SQL_DBS;
- if( log_config.sql_logs )
+ if( logs->config.sql_logs )
config |= C_SQL_LOGS;
+#ifdef MEMWATCH
+ config |= C_MEMWATCH;
+#endif
+#ifdef DMALLOC
+ config |= C_DMALLOC;
+#endif
+#ifdef GCOLLECT
+ config |= C_GCOLLECT;
+#endif
+
+#ifdef SEND_SHORTLIST
+ config |= C_SEND_SHORTLIST;
+#endif
+
#define BFLAG_LENGTH 35
- CREATE(buf, char, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) + 1 );
+ CREATE(buf, char, 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) + 1 );
/* build packet */
WBUFW(buf,0) = 0x3000;
- WBUFW(buf,2) = 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) );
- WBUFW(buf,4) = 0x9c;
+ WBUFW(buf,2) = 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) );
+ WBUFW(buf,4) = 0x9e;
safestrncpy((char*)WBUFP(buf,6), date, 12);
safestrncpy((char*)WBUFP(buf,6 + 12), time_c, 9);
safestrncpy((char*)WBUFP(buf,6 + 12 + 9), timestring, 24);
- WBUFL(buf,6 + 12 + 9 + 24) = rev;
- WBUFL(buf,6 + 12 + 9 + 24 + 4) = map_getusers();
+ safestrncpy((char*)WBUFP(buf,6 + 12 + 9 + 24), git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown", 41);
+ WBUFL(buf,6 + 12 + 9 + 24 + 41) = map_getusers();
- WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4) = config;
- WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4 + 4) = bd_size;
+ WBUFL(buf,6 + 12 + 9 + 24 + 41 + 4) = config;
+ WBUFL(buf,6 + 12 + 9 + 24 + 41 + 4 + 4) = bd_size;
for( i = 0; i < bd_size; i++ ) {
- safestrncpy((char*)WBUFP(buf,6 + 12 + 9+ 24 + 4 + 4 + 4 + 4 + ( i * ( BFLAG_LENGTH + 4 ) ) ), battle_data[i].str, 35);
- WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + BFLAG_LENGTH + ( i * ( BFLAG_LENGTH + 4 ) ) ) = *battle_data[i].val;
+ safestrncpy((char*)WBUFP(buf,6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( i * ( BFLAG_LENGTH + 4 ) ) ), battle_data[i].str, 35);
+ WBUFL(buf,6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + BFLAG_LENGTH + ( i * ( BFLAG_LENGTH + 4 ) ) ) = *battle_data[i].val;
}
- chrif_send_report(buf, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) );
+ chrif_send_report(buf, 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) );
aFree(buf);
#undef BFLAG_LENGTH
}
-static int rAthena_report_timer(int tid, unsigned int tick, int id, intptr_t data) {
+static int Hercules_report_timer(int tid, unsigned int tick, int id, intptr_t data) {
if( chrif_isconnected() ) {/* char server relays it, so it must be online. */
- rAthena_report(__DATE__,__TIME__);
+ Hercules_report(__DATE__,__TIME__);
}
return 0;
}
@@ -6041,15 +6116,13 @@ int battle_get_value(const char* w1)
return *battle_data[i].val;
}
-void battle_set_defaults()
-{
+void battle_set_defaults(void) {
int i;
for (i = 0; i < ARRAYLENGTH(battle_data); i++)
*battle_data[i].val = battle_data[i].defval;
}
-void battle_adjust_conf()
-{
+void battle_adjust_conf(void) {
battle_config.monster_max_aspd = 2000 - battle_config.monster_max_aspd*10;
battle_config.max_aspd = 2000 - battle_config.max_aspd*10;
battle_config.max_third_aspd = 2000 - battle_config.max_third_aspd*10;
@@ -6092,12 +6165,11 @@ void battle_adjust_conf()
int battle_config_read(const char* cfgName)
{
- char line[1024], w1[1024], w2[1024];
FILE* fp;
static int count = 0;
if (count == 0)
- battle_set_defaults();
+ battle->config_set_defaults();
count++;
@@ -6106,6 +6178,7 @@ int battle_config_read(const char* cfgName)
ShowError("File not found: %s\n", cfgName);
else
{
+ char line[1024], w1[1024], w2[1024];
while(fgets(line, sizeof(line), fp))
{
if (line[0] == '/' && line[1] == '/')
@@ -6113,9 +6186,9 @@ int battle_config_read(const char* cfgName)
if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2)
continue;
if (strcmpi(w1, "import") == 0)
- battle_config_read(w2);
+ battle->config_read(w2);
else
- if (battle_set_value(w1, w2) == 0)
+ if (battle->config_set_value(w1, w2) == 0)
ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
}
@@ -6124,25 +6197,72 @@ int battle_config_read(const char* cfgName)
count--;
- if (count == 0)
- battle_adjust_conf();
+ if (count == 0) {
+ battle->config_adjust();
+ clif->bc_ready();
+ }
return 0;
}
-void do_init_battle(void)
-{
+void do_init_battle(void) {
delay_damage_ers = ers_new(sizeof(struct delay_damage),"battle.c::delay_damage_ers",ERS_OPT_CLEAR);
add_timer_func_list(battle_delay_damage_sub, "battle_delay_damage_sub");
#ifndef STATS_OPT_OUT
- add_timer_func_list(rAthena_report_timer, "rAthena_report_timer");
- add_timer_interval(gettick()+30000, rAthena_report_timer, 0, 0, 60000 * 30);
+ add_timer_func_list(Hercules_report_timer, "Hercules_report_timer");
+ add_timer_interval(gettick()+30000, Hercules_report_timer, 0, 0, 60000 * 30);
#endif
}
-void do_final_battle(void)
-{
+void do_final_battle(void) {
ers_destroy(delay_damage_ers);
}
+
+/* initialize the interface */
+void battle_defaults(void) {
+ battle = &battle_s;
+ battle->init = do_init_battle;
+ battle->final = do_final_battle;
+ battle->calc_attack = battle_calc_attack;
+ battle->calc_damage = battle_calc_damage;
+ battle->calc_gvg_damage = battle_calc_gvg_damage;
+ battle->calc_bg_damage = battle_calc_bg_damage;
+ battle->calc_base_damage = battle_calc_base_damage;
+ battle->calc_misc_attack = battle_calc_misc_attack;
+ battle->calc_magic_attack = battle_calc_magic_attack;
+ battle->weapon_attack = battle_weapon_attack;
+ battle->delay_damage = battle_delay_damage;
+ battle->drain = battle_drain;
+ battle->calc_return_damage = battle_calc_return_damage;
+ battle->calc_weapon_attack = battle_calc_weapon_attack;
+ battle->attr_ratio = battle_attr_ratio;
+ battle->attr_fix = battle_attr_fix;
+ battle->calc_cardfix = battle_calc_cardfix;
+ battle->get_master = battle_get_master;
+ battle->get_targeted = battle_gettargeted;
+ battle->get_enemy = battle_getenemy;
+ battle->get_target = battle_gettarget;
+ battle->get_current_skill = battle_getcurrentskill;
+ battle->check_undead = battle_check_undead;
+ battle->check_target = battle_check_target;
+ battle->check_range = battle_check_range;
+ battle->consume_ammo = battle_consume_ammo;
+ battle->get_targeted_sub = battle_gettargeted_sub;
+ battle->get_enemy_sub = battle_getenemy_sub;
+ battle->get_enemy_area_sub = battle_getenemyarea_sub;
+ battle->delay_damage_sub = battle_delay_damage_sub;
+ battle->blewcount_bonus = battle_blewcount_bonus;
+ battle->range_type = battle_range_type;
+ battle->adjust_skill_damage = battle_adjust_skill_damage;
+ battle->add_mastery = battle_addmastery;
+ battle->calc_drain = battle_calc_drain;
+ battle->config_read = battle_config_read;
+ battle->config_set_defaults = battle_set_defaults;
+ battle->config_set_value = battle_set_value;
+ battle->config_get_value = battle_get_value;
+ battle->config_adjust = battle_adjust_conf;
+ battle->get_enemy_area = battle_getenemyarea;
+ battle->damage_area = battle_damage_area;
+}