diff options
Diffstat (limited to 'src/map/battle.c')
-rw-r--r-- | src/map/battle.c | 631 |
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; |