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.c631
1 files changed, 397 insertions, 234 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index b2ee9cf1d..3575dea6f 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -4,43 +4,43 @@
#define HERCULES_CORE
-#include "../config/core.h" // CELL_NOSTACK, CIRCULAR_AREA, CONSOLE_INPUT, HMAP_ZONE_DAMAGE_CAP_TYPE, OFFICIAL_WALKPATH, RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, RE_LVL_DMOD(), RE_LVL_MDMOD(), RE_LVL_TMDMOD(), RE_SKILL_REDUCTION(), SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, STATS_OPT_OUT
+#include "config/core.h" // CELL_NOSTACK, CIRCULAR_AREA, CONSOLE_INPUT, HMAP_ZONE_DAMAGE_CAP_TYPE, OFFICIAL_WALKPATH, RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, RE_LVL_DMOD(), RE_LVL_MDMOD(), RE_LVL_TMDMOD(), RE_SKILL_REDUCTION(), SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, STATS_OPT_OUT
#include "battle.h"
+#include "map/battleground.h"
+#include "map/chrif.h"
+#include "map/clif.h"
+#include "map/elemental.h"
+#include "map/guild.h"
+#include "map/homunculus.h"
+#include "map/itemdb.h"
+#include "map/map.h"
+#include "map/mercenary.h"
+#include "map/mob.h"
+#include "map/party.h"
+#include "map/path.h"
+#include "map/pc.h"
+#include "map/pet.h"
+#include "map/skill.h"
+#include "map/status.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/ers.h"
+#include "common/malloc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/sysinfo.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "battleground.h"
-#include "chrif.h"
-#include "clif.h"
-#include "elemental.h"
-#include "guild.h"
-#include "homunculus.h"
-#include "itemdb.h"
-#include "map.h"
-#include "mercenary.h"
-#include "mob.h"
-#include "party.h"
-#include "path.h"
-#include "pc.h"
-#include "pet.h"
-#include "skill.h"
-#include "status.h"
-#include "../common/HPM.h"
-#include "../common/cbasetypes.h"
-#include "../common/ers.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/sysinfo.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
-
struct Battle_Config battle_config;
struct battle_interface battle_s;
@@ -300,10 +300,10 @@ int battle_delay_damage(int64 tick, int amotion, struct block_list *src, struct
int battle_attr_ratio(int atk_elem,int def_type, int def_lv)
{
- if (atk_elem < 0 || atk_elem >= ELE_MAX)
+ if (atk_elem < ELE_NEUTRAL || atk_elem >= ELE_MAX)
return 100;
- if (def_type < 0 || def_type >= ELE_MAX || def_lv < 1 || def_lv > 4)
+ if (def_type < ELE_NEUTRAL || def_type >= ELE_MAX || def_lv < 1 || def_lv > 4)
return 100;
return battle->attr_fix_table[def_lv-1][atk_elem][def_type];
@@ -322,10 +322,10 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
if (src) sc = status->get_sc(src);
if (target) tsc = status->get_sc(target);
- if (atk_elem < 0 || atk_elem >= ELE_MAX)
+ if (atk_elem < ELE_NEUTRAL || atk_elem >= ELE_MAX)
atk_elem = rnd()%ELE_MAX;
- if (def_type < 0 || def_type >= ELE_MAX ||
+ if (def_type < ELE_NEUTRAL || def_type >= ELE_MAX ||
def_lv < 1 || def_lv > 4) {
ShowError("battle_attr_fix: unknown attr type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv);
return damage;
@@ -407,6 +407,8 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
else
return damage + (damage * (ratio - 100) / 100);
}
+
+//FIXME: Missing documentation for flag, flag2
int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, struct weapon_atk *watk, int nk, bool n_ele, short s_ele, short s_ele_, int size, int type, int flag, int flag2){ // [malufett]
#ifdef RENEWAL
int64 damage, eatk = 0;
@@ -421,41 +423,47 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u
damage = status->get_weapon_atk(src, watk, flag);
- if( sd ){
- if( type == EQI_HAND_R )
- damage = battle->calc_sizefix(sd, damage, EQI_HAND_R, size, flag&8);
+ if ( sd ) {
+ if ( type == EQI_HAND_R )
+ damage = battle->calc_sizefix(sd, damage, EQI_HAND_R, size, flag & 8);
else
- damage = battle->calc_sizefix(sd, damage, EQI_HAND_L, size, flag&8);
+ damage = battle->calc_sizefix(sd, damage, EQI_HAND_L, size, flag & 8);
- if( flag&2 && sd->bonus.arrow_atk )
+ if ( flag & 2 && sd->bonus.arrow_atk && skill_id != GN_CARTCANNON )
damage += sd->bonus.arrow_atk;
- if( sd->battle_status.equip_atk != 0 )
+ if ( sd->battle_status.equip_atk != 0 )
eatk = sd->base_status.equip_atk;
+
+ if ( sd->bonus.atk_rate )
+ damage += damage * sd->bonus.atk_rate / 100;
}
if ( skill_id == TF_POISON )
eatk += 15 * skill_lv;
+ if ( skill_id != ASC_METEORASSAULT ) {
+ if ( sc && sc->data[SC_SUB_WEAPONPROPERTY] ) // Temporary. [malufett]
+ damage += damage * sc->data[SC_SUB_WEAPONPROPERTY]->val2 / 100;
+ }
+
if( sc && sc->count ){
if( sc->data[SC_ZENKAI] && watk->ele == sc->data[SC_ZENKAI]->val2 )
eatk += 200;
+ }
+
#ifdef RENEWAL_EDP
- if( sc->data[SC_EDP] && skill_id != AS_GRIMTOOTH && skill_id != AS_VENOMKNIFE && skill_id != ASC_BREAKER ){
- eatk = eatk * (sc->data[SC_EDP]->val4 / 100 - 1);
- damage = damage * (sc->data[SC_EDP]->val4 / 100);
- }
+ if ( sc && sc->data[SC_EDP] && skill_id != AS_GRIMTOOTH && skill_id != AS_VENOMKNIFE && skill_id != ASC_BREAKER ) {
+ struct status_data *tstatus;
+ tstatus = status->get_status_data(bl);
+ eatk += damage * 0x19 * battle->attr_fix_table[tstatus->ele_lv - 1][ELE_POISON][tstatus->def_ele] / 10000;
+ damage += (eatk + damage) * sc->data[SC_EDP]->val3 / 100 + eatk;
+ } else /* fall through */
#endif
- }
-
- if( skill_id != ASC_METEORASSAULT ){
- if( sc && sc->data[SC_SUB_WEAPONPROPERTY] ) // Temporary. [malufett]
- damage += damage * sc->data[SC_SUB_WEAPONPROPERTY]->val2 / 100;
- }
-
- // Temporary. [malufett]
- damage = battle->calc_elefix(src, bl, skill_id, skill_lv, damage + eatk, nk, n_ele, s_ele, s_ele_, type == EQI_HAND_L, flag);
-
+ damage += eatk;
+
+ damage = battle->calc_elefix(src, bl, skill_id, skill_lv, damage, nk, n_ele, s_ele, s_ele_, type == EQI_HAND_L, flag);
+
/**
* In RE Shield Boomerang takes weapon element only for damage calculation,
* - resist calculation is always against neutral
@@ -479,7 +487,7 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u
* it calculates nothing extra fancy, is needed for magnum breaks WATK_ELEMENT bonus. [Skotlex]
*------------------------------------------
* Pass damage2 as NULL to not calc it.
- * Flag values:
+ * Flag values: // TODO: Check whether these values are correct (the flag parameter seems to be passed through to other functions), and replace them with an enum.
* &1: Critical hit
* &2: Arrow attack
* &4: Skill is Magic Crasher
@@ -487,11 +495,23 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u
*&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)
*/
/* 'battle_calc_base_damage' is used on renewal, 'battle_calc_base_damage2' otherwise. */
+// FIXME: Missing documentation for flag2
int64 battle_calc_base_damage(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int nk, bool n_ele, short s_ele, short s_ele_, int type, int flag, int flag2) {
int64 damage;
struct status_data *st = status->get_status_data(src);
struct status_change *sc = status->get_sc(src);
-
+
+ if ( !skill_id ) {
+ s_ele = st->rhw.ele;
+ s_ele_ = st->lhw.ele;
+ if ( src->type == BL_PC ) {
+ if ( ((TBL_PC*)src)->charm_type != CHARM_TYPE_NONE && ((TBL_PC*)src)->charm_count >= MAX_SPIRITCHARM ) {
+ s_ele = s_ele_ = ((TBL_PC*)src)->charm_type;
+ }
+ if ( flag & 2 && ((TBL_PC*)src)->bonus.arrow_ele )
+ s_ele = ((TBL_PC*)src)->bonus.arrow_ele;
+ }
+ }
if (src->type == BL_PC) {
int64 batk;
// Property from mild wind bypasses it
@@ -599,6 +619,7 @@ int64 battle_calc_sizefix(struct map_session_data *sd, int64 damage, int type, i
/*==========================================
* Passive skill damages increases
*------------------------------------------*/
+// FIXME: type is undocumented
int64 battle_addmastery(struct map_session_data *sd,struct block_list *target,int64 dmg,int type) {
int64 damage;
struct status_data *st = status->get_status_data(target);
@@ -849,6 +870,7 @@ void battle_calc_masteryfix_unknown(struct block_list *src, struct block_list *t
/*==========================================
* Elemental attribute fix.
*------------------------------------------*/
+// FIXME: flag is undocumented
int64 battle_calc_elefix(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int nk, int n_ele, int s_ele, int s_ele_, bool left, int flag){
struct status_data *tstatus;
@@ -869,8 +891,6 @@ int64 battle_calc_elefix(struct block_list *src, struct block_list *target, uint
damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
if( skill_id == NC_ARMSCANNON )
damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
- if( skill_id == GN_CARTCANNON )
- damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
if( skill_id == GS_GROUNDDRIFT ) //Additional 50*lv Neutral damage.
damage += battle->attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
}
@@ -896,15 +916,53 @@ int64 battle_calc_elefix(struct block_list *src, struct block_list *target, uint
#endif
return damage;
}
+int64 battle_calc_cardfix2(struct block_list *src, struct block_list *bl, int64 damage, int s_ele, int nk, int flag) {
+#ifdef RENEWAL
+ struct map_session_data *tsd;
+ struct status_data *sstatus;
+
+ if ( !damage )
+ return 0;
+
+ nullpo_ret(bl);
+ nullpo_ret(src);
+
+ tsd = BL_CAST(BL_PC, bl);
+ sstatus = status->get_status_data(src);
+
+ if ( tsd ) {
+ if ( !(nk&NK_NO_CARDFIX_DEF) ) {
+ // RaceAddTolerance
+ damage -= damage * tsd->race_tolerance[sstatus->race] / 100;
+ damage -= damage * tsd->race_tolerance[is_boss(src) ? RC_BOSS : RC_NONBOSS] / 100;
+ if ( flag&BF_SHORT )
+ damage -= damage * tsd->bonus.near_attack_def_rate / 100;
+ else // SubRangeAttackDamage or bLongAtkDef
+ damage -= damage * tsd->bonus.long_attack_def_rate / 100;
+ }
+ if ( flag&BF_LONG && tsd->sc.data[SC_GS_ADJUSTMENT] ) {
+ damage -= 20 * damage / 100;
+ }
+ }
+#endif
+ return damage;
+}
/*==========================================
* Calculates card bonuses damage adjustments.
* cflag(cardfix flag):
* &1 - calc for left hand.
* &2 - atker side cardfix(BF_WEAPON) otherwise target side(BF_WEAPON).
*------------------------------------------*/
+// FIXME: wflag is undocumented
int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int64 damage, int cflag, int wflag){
struct map_session_data *sd, *tsd;
- short cardfix = 1000, t_class, s_class, s_race2, t_race2;
+ short cardfix =
+#ifdef RENEWAL
+ 100;
+#else
+ 1000;
+#endif
+ short t_class, s_class, s_race2, t_race2;
struct status_data *sstatus, *tstatus;
int i;
@@ -937,8 +995,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
break;
}
}
- if (cardfix != 1000)
- damage = damage * cardfix / 1000;
}
if( tsd && !(nk&NK_NO_CARDFIX_DEF) )
@@ -961,8 +1017,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix = cardfix * (100 - tsd->subrace2[s_race2]) / 100;
cardfix = cardfix * (100 - tsd->subrace[sstatus->race]) / 100;
cardfix = cardfix * (100 - tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS]) / 100;
- if( sstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100-tsd->subrace[RC_NONDEMIHUMAN]) / 100;
for(i=0; i < ARRAYLENGTH(tsd->add_mdef) && tsd->add_mdef[i].rate;i++) {
if(tsd->add_mdef[i].class_ == s_class) {
@@ -982,16 +1036,25 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
if( tsd->sc.data[SC_PROTECT_MDEF] )
cardfix = cardfix * ( 100 - tsd->sc.data[SC_PROTECT_MDEF]->val1 ) / 100;
-
- if( cardfix != 1000 )
- damage = damage * cardfix / 1000;
}
+#ifdef RENEWAL
+ if ( cardfix != 100 )
+ damage += damage * (cardfix - 100) / 100;
+#else
+ if ( cardfix != 1000 )
+ damage = damage * cardfix / 1000;
+#endif
break;
case BF_WEAPON:
t_race2 = status->get_race2(target);
if( cflag&2 ){
if( sd && !(nk&NK_NO_CARDFIX_ATK) ){
- short cardfix_ = 1000;
+ short cardfix_ =
+#ifdef RENEWAL
+ 100;
+#else
+ 1000;
+#endif
if( sd->state.arrow_atk ){
cardfix = cardfix * (100 + sd->right_weapon.addrace[tstatus->race] + sd->arrow_addrace[tstatus->race]) / 100;
if( !(nk&NK_NO_ELEFIX) ){
@@ -1009,8 +1072,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix = cardfix * (100 + sd->right_weapon.addsize[tstatus->size]+sd->arrow_addsize[tstatus->size]) / 100;
cardfix = cardfix * (100 + sd->right_weapon.addrace2[t_race2]) / 100;
cardfix = cardfix * (100 + sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS] + sd->arrow_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100 + sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->arrow_addrace[RC_NONDEMIHUMAN]) / 100;
}else{ // Melee attack
if( !battle_config.left_cardfix_to_right ){
cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100;
@@ -1029,8 +1090,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix = cardfix * (100+sd->right_weapon.addsize[tstatus->size]) / 100;
cardfix = cardfix * (100+sd->right_weapon.addrace2[t_race2]) / 100;
cardfix = cardfix * (100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100 + sd->right_weapon.addrace[RC_NONDEMIHUMAN]) / 100;
if( cflag&1 ){
cardfix_ = cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100;
@@ -1049,8 +1108,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix_ = cardfix_ * (100+sd->left_weapon.addsize[tstatus->size]) / 100;
cardfix_ = cardfix_ * (100+sd->left_weapon.addrace2[t_race2]) / 100;
cardfix_ = cardfix_ * (100+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix_ = cardfix_*(100+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100;
}
}else{
int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele];
@@ -1076,8 +1133,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix = cardfix * (100 + sd->right_weapon.addsize[tstatus->size] + sd->left_weapon.addsize[tstatus->size])/100;
cardfix = cardfix * (100 + sd->right_weapon.addrace2[t_race2] + sd->left_weapon.addrace2[t_race2])/100;
cardfix = cardfix * (100 + sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS] + sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100;
- if( tstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100+sd->right_weapon.addrace[RC_NONDEMIHUMAN] + sd->left_weapon.addrace[RC_NONDEMIHUMAN]) / 100;
}
}
@@ -1099,11 +1154,16 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
#ifndef RENEWAL
if( wflag&BF_LONG )
cardfix = cardfix * (100 + sd->bonus.long_attack_atk_rate) / 100;
-#endif
if( (cflag&1) && cardfix_ != 1000 )
damage = damage * cardfix_ / 1000;
else if( cardfix != 1000 )
damage = damage * cardfix / 1000;
+#else
+ if ( (cflag & 1) && cardfix_ != 100 )
+ damage += damage * (cardfix - 100) / 100;
+ else if ( cardfix != 100 )
+ damage += damage * (cardfix - 100) / 100;
+#endif
}
}else{
// Target side
@@ -1137,8 +1197,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
cardfix = cardfix * (100-tsd->subrace2[s_race2]) / 100;
cardfix = cardfix * (100-tsd->subrace[sstatus->race]) / 100;
cardfix = cardfix * (100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS]) / 100;
- if( sstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100-tsd->subrace[RC_NONDEMIHUMAN]) / 100;
for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ ){
if( tsd->add_def[i].class_ == s_class )
@@ -1147,52 +1205,59 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
break;
}
}
-
+#ifndef RENEWAL
if( wflag&BF_SHORT )
cardfix = cardfix * (100 - tsd->bonus.near_attack_def_rate) / 100;
else // BF_LONG (there's no other choice)
cardfix = cardfix * (100 - tsd->bonus.long_attack_def_rate) / 100;
-
+#endif
if( tsd->sc.data[SC_PROTECT_DEF] )
cardfix = cardfix * (100 - tsd->sc.data[SC_PROTECT_DEF]->val1) / 100;
-
+#ifdef RENEWAL
+ if ( cardfix != 100 )
+ damage += damage * (cardfix - 100) / 100;
+#else
if( cardfix != 1000 )
damage = damage * cardfix / 1000;
+#endif
}
}
break;
case BF_MISC:
- if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
- // misc damage reduction from equipment
- if (!(nk&NK_NO_ELEFIX))
+ if ( tsd && !(nk&NK_NO_CARDFIX_DEF) ) {
+ // misc damage reduction from equipment
+#ifndef RENEWAL
+ if ( !(nk&NK_NO_ELEFIX) )
{
int ele_fix = tsd->subele[s_ele];
for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
{
if(tsd->subele2[i].ele != s_ele) continue;
if(!(tsd->subele2[i].flag&wflag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&wflag&BF_RANGEMASK &&
- tsd->subele2[i].flag&wflag&BF_SKILLMASK))
+ tsd->subele2[i].flag&wflag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&wflag&BF_SKILLMASK))
continue;
ele_fix += tsd->subele2[i].rate;
}
cardfix = cardfix * (100 - ele_fix) / 100;
}
- cardfix = cardfix*(100-tsd->subsize[sstatus->size]) / 100;
- cardfix = cardfix*(100-tsd->subrace2[s_race2]) / 100;
cardfix = cardfix*(100-tsd->subrace[sstatus->race]) / 100;
cardfix = cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS]) / 100;
- if( sstatus->race != RC_DEMIHUMAN )
- cardfix = cardfix * (100 - tsd->subrace[RC_NONDEMIHUMAN]) / 100;
-
- cardfix = cardfix * ( 100 - tsd->bonus.misc_def_rate ) / 100;
if( wflag&BF_SHORT )
cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
else // BF_LONG (there's no other choice)
cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
-
- if (cardfix != 1000)
+#endif
+ cardfix = cardfix*(100 - tsd->subsize[sstatus->size]) / 100;
+ cardfix = cardfix*(100 - tsd->subrace2[s_race2]) / 100;
+ cardfix = cardfix * (100 - tsd->bonus.misc_def_rate) / 100;
+#ifdef RENEWAL
+ if ( cardfix != 100 )
+ damage += damage * (cardfix - 100) / 100;
+#else
+ if ( cardfix != 1000 )
damage = damage * cardfix / 1000;
+#endif
}
break;
}
@@ -1207,6 +1272,7 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_
* &2 - pdef(Pierce defense)
* &4 - tdef(Total defense reduction)
*------------------------------------------*/
+// TODO: Add an enum for flag
int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int flag, int pdef){
struct status_data *sstatus, *tstatus;
struct map_session_data *sd, *tsd;
@@ -1244,21 +1310,26 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_
#endif
if ( sd ) {
+ if ( sd->charm_type == CHARM_TYPE_LAND && sd->charm_count > 0 ) // hidden from status window
+ def1 += 10 * def1 * sd->charm_count / 100;
+
i = sd->ignore_def[is_boss(target) ? RC_BOSS : RC_NONBOSS];
i += sd->ignore_def[tstatus->race];
if ( i ) {
if ( i > 100 ) i = 100;
def1 -= def1 * i / 100;
+#ifndef RENEWAL
def2 -= def2 * i / 100;
+#endif
}
- if (sd->charm_type == CHARM_TYPE_LAND && sd->charm_count > 0 ) // hidden from status window
- def1 += 10 * def1 * sd->charm_count / 100;
}
if( sc && sc->data[SC_EXPIATIO] ){
i = 5 * sc->data[SC_EXPIATIO]->val1; // 5% per level
def1 -= def1 * i / 100;
+#ifndef RENEWAL
def2 -= def2 * i / 100;
+#endif
}
if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type ) {
@@ -1275,7 +1346,9 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_
def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
}
}
+#ifndef RENEWAL
if(skill_id == AM_ACIDTERROR) def1 = 0; //Acid Terror ignores only armor defense. [Skotlex]
+#endif
if(def2 < 1) def2 = 1;
}
//Vitality reduction from rodatazone: http://rodatazone.simgaming.net/mechanics/substats.php#def
@@ -1403,6 +1476,7 @@ int battle_calc_chorusbonus(struct map_session_data *sd) {
return members - 2; // Effect bonus from additional Minstrel's/Wanderer's if not above the max possible
}
+// FIXME: flag is undocumented
int battle_calc_skillratio(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int skillratio, int flag){
int i;
struct status_change *sc, *tsc;
@@ -1927,7 +2001,11 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
skillratio += 20 * skill_lv;
break;
case AM_ACIDTERROR:
+#ifdef RENEWAL
+ skillratio += 80 * skill_lv + 100;
+#else
skillratio += 40 * skill_lv;
+#endif
break;
case MO_FINGEROFFENSIVE:
skillratio+= 50 * skill_lv;
@@ -1935,8 +2013,8 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
case MO_INVESTIGATE:
skillratio += 75 * skill_lv;
break;
- #ifndef RENEWAL
case MO_EXTREMITYFIST:
+ #ifndef RENEWAL
{
//Overflow check. [Skotlex]
unsigned int ratio = skillratio + 100*(8 + st->sp/10);
@@ -1944,8 +2022,8 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
if (ratio > 60000) ratio = 60000; //We leave some room here in case skillratio gets further increased.
skillratio = (unsigned short)ratio;
}
+#endif
break;
- #endif
case MO_TRIPLEATTACK:
skillratio += 20 * skill_lv;
break;
@@ -2050,14 +2128,11 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
case GS_TRACKING:
skillratio += 100 * (skill_lv+1);
break;
+#ifndef RENEWAL
case GS_PIERCINGSHOT:
-#ifdef RENEWAL
- if( sd && sd->weapontype1 == W_RIFLE )
- skillratio += 50 + 30 * skill_lv;
- else
-#endif
skillratio += 20 * skill_lv;
break;
+#endif
case GS_RAPIDSHOWER:
skillratio += 10 * skill_lv;
break;
@@ -2456,7 +2531,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
}
break;
case GN_CARTCANNON:
- skillratio = 50 * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5) * (st->int_ / 40) + 60 * skill_lv;
+ skillratio += -100 + (int)(50.0f * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5) * (st->int_ / 40.0f) + 60.0f * skill_lv);
break;
case GN_SPORE_EXPLOSION:
skillratio = 100 * skill_lv + (200 + st->int_) * status->get_lv(src) / 100;
@@ -2705,6 +2780,8 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
group->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX);
} else
skill->del_unitgroup(group,ALC_MARK);
+ if (--group->val3<=0)
+ skill->del_unitgroup(group,ALC_MARK);
#else
if (--group->val2<=0)
skill->del_unitgroup(group,ALC_MARK);
@@ -2920,11 +2997,11 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if(sc->data[SC_DEFENDER] &&
((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON) || skill_id == CR_ACIDDEMONSTRATION))
damage = damage * ( 100 - sc->data[SC_DEFENDER]->val2 ) / 100;
-
+#ifndef RENEWAL
if(sc->data[SC_GS_ADJUSTMENT] &&
(flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
damage -= damage * 20 / 100;
-
+#endif
if(sc->data[SC_FOGWALL]) {
if(flag&BF_SKILL) { //25% reduction
if ( !(skill->get_inf(skill_id)&INF_GROUND_SKILL) && !(skill->get_nk(skill_id)&NK_SPLASH) )
@@ -3076,28 +3153,31 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if( sc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) )
status->change_spread(bl, src); // Deadly infect attacked side
+
+ if ( sd && damage > 0 && (sce = sc->data[SC_GENTLETOUCH_ENERGYGAIN]) ) {
+ if ( rnd() % 100 < sce->val2 )
+ pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, 1), pc->getmaxspiritball(sd, 0));
+ }
}
//SC effects from caster side.
- sc = status->get_sc(src);
-
- if (sc && sc->count) {
- if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
+ if (tsc && tsc->count) {
+ if( tsc->data[SC_INVINCIBLE] && !tsc->data[SC_INVINCIBLEOFF] )
damage += damage * 75 / 100;
// [Epoque]
if (bl->type == BL_MOB) {
int i;
- if ( ((sce=sc->data[SC_MANU_ATK]) && (flag&BF_WEAPON)) ||
- ((sce=sc->data[SC_MANU_MATK]) && (flag&BF_MAGIC))
+ if ( ((sce=tsc->data[SC_MANU_ATK]) && (flag&BF_WEAPON)) ||
+ ((sce=tsc->data[SC_MANU_MATK]) && (flag&BF_MAGIC))
)
for (i=0;ARRAYLENGTH(mob->manuk)>i;i++)
if (((TBL_MOB*)bl)->class_==mob->manuk[i]) {
damage += damage * sce->val1 / 100;
break;
}
- if ( ((sce=sc->data[SC_SPL_ATK]) && (flag&BF_WEAPON)) ||
- ((sce=sc->data[SC_SPL_MATK]) && (flag&BF_MAGIC))
+ if ( ((sce=tsc->data[SC_SPL_ATK]) && (flag&BF_WEAPON)) ||
+ ((sce=tsc->data[SC_SPL_MATK]) && (flag&BF_MAGIC))
)
for (i=0;ARRAYLENGTH(mob->splendide)>i;i++)
if (((TBL_MOB*)bl)->class_==mob->splendide[i]) {
@@ -3114,14 +3194,19 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
sc_start(src,bl,tsc->data[SC_POISONINGWEAPON]->val2,rate,tsc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON,1) - (tstatus->vit + tstatus->luk) / 2 * 1000);
}
}
- if( sc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) )
+ if( tsc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * tsc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) )
status->change_spread(src, bl);
- if (sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 && damage > 0)
+ if (tsc->data[SC_SHIELDSPELL_REF] && tsc->data[SC_SHIELDSPELL_REF]->val1 == 1 && damage > 0)
skill->break_equip(bl,EQP_ARMOR,10000,BCT_ENEMY );
- if (sc->data[SC_STYLE_CHANGE] && rnd()%2) {
+ if (tsc->data[SC_STYLE_CHANGE] && rnd()%2) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
if (hd) homun->addspiritball(hd, 10);
}
+ if ( src->type == BL_PC && damage > 0 && (sce = tsc->data[SC_GENTLETOUCH_ENERGYGAIN]) ) {
+ struct map_session_data *tsd = (struct map_session_data *)src;
+ if ( tsd && rnd() % 100 < sce->val2 )
+ pc->addspiritball(tsd, skill->get_time(MO_CALLSPIRITS, 1), pc->getmaxspiritball(tsd, 0));
+ }
}
/* no data claims these settings affect anything other than players */
if( damage && sd && bl->type == BL_PC ) {
@@ -3191,6 +3276,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
/*==========================================
* Calculates BG related damage adjustments.
*------------------------------------------*/
+// FIXME: flag is undocumented
int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64 damage, int div_, uint16 skill_id, uint16 skill_lv, int flag)
{
if( !damage )
@@ -3209,6 +3295,7 @@ int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64
/*==========================================
* Calculates GVG related damage adjustments.
*------------------------------------------*/
+// FIXME: flag is undocumented
int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 damage,int div_,uint16 skill_id,uint16 skill_lv,int flag) {
struct mob_data* md = BL_CAST(BL_MOB, bl);
int class_ = status->get_class(bl);
@@ -3285,13 +3372,13 @@ void battle_consume_ammo(TBL_PC*sd, int skill_id, int lv) {
if (!battle_config.arrow_decrement)
return;
- if (skill_id) {
+ if (skill_id && lv) {
qty = skill->get_ammo_qty(skill_id, lv);
if (!qty) qty = 1;
}
if(sd->equip_index[EQI_AMMO]>=0) //Qty check should have been done in skill_check_condition
- pc->delitem(sd,sd->equip_index[EQI_AMMO],qty,0,1,LOG_TYPE_CONSUME);
+ pc->delitem(sd, sd->equip_index[EQI_AMMO], qty, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME);
sd->state.arrow_atk = 0;
}
@@ -3345,6 +3432,7 @@ int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id) {
/*==========================================
* battle_calc_magic_attack [DracoRPG]
*------------------------------------------*/
+// FIXME: mflag is undocumented
struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) {
int nk;
short s_ele = 0;
@@ -3500,7 +3588,10 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
break;
default: {
MATK_ADD( status->get_matk(src, 2) );
-
+#ifdef RENEWAL
+ ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
+ ad.damage = battle->calc_cardfix2(src, target, ad.damage, s_ele, nk, ad.flag);
+#endif
if (nk&NK_SPLASHSPLIT) { // Divide MATK in case of multiple targets skill
if(mflag>0)
ad.damage/= mflag;
@@ -3520,7 +3611,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
skillratio = sc->data[SC_SPELLFIST]->val2 * 50 + sc->data[SC_SPELLFIST]->val4 * 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech]
ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
ad.flag = BF_WEAPON|BF_SHORT;
- ad.type = 0;
+ ad.type = BDT_NORMAL;
}
/* Fall through */
default:
@@ -3536,7 +3627,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
}
#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
- if( target && skill_id ) {
+ if (skill_id) {
for(i = 0; i < map->list[target->m].zone->capped_skills_count; i++) {
if( skill_id == map->list[target->m].zone->capped_skills[i]->nameid && (map->list[target->m].zone->capped_skills[i]->type & target->type) ) {
if( target->type == BL_MOB && map->list[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
@@ -3554,9 +3645,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
}
#endif
-#ifdef RENEWAL
- ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
-#endif
if(sd) {
uint16 rskill;/* redirect skill */
//Damage bonuses
@@ -3671,6 +3759,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
/*==========================================
* Calculate Misc damage for skill_id
*------------------------------------------*/
+// FIXME: mflag is undocumented
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;
@@ -3789,7 +3878,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
short tdef = status->get_total_def(target);
short tmdef = status->get_total_mdef(target);
int targetVit = min(120, status_get_vit(target));
- short totaldef = (tmdef + tdef - ((uint64)(tmdef + tdef) >> 32)) >> 1;
+ short totaldef = (tmdef + tdef - ((uint64)(tmdef + tdef) >> 32)) >> 1; // FIXME: What's the >> 32 supposed to do here? tmdef and tdef are both 16-bit...
matk = battle->calc_magic_attack(src, target, skill_id, skill_lv, mflag).damage;
atk = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, false, s_ele, ELE_NEUTRAL, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), md.flag);
@@ -3866,10 +3955,11 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
int ratio = 300 + 50 * skill_lv;
int64 matk = battle->calc_magic_attack(src, target, skill_id, skill_lv, mflag).damage;
short totaldef = status->get_total_def(target) + status->get_total_mdef(target);
- int64 atk = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, false, s_ele, ELE_NEUTRAL, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), md.flag);
-
+ int64 atk = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, false, s_ele, ELE_NEUTRAL, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), md.flag);
+#ifdef RENEWAL_EDP
if( sc && sc->data[SC_EDP] )
ratio >>= 1;
+#endif
md.damage = (matk + atk) * ratio / 100;
md.damage -= totaldef;
#endif
@@ -3895,7 +3985,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
case RA_CLUSTERBOMB:
case RA_FIRINGTRAP:
case RA_ICEBOUNDTRAP:
- md.damage = skill_lv * sstatus->dex + sstatus->int_ * 5 ;
+ md.damage = (int64)skill_lv * sstatus->dex + sstatus->int_ * 5 ;
RE_LVL_TMDMOD();
if(sd)
{
@@ -3909,7 +3999,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
break;
case WM_SOUND_OF_DESTRUCTION:
- md.damage = 1000 * skill_lv + sstatus->int_ * (sd ? pc->checkskill(sd,WM_LESSON) : 10);
+ md.damage = 1000 * (int64)skill_lv + sstatus->int_ * (sd ? pc->checkskill(sd,WM_LESSON) : 10);
md.damage += md.damage * 10 * battle->calc_chorusbonus(sd) / 100;
break;
/**
@@ -4011,7 +4101,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
}
}
#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
- if( target && skill_id ) {
+ if (skill_id) {
for(i = 0; i < map->list[target->m].zone->capped_skills_count; i++) {
if( skill_id == map->list[target->m].zone->capped_skills[i]->nameid && (map->list[target->m].zone->capped_skills[i]->type & target->type) ) {
if( target->type == BL_MOB && map->list[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
@@ -4030,6 +4120,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
}
#endif
md.damage = battle->calc_cardfix(BF_MISC, src, target, nk, s_ele, 0, md.damage, 0, md.flag);
+ md.damage = battle->calc_cardfix2(src, target, md.damage, s_ele, nk, md.flag);
if(skill_id){
uint16 rskill;/* redirect skill id */
switch(skill_id){
@@ -4100,6 +4191,7 @@ void battle_calc_misc_attack_unknown(struct block_list *src, struct block_list *
/*==========================================
* battle_calc_weapon_attack (by Skotlex)
*------------------------------------------*/
+// FIXME: wflag is undocumented
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.
@@ -4128,6 +4220,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
unsigned weapon : 1; ///< It's a weapon attack (consider VVS, and all that)
#ifdef RENEWAL
unsigned tdef : 1; ///< Total defense reduction
+ unsigned distinct : 1; ///< Has its own battle calc formula
#endif
} flag;
@@ -4149,13 +4242,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
flag.infdef = 1; // Reverberation takes 1 damage
//Initial Values
- wd.type=0; //Normal attack
- wd.div_=skill_id?skill->get_num(skill_id,skill_lv):1;
+ wd.type = BDT_NORMAL;
+ 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_id ? skill->get_blewcount(skill_id,skill_lv) : 0;
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
@@ -4216,7 +4309,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case TF_DOUBLE: //For NPC used skill.
case GS_CHAINACTION:
- wd.type = 0x08;
+ wd.type = BDT_MULTIHIT;
break;
case GS_GROUNDDRIFT:
@@ -4255,13 +4348,28 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if( tsc && (tsc->data[SC_WUGBITE] || tsc->data[SC_ANKLESNARE] || tsc->data[SC_ELECTRICSHOCKER]) )
wd.div_ = tstatus->size + 2 + ( (rnd()%100 < 50-tstatus->size*10) ? 1 : 0 );
break;
+
+ case NPC_EARTHQUAKE:
+ wd.flag = (wd.flag&~(BF_WEAPON)) | BF_MAGIC;
+ break;
#ifdef RENEWAL
+ case MO_EXTREMITYFIST:
+ case GS_PIERCINGSHOT:
+ case AM_ACIDTERROR:
+ case AM_DEMONSTRATION:
+ case NJ_ISSEN:
+ case PA_SACRIFICE:
+ flag.distinct = 1;
+ break;
+ case GN_CARTCANNON:
case PA_SHIELDCHAIN:
- case NJ_KUNAI:
- case HW_MAGICCRASHER:
- case NJ_SYURIKEN:
case GS_MAGICALBULLET:
+ case NJ_SYURIKEN:
case KO_BAKURETSU:
+ flag.distinct = 1;
+ /* Fall through */
+ case NJ_KUNAI:
+ case HW_MAGICCRASHER:
flag.tdef = 1;
break;
#endif
@@ -4270,15 +4378,15 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
wd.flag |= flag.arrow?BF_LONG:BF_SHORT;
if ((!skill_id || skill_id == PA_SACRIFICE) && tstatus->flee2 && rnd()%1000 < tstatus->flee2) {
//Check for Lucky Dodge
- wd.type=0x0b;
+ wd.type = BDT_PDODGE;
wd.dmg_lv=ATK_LUCKY;
if (wd.div_ < 0) wd.div_*=-1;
return wd;
}
- s_ele = s_ele_ = skill->get_ele(skill_id, skill_lv);
- if( !skill_id || s_ele == -1 )
- { //Take weapon's element
+ s_ele = s_ele_ = skill_id ? skill->get_ele(skill_id, skill_lv) : -1;
+ if (s_ele == -1) {
+ //Take weapon's element
s_ele = sstatus->rhw.ele;
s_ele_ = sstatus->lhw.ele;
if (sd && sd->charm_type != CHARM_TYPE_NONE && sd->charm_count >= MAX_SPIRITCHARM) {
@@ -4289,13 +4397,14 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
s_ele = sd->bonus.arrow_ele;
if( battle_config.attack_attr_none&src->type )
n_ele = true; //Weapon's element is "not elemental"
- }
- else if( s_ele == -2 ) //Use enchantment's element
+ } else if (s_ele == -2) {
+ //Use enchantment's element
s_ele = s_ele_ = status_get_attack_sc_element(src,sc);
- else if( s_ele == -3 ) //Use random element
+ } else if (s_ele == -3) {
+ //Use random element
s_ele = s_ele_ = rnd()%ELE_MAX;
- switch( skill_id )
- {
+ }
+ switch (skill_id) {
case GS_GROUNDDRIFT:
s_ele = s_ele_ = wflag; //element comes in flag.
break;
@@ -4337,13 +4446,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
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.type = 0x08;
+ wd.type = BDT_MULTIHIT;
}
}
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.type = 0x08;
+ wd.type = BDT_MULTIHIT;
}
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){
@@ -4374,13 +4483,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if ( wd.div_ > 1 ) {
wd.div_ = min(wd.div_, sd->status.inventory[i].amount);
sc->data[SC_FEARBREEZE]->val4 = wd.div_ - 1;
- wd.type = 0x08;
+ wd.type = BDT_MULTIHIT;
}
}
}
//Check for critical
- if( !flag.cri && !(wd.type&0x08) && sstatus->cri &&
+ if( !flag.cri && wd.type != BDT_MULTIHIT && sstatus->cri &&
(!skill_id ||
skill_id == KN_AUTOCOUNTER ||
skill_id == SN_SHARPSHOOTING || skill_id == MA_SHARPSHOOTING ||
@@ -4432,7 +4541,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
flag.cri = 1;
}
if (flag.cri) {
- wd.type = 0x0a;
+ wd.type = BDT_CRIT;
#ifndef RENEWAL
flag.idef = flag.idef2 =
#endif
@@ -4590,8 +4699,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
#define ATK_ADD( a ) do { int64 temp__ = (a); wd.damage += temp__; if (flag.lh) wd.damage2 += temp__; } while(0)
#define ATK_ADD2( a , b ) do { wd.damage += (a); if (flag.lh) wd.damage2 += (b); } while(0)
#ifdef RENEWAL
-#define GET_NORMAL_ATTACK( f ) ( wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (f), wd.flag) )
-#define GET_NORMAL_ATTACK2( f ) ( wd.damage2 = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, (f), wd.flag) )
+#define GET_NORMAL_ATTACK( f , s ) ( wd.damage = battle->calc_base_damage(src, target, s, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (f), wd.flag) )
+#define GET_NORMAL_ATTACK2( f , s ) ( wd.damage2 = battle->calc_base_damage(src, target, s, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, (f), wd.flag) )
#endif
switch (skill_id) {
//Calc base damage according to skill
@@ -4610,7 +4719,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
{
short totaldef = status->get_total_def(target);
i = 0;
- GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) );
+ GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0 );
if( sc && sc->data[SC_NJ_BUNSINJYUTSU] && (i=sc->data[SC_NJ_BUNSINJYUTSU]->val2) > 0 )
wd.div_ = ~( i++ + 2 ) + 1;
if( wd.damage ){
@@ -4623,18 +4732,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
break;
case NJ_SYURIKEN: // [malufett]
- GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) );
- wd.damage += battle->calc_masteryfix(src, target, skill_id, skill_lv, 4 * skill_lv + (sd ? sd->bonus.arrow_atk : 0), wd.div_, 0, flag.weapon);
- break;
- case MO_EXTREMITYFIST: // [malufett]
- {
- short totaldef = status->get_total_def(target);
- GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|8 );
- if( wd.damage ){
- wd.damage = (250 + 150 * skill_lv) + (10 * (status_get_sp(src)+1) * wd.damage / 100) + (8 * wd.damage);
- ATK_ADD(-totaldef);
- }
- }
+ GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0);
+ ATK_ADD(battle->calc_masteryfix(src, target, skill_id, skill_lv, 4 * skill_lv + (sd ? sd->bonus.arrow_atk : 0), wd.div_, 0, flag.weapon));
#endif
break;
#ifndef RENEWAL
@@ -4710,11 +4809,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
i |= 16; // for ex. shuriken must not be influenced by DEX
}
#ifdef RENEWAL
- GET_NORMAL_ATTACK( i );
+ GET_NORMAL_ATTACK( i, skill_id);
wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
+ wd.damage = battle->calc_cardfix2(src, target, wd.damage, s_ele, nk, wd.flag);
if (flag.lh){
- GET_NORMAL_ATTACK2( i );
+ GET_NORMAL_ATTACK2( i, skill_id );
wd.damage2 = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage2, wd.div_, 1, flag.weapon);
+ wd.damage2 = battle->calc_cardfix2(src, target, wd.damage2, s_ele, nk, wd.flag);
}
#else
wd.damage = battle->calc_base_damage2(sstatus, &sstatus->rhw, sc, tstatus->size, sd, i);
@@ -4730,8 +4831,10 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
//Add any bonuses that modify the base baseatk+watk (pre-skills)
if(sd) {
+#ifndef RENEWAL
if (sd->bonus.atk_rate)
ATK_ADDRATE(sd->bonus.atk_rate);
+#endif
if(flag.cri && sd->bonus.crit_atk_rate)
ATK_ADDRATE(sd->bonus.crit_atk_rate);
if(flag.cri && sc && sc->data[SC_MTF_CRIDAMAGE])
@@ -4775,7 +4878,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case KO_BAKURETSU:
{
#ifdef RENEWAL
- GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0));
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), skill_id);
#endif
skillratio = skill_lv * (50 + status_get_dex(src) / 4);
skillratio = (int)(skillratio * (sd ? pc->checkskill(sd, NJ_TOBIDOUGU) : 10) * 40.f / 100.0f * status->get_lv(src) / 120);
@@ -4784,7 +4887,32 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
break;
#ifdef RENEWAL
+ case GS_MAGICALBULLET:
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), skill_id);
+ ATK_ADD(battle->attr_fix(src, target,
+ battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, status->get_matk(src, 2), 0, wd.flag), ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv));
+ break;
+ case GS_PIERCINGSHOT:
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), 0);
+ if ( wd.damage ) {
+ if ( sd && sd->weapontype1 == W_RIFLE )
+ ATK_RATE(30 * (skill_lv + 5));
+ else
+ ATK_RATE(20 * (skill_lv + 5));
+ }
+ break;
+ case MO_EXTREMITYFIST: // [malufett]
+ {
+ short totaldef = status->get_total_def(target);
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | 8, skill_id);
+ if ( wd.damage ) {
+ ATK_ADD(250 * (skill_lv + 1) + (10 * (status_get_sp(src) + 1) * wd.damage / 100) + (8 * wd.damage));
+ ATK_ADD(-totaldef);
+ }
+ }
+ break;
case PA_SHIELDCHAIN:
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), skill_id);
if ( sd ) {
short index = sd->equip_index[EQI_HAND_L];
if ( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR ) {
@@ -4794,6 +4922,32 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_ADD(sstatus->rhw.atk2); //Else use Atk2
ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag));
break;
+ case AM_DEMONSTRATION:
+ case AM_ACIDTERROR: // [malufett/Hercules]
+ {
+ int64 matk;
+ int totaldef = status->get_total_def(target) + status->get_total_mdef(target);
+ matk = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, status->get_matk(src, 2), 0, wd.flag);
+ matk = battle->attr_fix(src, target, matk, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
+ matk = matk * battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag) / 100;
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), 0);
+ ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag));
+ ATK_ADD(matk);
+ ATK_ADD(-totaldef);
+ if ( skill_id == AM_ACIDTERROR && is_boss(target) )
+ ATK_RATE(50);
+ if ( skill_id == AM_DEMONSTRATION )
+ wd.damage = max(wd.damage, 1);
+ }
+ break;
+ case GN_CARTCANNON:
+ GET_NORMAL_ATTACK((sc && sc->data[SC_MAXIMIZEPOWER] ? 1 : 0) | (sc && sc->data[SC_WEAPONPERFECT] ? 8 : 0), skill_id);
+ ATK_ADD(sd ? sd->bonus.arrow_atk : 0);
+ wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
+ ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag));
+ if ( sd && s_ele != sd->bonus.arrow_ele )
+ s_ele = sd->bonus.arrow_ele;
+ break;
case NJ_TATAMIGAESHI:
ATK_RATE(200);
/* Fall through */
@@ -4801,7 +4955,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case ML_SPIRALPIERCE: // [malufett]
if( skill_id != NJ_TATAMIGAESHI ){
short index = sd?sd->equip_index[EQI_HAND_R]:0;
- GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) );
+ GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0);
wd.damage = wd.damage * 70 / 100;
//n_ele = true; // FIXME: This is has no effect if it's after GET_NORMAL_ATTACK (was this intended, or was it supposed to be put above?)
@@ -4818,6 +4972,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_RATE(85);
}
wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
+ wd.damage = battle->calc_cardfix2(src, target, wd.damage, s_ele, nk, wd.flag);
}
/* Fall through */
#endif
@@ -4845,13 +5000,11 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if(sd && sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST)
ATK_ADD(10*pc->checkskill(sd, TK_RUN));
break;
- case GS_MAGICALBULLET:
+
#ifndef RENEWAL
+ case GS_MAGICALBULLET:
ATK_ADD( status->get_matk(src, 2) );
-#else
- ATK_ADD( battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage );
-#endif
-#ifndef RENEWAL
+ break;
case NJ_SYURIKEN:
ATK_ADD(4*skill_lv);
#endif
@@ -4886,15 +5039,15 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
break;
case SR_GATEOFHELL:
- ATK_ADD (sstatus->max_hp - status_get_hp(src));
- if(sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE) {
- ATK_ADD( (sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status->get_lv(src) );
+ ATK_ADD(sstatus->max_hp - status_get_hp(src));
+ if ( sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE ) {
+ ATK_ADD((sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status->get_lv(src));
} else {
- ATK_ADD( (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_FALLENEMPIRE:// [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)]
- ATK_ADD( ((tstatus->size+1)*2 + skill_lv - 1) * sstatus->str);
+ ATK_ADD( ((tstatus->size+1)*2 + (int64)skill_lv - 1) * sstatus->str);
if( tsd && tsd->weight ){
ATK_ADD( (tsd->weight/10) * sstatus->dex / 120 );
}else{
@@ -5045,7 +5198,11 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
}
- if(!flag.idef || !flag.idef2) { //Defense reduction
+ if((!flag.idef || !flag.idef2)
+#ifdef RENEWAL
+ && (!flag.distinct || flag.tdef)
+#endif
+ ) { //Defense reduction
wd.damage = battle->calc_defense(BF_WEAPON, src, target, skill_id, skill_lv, wd.damage,
(flag.idef?1:0)|(flag.pdef?2:0)
#ifdef RENEWAL
@@ -5062,8 +5219,19 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
#ifdef RENEWAL
+ if ( flag.distinct ) {
+ wd.damage = battle->calc_cardfix2(src, target, wd.damage, s_ele, nk, wd.flag);
+ if ( flag.lh ) {
+ wd.damage2 = battle->calc_cardfix2(src, target, wd.damage2, s_ele, nk, wd.flag);
+ }
+ }
//Div fix.
damage_div_fix(wd.damage, wd.div_);
+ if ( skill_id > 0 && (skill->get_ele(skill_id, skill_lv) == ELE_NEUTRAL || flag.distinct) ) { // re-evaluate forced neutral skills
+ wd.damage = battle->attr_fix(src, target, wd.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
+ if ( flag.lh )
+ wd.damage2 = battle->attr_fix(src, target, wd.damage2, s_ele_, tstatus->def_ele, tstatus->ele_lv);
+ }
#endif
#if 0 // Can't find any source about this one even in eagis
if (skill_id == NPC_EARTHQUAKE) {
@@ -5146,7 +5314,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if(skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS)
return wd; //Enough, rest is not needed.
#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
- if( target && skill_id ) {
+ if (skill_id) {
for(i = 0; i < map->list[target->m].zone->capped_skills_count; i++) {
if( skill_id == map->list[target->m].zone->capped_skills[i]->nameid && (map->list[target->m].zone->capped_skills[i]->type & target->type) ) {
if( target->type == BL_MOB && map->list[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
@@ -5187,11 +5355,12 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_ADD(10*sd->status.inventory[index].refine);
}
}
-#endif
//Card Fix, tsd side
- 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?1:0), 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 ? 1 : 0), wd.flag);
}
+#endif
+
if( flag.infdef ) { //Plants receive 1 damage when hit
short class_ = status->get_class(target);
if( flag.hit || wd.damage > 0 )
@@ -5370,7 +5539,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
rnd()%100 < tsc->data[SC_SWORDREJECT]->val2
) {
ATK_RATER(50);
- status_fix_damage(target,src,wd.damage,clif->damage(target,src,0,0,wd.damage,0,0,0));
+ status_fix_damage(target,src,wd.damage,clif->damage(target,src,0,0,wd.damage,0,BDT_NORMAL,0));
clif->skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_SWORDREJECT]->val1,1);
if( --(tsc->data[SC_SWORDREJECT]->val3) <= 0 )
status_change_end(target, SC_SWORDREJECT, INVALID_TIMER);
@@ -5476,8 +5645,8 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
rdamage = ratio + (damage)* (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10;
skill->blown(target, src, skill->get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit->getdir(src), 0);
clif->skill_damage(target, src, tick, status_get_amotion(src), 0, rdamage,
- 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does
- clif->delay_damage(tick + delay, src, target,status_get_amotion(src)+1000,0, rdamage/10, 1, 0);
+ 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, BDT_SKILL); // This is how official does
+ clif->delay_damage(tick + delay, src, target,status_get_amotion(src)+1000,0, rdamage/10, 1, BDT_NORMAL);
status->damage(src, target, status->damage(target, src, rdamage, 0, 0, 1)/10, 0, 0, 1);
status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER);
/* shouldn't this trigger skill->additional_effect? */
@@ -5495,7 +5664,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
int64 rd1 = damage * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage.
trdamage += rdamage = rd1 - (damage = rd1 * 30 / 100); // not normalized as intended.
- rdelay = clif->skill_damage(src, target, tick, status_get_amotion(src), status_get_dmotion(src), -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, 6);
+ rdelay = clif->skill_damage(src, target, tick, status_get_amotion(src), status_get_dmotion(src), -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, BDT_SKILL);
skill->blown(target, src, skill->get_blewcount(RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1), unit->getdir(src), 0);
if( tsd ) /* is this right? rdamage as both left and right? */
@@ -5522,7 +5691,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
if ( tsd && tsd->bonus.short_weapon_damage_return ) {
NORMALIZE_RDAMAGE(damage * tsd->bonus.short_weapon_damage_return / 100);
- rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE);
/* is this right? rdamage as both left and right? */
battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
@@ -5547,9 +5716,9 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
NORMALIZE_RDAMAGE(damage * sc->data[SC_REFLECTSHIELD]->val2 / 100);
#ifndef RENEWAL
- rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE);
#else
- rdelay = clif->skill_damage(src, src, tick, delay, status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, 4);
+ rdelay = clif->skill_damage(src, src, tick, delay, status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, BDT_ENDURE);
#endif
/* is this right? rdamage as both left and right? */
if( tsd )
@@ -5583,7 +5752,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 ){
NORMALIZE_RDAMAGE(damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100);
- rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE);
/* is this right? rdamage as both left and right? */
if( tsd )
@@ -5597,7 +5766,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
if( ssc->data[SC_INSPIRATION] ) {
NORMALIZE_RDAMAGE(damage / 100);
- rdelay = clif->delay_damage(tick+delay,target, target, status_get_amotion(target), status_get_dmotion(target), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,target, target, status_get_amotion(target), status_get_dmotion(target), rdamage, 1, BDT_ENDURE);
/* is this right? rdamage as both left and right? */
if( sd )
@@ -5612,7 +5781,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
if ( tsd && tsd->bonus.long_weapon_damage_return ) {
NORMALIZE_RDAMAGE(damage * tsd->bonus.long_weapon_damage_return / 100);
- rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE);
/* is this right? rdamage as both left and right? */
battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
@@ -5707,7 +5876,7 @@ int battle_damage_area(struct block_list *bl, va_list ap) {
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,amotion,dmotion,damage,1,ATK_BLOCK,0);
+ clif->damage(bl,bl,amotion,dmotion,damage,1,BDT_ENDURE,0);
if( !(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();
@@ -5718,6 +5887,7 @@ int battle_damage_area(struct block_list *bl, va_list ap) {
/*==========================================
* Do a basic physical attack (call trough unit_attack_timer)
*------------------------------------------*/
+// FIXME: flag is undocumented
enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, int64 tick, int flag) {
struct map_session_data *sd = NULL, *tsd = NULL;
struct status_data *sstatus, *tstatus;
@@ -5753,10 +5923,10 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
{
int index = sd->equip_index[EQI_AMMO];
if (index<0) {
- if (sd->weapontype1 > W_KATAR && sd->weapontype1 < W_HUUMA)
- clif->arrow_fail(sd, 0);
- else
+ if ( sd->weapontype1 > W_KATAR && sd->weapontype1 < W_HUUMA )
clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0);
+ else
+ clif->arrow_fail(sd, 0);
return ATK_NONE;
}
//Ammo check by Ishizu-chan
@@ -5799,7 +5969,7 @@ 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, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
+ clif->damage(src, target, sstatus->amotion, 1, 0, 1, BDT_NORMAL, 0); //Display MISS.
status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER);
skill->attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skill_lv,tick,0);
return ATK_BLOCK;
@@ -5812,7 +5982,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER);
if(sc_start4(target, src, SC_BLADESTOP, 100, sd?pc->checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration)) {
//Target locked.
- clif->damage(src, target, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
+ clif->damage(src, target, sstatus->amotion, 1, 0, 1, BDT_NORMAL, 0); //Display MISS.
clif->bladestop(target, src->id, 1);
sc_start4(target, target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration);
return ATK_BLOCK;
@@ -5856,18 +6026,6 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
return ATK_DEF;
return ATK_MISS;
}
- if( sc->data[SC_GENTLETOUCH_ENERGYGAIN] ) {
- if( sd && rnd()%100 < 10 + 5 * sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1)
- pc->addspiritball(sd,
- skill->get_time(MO_CALLSPIRITS, sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1),
- sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1);
- }
- if( tsc && tsc->data[SC_GENTLETOUCH_ENERGYGAIN] ) {
- if( tsd && rnd()%100 < 10 + 5 * tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1)
- pc->addspiritball(tsd,
- skill->get_time(MO_CALLSPIRITS, tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1),
- tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1);
- }
if( tsc && tsc->data[SC_MTF_MLEATKED] && rnd()%100 < 20 )
clif->skill_nodamage(target, target, SM_ENDURE, 5,
@@ -5890,7 +6048,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
if( sd && sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0 && sd->status.inventory[sd->equip_index[EQI_AMMO]].amount >= sc->data[SC_FEARBREEZE]->val4 && battle_config.arrow_decrement){
- pc->delitem(sd,sd->equip_index[EQI_AMMO],sc->data[SC_FEARBREEZE]->val4,0,1,LOG_TYPE_CONSUME);
+ pc->delitem(sd, sd->equip_index[EQI_AMMO], sc->data[SC_FEARBREEZE]->val4, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME);
sc->data[SC_FEARBREEZE]->val4 = 0;
}
}
@@ -5938,7 +6096,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, 0, 0, damage, 0, 0, 0);
+ clif->damage(d_bl, d_bl, 0, 0, damage, 0, BDT_NORMAL, 0);
status_fix_damage(NULL, d_bl, damage, 0);
}
else
@@ -5946,7 +6104,7 @@ 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);
+ 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, BDT_SKILL);
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 ) {
@@ -6215,21 +6373,28 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
}
break;
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 && t_bl->id != s_bl->id)) //Zanzoe
- {
+ {
+ TBL_MOB *md = BL_CAST(BL_MOB, target);
+ if((
+ (md->special_state.ai == AI_SPHERE || (md->special_state.ai == AI_FLORA && battle_config.summon_flora&1))
+ && s_bl->type == BL_PC && src->type != BL_MOB
+ )
+ || (md->special_state.ai == AI_ZANZOU && t_bl->id != s_bl->id)
+ ) {
//Targetable by players
state |= BCT_ENEMY;
strip_enemy = 0;
}
break;
+ }
case BL_SKILL:
{
TBL_SKILL *su = (TBL_SKILL*)target;
if( !su->group )
return 0;
- if( skill->get_inf2(su->group->skill_id)&INF2_TRAP && su->group->unit_id != UNT_USED_TRAPS) { //Only a few skills can target traps...
+ if( skill->get_inf2(su->group->skill_id)&INF2_TRAP &&
+ su->group->unit_id != UNT_USED_TRAPS &&
+ su->group->unit_id != UNT_NETHERWORLD ) { //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
case RK_DRAGONBREATH_WATER:
@@ -6367,8 +6532,8 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
) {
if( t_bl->type == BL_PC && (sd->duel_group == ((TBL_PC*)t_bl)->duel_group) )
return (BCT_ENEMY&flag)?1:-1; // Duel targets can ONLY be your enemy, nothing else.
- else
- return 0; // You can't target anything out of your duel
+ else if ( src->type != BL_SKILL || (flag&BCT_ENEMY) )
+ return 0;
}
}
if( map_flag_gvg(m) && !sd->status.guild_id && t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->class_ == MOBID_EMPERIUM )
@@ -6384,19 +6549,16 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
&& md->guardian_data && (md->guardian_data->g || md->guardian_data->castle->guild_id) )
return 0; // Disable guardians/emperium owned by Guilds on non-woe times.
- if( !md->special_state.ai )
- { //Normal mobs
- if(
- ( target->type == BL_MOB && t_bl->type == BL_PC && ( ((TBL_MOB*)target)->special_state.ai != 4 && ((TBL_MOB*)target)->special_state.ai != 1 ) ) ||
- ( t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai )
- )
+ if (md->special_state.ai == AI_NONE) {
+ //Normal mobs
+ struct mob_data *target_md = BL_CAST(BL_MOB, target);
+ if( (target_md && t_bl->type == BL_PC && target_md->special_state.ai != AI_ZANZOU && target_md->special_state.ai != AI_ATTACK)
+ || (t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai) )
state |= BCT_PARTY; //Normal mobs with no ai are friends.
else
state |= BCT_ENEMY; //However, all else are enemies.
- }
- else
- {
- if( t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai )
+ } else {
+ if (t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->special_state.ai == AI_NONE)
state |= BCT_ENEMY; //Natural enemy for AI mobs are normal mobs.
}
break;
@@ -7287,6 +7449,7 @@ void battle_defaults(void) {
battle->attr_ratio = battle_attr_ratio;
battle->attr_fix = battle_attr_fix;
battle->calc_cardfix = battle_calc_cardfix;
+ battle->calc_cardfix2 = battle_calc_cardfix2;
battle->calc_elefix = battle_calc_elefix;
battle->calc_masteryfix = battle_calc_masteryfix;
battle->calc_chorusbonus = battle_calc_chorusbonus;