diff options
Diffstat (limited to 'src/map/battle.c')
-rw-r--r-- | src/map/battle.c | 627 |
1 files changed, 282 insertions, 345 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index 64fda033f..f51240810 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2016 Hercules Dev Team + * Copyright (C) 2012-2018 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify @@ -20,11 +20,11 @@ */ #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 #include "battle.h" #include "map/battleground.h" -#include "map/chrif.h" +#include "map/clan.h" #include "map/clif.h" #include "map/elemental.h" #include "map/guild.h" @@ -59,7 +59,7 @@ #include <string.h> struct Battle_Config battle_config; -struct battle_interface battle_s; +static struct battle_interface battle_s; struct battle_interface *battle; /** @@ -68,7 +68,7 @@ struct battle_interface *battle; * @param bl The bl to check. * @return The current/last skill ID. */ -int battle_getcurrentskill(struct block_list *bl) +static int battle_getcurrentskill(struct block_list *bl) { const struct unit_data *ud; @@ -91,7 +91,8 @@ int battle_getcurrentskill(struct block_list *bl) /*========================================== * Get random targeting enemy *------------------------------------------*/ -int battle_gettargeted_sub(struct block_list *bl, va_list ap) { +static int battle_gettargeted_sub(struct block_list *bl, va_list ap) +{ struct block_list **bl_list; struct unit_data *ud; int target_id; @@ -119,7 +120,8 @@ int battle_gettargeted_sub(struct block_list *bl, va_list ap) { return 0; } -struct block_list* battle_gettargeted(struct block_list *target) { +static struct block_list *battle_gettargeted(struct block_list *target) +{ struct block_list *bl_list[24]; int c = 0; nullpo_retr(NULL, target); @@ -134,7 +136,8 @@ struct block_list* battle_gettargeted(struct block_list *target) { } //Returns the id of the current targeted character of the passed bl. [Skotlex] -int battle_gettarget(struct block_list* bl) { +static int battle_gettarget(struct block_list *bl) +{ nullpo_ret(bl); switch (bl->type) { @@ -149,7 +152,8 @@ int battle_gettarget(struct block_list* bl) { return 0; } -int battle_getenemy_sub(struct block_list *bl, va_list ap) { +static int battle_getenemy_sub(struct block_list *bl, va_list ap) +{ struct block_list **bl_list; struct block_list *target; int *c; @@ -177,7 +181,8 @@ int battle_getenemy_sub(struct block_list *bl, va_list ap) { } // Picks a random enemy of the given type (BL_PC, BL_CHAR, etc) within the range given. [Skotlex] -struct block_list* battle_getenemy(struct block_list *target, int type, int range) { +static struct block_list *battle_getenemy(struct block_list *target, int type, int range) +{ struct block_list *bl_list[24]; int c = 0; @@ -193,7 +198,9 @@ struct block_list* battle_getenemy(struct block_list *target, int type, int rang return bl_list[rnd()%c]; } -int battle_getenemyarea_sub(struct block_list *bl, va_list ap) { + +static int battle_getenemyarea_sub(struct block_list *bl, va_list ap) +{ struct block_list **bl_list, *src; int *c, ignore_id; @@ -223,7 +230,8 @@ int battle_getenemyarea_sub(struct block_list *bl, va_list ap) { } // Pick a random enemy -struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int range, int type, int ignore_id) { +static struct block_list *battle_getenemyarea(struct block_list *src, int x, int y, int range, int type, int ignore_id) +{ struct block_list *bl_list[24]; int c = 0; @@ -239,7 +247,8 @@ struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int return bl_list[rnd()%c]; } -int battle_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) { +static int battle_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) +{ struct delay_damage *dat = (struct delay_damage *)data; if ( dat ) { @@ -280,7 +289,8 @@ int battle_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) { return 0; } -int battle_delay_damage(int64 tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects) { +static int battle_delay_damage(int64 tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects) +{ struct delay_damage *dat; struct status_change *sc; struct block_list *d_tbl = NULL; @@ -328,7 +338,8 @@ int battle_delay_damage(int64 tick, int amotion, struct block_list *src, struct return 0; } -int battle_attr_ratio(int atk_elem,int def_type, int def_lv) + +static int battle_attr_ratio(int atk_elem, int def_type, int def_lv) { if (atk_elem < ELE_NEUTRAL || atk_elem >= ELE_MAX) return 100; @@ -344,7 +355,7 @@ int battle_attr_ratio(int atk_elem,int def_type, int def_lv) * Added passing of the chars so that the status changes can affect it. [Skotlex] * Note: Passing src/target == NULL is perfectly valid, it skips SC_ checks. *------------------------------------------*/ -int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 damage,int atk_elem,int def_type, int def_lv) +static int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 damage, int atk_elem, int def_type, int def_lv) { struct status_change *sc=NULL, *tsc=NULL; int ratio; @@ -438,8 +449,10 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d return damage + (damage * (ratio - 100) / 100); } +// [malufett] //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] +static 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) +{ #ifdef RENEWAL int64 damage, eatk = 0; struct status_change *sc; @@ -511,6 +524,7 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u return 0; #endif } + /*========================================== * Calculates the standard damage of a normal attack assuming it hits, * it calculates nothing extra fancy, is needed for magnum breaks WATK_ELEMENT bonus. [Skotlex] @@ -525,7 +539,8 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u */ /* '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) { +static 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); @@ -562,7 +577,9 @@ int64 battle_calc_base_damage(struct block_list *src, struct block_list *bl, uin return damage; } -int64 battle_calc_base_damage2(struct status_data *st, struct weapon_atk *wa, struct status_change *sc, unsigned short t_size, struct map_session_data *sd, int flag) { + +static int64 battle_calc_base_damage2(struct status_data *st, struct weapon_atk *wa, struct status_change *sc, unsigned short t_size, struct map_session_data *sd, int flag) +{ unsigned int atkmin=0, atkmax=0; short type = 0; int64 damage = 0; @@ -643,7 +660,8 @@ int64 battle_calc_base_damage2(struct status_data *st, struct weapon_atk *wa, st return damage; } -int64 battle_calc_sizefix(struct map_session_data *sd, int64 damage, int type, int size, bool ignore){ +static int64 battle_calc_sizefix(struct map_session_data *sd, int64 damage, int type, int size, bool ignore) +{ //SizeFix only for players nullpo_retr(damage, sd); if (!(sd->special_state.no_sizefix || (ignore))) @@ -655,7 +673,8 @@ 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) { +static 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); int weapon, skill_lv; @@ -767,7 +786,8 @@ int64 battle_addmastery(struct map_session_data *sd,struct block_list *target,in /*========================================== * Calculates ATK masteries. *------------------------------------------*/ -int64 battle_calc_masteryfix(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int div, bool left, bool weapon) { +static int64 battle_calc_masteryfix(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int div, bool left, bool weapon) +{ int skill2_lv, i; struct status_change *sc; struct map_session_data *sd; @@ -875,7 +895,7 @@ int64 battle_calc_masteryfix(struct block_list *src, struct block_list *target, } #else if( skill_id != ASC_BREAKER && weapon ) // Adv Katar Mastery is does not applies to ASC_BREAKER, but other masteries DO apply >_> - if( sd->status.weapon == W_KATAR && (skill2_lv=pc->checkskill(sd,ASC_KATAR)) > 0 ) + if (sd->weapontype == W_KATAR && (skill2_lv=pc->checkskill(sd,ASC_KATAR)) > 0) damage += damage * (10 + 2 * skill2_lv) / 100; #endif @@ -901,14 +921,16 @@ int64 battle_calc_masteryfix(struct block_list *src, struct block_list *target, return damage; } -void battle_calc_masteryfix_unknown(struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, int64 *damage, int *div, bool *left, bool *weapon) { +static void battle_calc_masteryfix_unknown(struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, int64 *damage, int *div, bool *left, bool *weapon) +{ } /*========================================== * 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){ +static 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; nullpo_ret(src); @@ -953,7 +975,8 @@ 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) { +static 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; @@ -984,6 +1007,7 @@ int64 battle_calc_cardfix2(struct block_list *src, struct block_list *bl, int64 #endif return damage; } + /*========================================== * Calculates card bonuses damage adjustments. * cflag(cardfix flag): @@ -991,13 +1015,10 @@ int64 battle_calc_cardfix2(struct block_list *src, struct block_list *bl, int64 * &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){ +static 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; -#ifdef RENEWAL - short cardfix = 100; -#else - short cardfix = 1000; -#endif + int cardfix = 1000; short t_class, s_class, s_race2, t_race2; struct status_data *sstatus, *tstatus; int i; @@ -1073,24 +1094,14 @@ 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; } -#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_ = -#ifdef RENEWAL - 100; -#else - 1000; -#endif + int cardfix_ = 1000; 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) ){ @@ -1190,16 +1201,11 @@ 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 @@ -1249,13 +1255,8 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ #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; @@ -1287,13 +1288,8 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ 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; } @@ -1309,7 +1305,8 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ * &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){ +static 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; struct status_change *sc, *tsc; @@ -1368,24 +1365,28 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_ #endif } - if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type ) { - unsigned char target_count; //256 max targets should be a sane max - target_count = unit->counttargeted(target); - if(target_count >= battle_config.vit_penalty_count) { - if(battle_config.vit_penalty_type == 1) { - if( !tsc || !tsc->data[SC_STEELBODY] ) - def1 = (def1 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - def2 = (def2 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100; - } else { //Assume type 2 - if( !tsc || !tsc->data[SC_STEELBODY] ) - def1 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; - def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num; + if (battle_config.vit_penalty_type != 0 && (battle_config.vit_penalty_target & target->type) != 0) { + int target_count = unit->counttargeted(target); + if (target_count >= battle_config.vit_penalty_count) { + int penalty = (target_count - (battle_config.vit_penalty_count - 1)) * battle_config.vit_penalty_num; + if (battle_config.vit_penalty_type == 1) { + if (tsc == NULL || tsc->data[SC_STEELBODY] == NULL) + def1 = def1 * (100 - penalty) / 100; + def2 = def2 * (100 - penalty) / 100; + } else { // Assume type 2 + if (tsc == NULL || tsc->data[SC_STEELBODY] == NULL) + def1 -= penalty; + def2 -= penalty; } } #ifndef RENEWAL - if(skill_id == AM_ACIDTERROR) def1 = 0; //Acid Terror ignores only armor defense. [Skotlex] + if (skill_id == AM_ACIDTERROR) + def1 = 0; // Acid Terror ignores only armor defense. [Skotlex] #endif - if(def2 < 1) def2 = 1; + if (def1 < 0) + def1 = 0; + if (def2 < 1) + def2 = 1; } //Vitality reduction from rodatazone: http://rodatazone.simgaming.net/mechanics/substats.php#def if (tsd) { @@ -1497,7 +1498,8 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_ } // Minstrel/Wanderer number check for chorus skills. -int battle_calc_chorusbonus(struct map_session_data *sd) { +static int battle_calc_chorusbonus(struct map_session_data *sd) +{ int members = 0; if (!sd || !sd->status.party_id) @@ -1513,7 +1515,8 @@ int battle_calc_chorusbonus(struct map_session_data *sd) { } // 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){ +static 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; struct map_session_data *sd, *tsd; @@ -2032,7 +2035,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += 100 + 100 * skill_lv + 100 * (skill_lv / 2); break; case RG_BACKSTAP: - if( sd && sd->status.weapon == W_BOW && battle_config.backstab_bow_penalty ) + if (sd != NULL && sd->weapontype == W_BOW && battle_config.backstab_bow_penalty) skillratio += (200 + 40 * skill_lv) / 2; else skillratio += 200 + 40 * skill_lv; @@ -2053,10 +2056,10 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block case CR_HOLYCROSS: { int ratio = 35 * skill_lv; - #ifdef RENEWAL - if(sd && sd->status.weapon == W_2HSPEAR) - ratio *= 2; - #endif +#ifdef RENEWAL + if (sd != NULL && sd->weapontype == W_2HSPEAR) + ratio *= 2; +#endif skillratio += ratio; break; } @@ -2714,7 +2717,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += 2*sc->data[SC_TRUESIGHT]->val1; if( sc->data[SC_LKCONCENTRATION] ) skillratio += sc->data[SC_LKCONCENTRATION]->val2; - if( sd && sd->status.weapon == W_KATAR && (i=pc->checkskill(sd,ASC_KATAR)) > 0 ) + if (sd != NULL && sd->weapontype == W_KATAR && (i=pc->checkskill(sd,ASC_KATAR)) > 0) skillratio += skillratio * (10 + 2 * i) / 100; #endif if( (!skill_id || skill_id == KN_AUTOCOUNTER) && sc->data[SC_CRUSHSTRIKE] ){ @@ -2735,10 +2738,12 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block return skillratio; } -void battle_calc_skillratio_magic_unknown(int *attack_type, struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, int *skillratio, int *flag) { +static void battle_calc_skillratio_magic_unknown(int *attack_type, struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, int *skillratio, int *flag) +{ } -void battle_calc_skillratio_weapon_unknown(int *attack_type, struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, int *skillratio, int *flag) { +static void battle_calc_skillratio_weapon_unknown(int *attack_type, struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, int *skillratio, int *flag) +{ } /*========================================== @@ -2746,7 +2751,8 @@ void battle_calc_skillratio_weapon_unknown(int *attack_type, struct block_list * * ATK may be MISS, BLOCKED FAIL, reduce, increase, end status... * After this we apply bg/gvg reduction *------------------------------------------*/ -int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int64 damage,uint16 skill_id,uint16 skill_lv) { +static int64 battle_calc_damage(struct block_list *src, struct block_list *bl, struct Damage *d, int64 damage, uint16 skill_id, uint16 skill_lv) +{ struct map_session_data *s_sd, *t_sd; struct status_change *s_sc, *sc; struct status_change_entry *sce; @@ -2870,7 +2876,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam if( sc->data[SC__MAELSTROM] && (flag&BF_MAGIC) && skill_id && (skill->get_inf(skill_id)&INF_GROUND_SKILL) ) { // {(Maelstrom Skill LevelxAbsorbed Skill Level)+(Caster's Job/5)}/2 int sp = (sc->data[SC__MAELSTROM]->val1 * skill_lv + (t_sd ? t_sd->status.job_level / 5 : 0)) / 2; - status->heal(bl, 0, sp, 3); + status->heal(bl, 0, sp, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT); d->dmg_lv = ATK_BLOCK; return 0; } @@ -3023,7 +3029,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam status_change_end(bl,SC_DEEP_SLEEP,INVALID_TIMER); } if( s_sd && t_sd && sc->data[SC_COLD] && flag&BF_WEAPON ){ - switch(s_sd->status.weapon){ + switch (s_sd->weapontype) { case W_MACE: case W_2HMACE: case W_1HAXE: @@ -3165,7 +3171,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam if( (sce = sc->data[SC_STONEHARDSKIN]) && flag&(BF_SHORT|BF_WEAPON) && damage > 0 ) { sce->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX); if( src->type == BL_PC ) { - if (s_sd && s_sd->status.weapon != W_BOW) + if (s_sd != NULL && s_sd->weapontype != W_BOW) skill->break_equip(src, EQP_WEAPON, 3000, BCT_SELF); } else skill->break_equip(src, EQP_WEAPON, 3000, BCT_SELF); @@ -3241,7 +3247,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam //(since battle_drain is strictly for players currently) if ((sce=sc->data[SC_HAMI_BLOODLUST]) && flag&BF_WEAPON && damage > 0 && rnd()%100 < sce->val3) - status->heal(src, damage*sce->val4/100, 0, 3); + status->heal(src, damage*sce->val4/100, 0, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT); if( (sce = sc->data[SC_FORCEOFVANGUARD]) && flag&BF_WEAPON && rnd()%100 < sce->val2 && sc->fv_counter <= sce->val3 ) @@ -3356,7 +3362,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam return damage; } -int64 battle_calc_pc_damage(struct block_list *src, struct block_list *bl, struct Damage *d, int64 damage, uint16 skill_id, uint16 skill_lv) +static int64 battle_calc_pc_damage(struct block_list *src, struct block_list *bl, struct Damage *d, int64 damage, uint16 skill_id, uint16 skill_lv) { int flag = d->flag; @@ -3391,7 +3397,8 @@ int64 battle_calc_pc_damage(struct block_list *src, struct block_list *bl, struc * 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) { +static 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) return 0; @@ -3411,7 +3418,8 @@ 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) { +static 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); @@ -3472,7 +3480,8 @@ int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 /*========================================== * HP/SP drain calculation *------------------------------------------*/ -int battle_calc_drain(int64 damage, int rate, int per) { +static int battle_calc_drain(int64 damage, int rate, int per) +{ int64 diff = 0; if (per && rnd()%1000 < rate) { @@ -3490,7 +3499,7 @@ int battle_calc_drain(int64 damage, int rate, int per) { /*========================================== * Consumes ammo for the given skill. *------------------------------------------*/ -void battle_consume_ammo(struct map_session_data *sd, int skill_id, int lv) +static void battle_consume_ammo(struct map_session_data *sd, int skill_id, int lv) { int qty=1; @@ -3510,7 +3519,8 @@ void battle_consume_ammo(struct map_session_data *sd, int skill_id, int lv) } //Skill Range Criteria -int battle_range_type(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv) { +static int battle_range_type(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv) +{ nullpo_retr(BF_SHORT, src); nullpo_retr(BF_SHORT, target); @@ -3534,7 +3544,9 @@ int battle_range_type(struct block_list *src, struct block_list *target, uint16 return BF_SHORT; return BF_LONG; } -int battle_adjust_skill_damage(int m, unsigned short skill_id) { + +static int battle_adjust_skill_damage(int m, unsigned short skill_id) +{ if( map->list[m].skill_count ) { int i; ARR_FIND(0, map->list[m].skill_count, i, map->list[m].skills[i]->skill_id == skill_id ); @@ -3547,7 +3559,8 @@ int battle_adjust_skill_damage(int m, unsigned short skill_id) { return 0; } -int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id) { +static int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id) +{ int i; nullpo_ret(sd); if (!sd->skillblown[0].id) @@ -3559,13 +3572,15 @@ int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id) { } return 0; } + //For quick div adjustment. #define damage_div_fix(dmg, div) do { if ((div) > 1) (dmg)*=(div); else if ((div) < 0) (div)*=-1; } while(0) /*========================================== * 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) { +static 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; struct map_session_data *sd = NULL; @@ -3902,7 +3917,8 @@ 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) { +static struct Damage battle_calc_misc_attack(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int mflag) +{ int temp; short i, nk; short s_ele; @@ -4212,16 +4228,16 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * hitrate = 80; //Default hitrate #endif - if(battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) { - unsigned char attacker_count; //256 max targets should be a sane max - attacker_count = unit->counttargeted(target); - if(attacker_count >= battle_config.agi_penalty_count) - { + if (battle_config.agi_penalty_type != 0 && (battle_config.agi_penalty_target & target->type) != 0) { + int attacker_count = unit->counttargeted(target); + if (attacker_count >= battle_config.agi_penalty_count) { + int penalty = (attacker_count - (battle_config.agi_penalty_count - 1)) * battle_config.agi_penalty_num; if (battle_config.agi_penalty_type == 1) - flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100; + flee = flee * (100 - penalty) / 100; else // assume type 2: absolute reduction - flee -= (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num; - if(flee < 1) flee = 1; + flee -= penalty; + if (flee < 1) + flee = 1; } } @@ -4327,18 +4343,21 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * } break; } + + battle->reflect_trap(target, src, &md, skill_id); return md; } -void battle_calc_misc_attack_unknown(struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, int *mflag, struct Damage *md) { +static void battle_calc_misc_attack_unknown(struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, int *mflag, struct Damage *md) +{ } /*========================================== * 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) +static struct Damage battle_calc_weapon_attack(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int wflag) { short temp=0; short s_ele, s_ele_; @@ -4575,8 +4594,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if(!skill_id) { //Skills ALWAYS use ONLY your right-hand weapon (tested on Aegis 10.2) - if (sd && sd->weapontype1 == 0 && sd->weapontype2 > 0) - { + if (sd && sd->weapontype1 == W_FIST && sd->weapontype2 != W_FIST) { flag.rh=0; flag.lh=1; } @@ -4649,7 +4667,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list short cri = sstatus->cri; if (sd != NULL) { // if show_katar_crit_bonus is enabled, it already done the calculation in status.c - if (!battle_config.show_katar_crit_bonus && sd->status.weapon == W_KATAR) { + if (!battle_config.show_katar_crit_bonus && sd->weapontype == W_KATAR) { cri <<= 1; } @@ -4737,15 +4755,16 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list short hitrate = 80; //Default hitrate #endif - if(battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) { - unsigned char attacker_count; //256 max targets should be a sane max - attacker_count = unit->counttargeted(target); - if(attacker_count >= battle_config.agi_penalty_count) { + if (battle_config.agi_penalty_type != 0 && (battle_config.agi_penalty_target & target->type) != 0) { + int attacker_count = unit->counttargeted(target); + if (attacker_count >= battle_config.agi_penalty_count) { + int penalty = (attacker_count - (battle_config.agi_penalty_count - 1)) * battle_config.agi_penalty_num; if (battle_config.agi_penalty_type == 1) - flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100; - else //asume type 2: absolute reduction - flee -= (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num; - if(flee < 1) flee = 1; + flee = flee * (100 - penalty) / 100; + else // asume type 2: absolute reduction + flee -= penalty; + if (flee < 1) + flee = 1; } } @@ -4822,8 +4841,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if ((temp = pc->checkskill(sd,BS_WEAPONRESEARCH)) > 0) hitrate += hitrate * ( 2 * temp ) / 100; - if( (sd->status.weapon == W_1HSWORD || sd->status.weapon == W_DAGGER) && - (temp = pc->checkskill(sd, GN_TRAINING_SWORD))>0 ) + if ((sd->weapontype == W_1HSWORD || sd->weapontype == W_DAGGER) && (temp = pc->checkskill(sd, GN_TRAINING_SWORD)) > 0) hitrate += 3 * temp; } @@ -4957,7 +4975,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list (!skill_id && sc && sc->data[SC_HLIF_CHANGE]?4:0)| (sc && sc->data[SC_WEAPONPERFECT]?8:0); if (flag.arrow && sd) - switch(sd->status.weapon) { + switch (sd->weapontype) { case W_BOW: case W_REVOLVER: case W_GATLING: @@ -5583,7 +5601,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if(wd.damage < 1) wd.damage = 1; if(wd.damage2 < 1) wd.damage2 = 1; #endif - } else if(sd->status.weapon == W_KATAR && !skill_id) { //Katars (offhand damage only applies to normal attacks, tested on Aegis 10.2) + } else if (sd->weapontype == W_KATAR && skill_id == 0) { + // Katars (offhand damage only applies to normal attacks, tested on Aegis 10.2) temp = pc->checkskill(sd,TF_DOUBLE); wd.damage2 = wd.damage * (1 + (temp * 2))/100; @@ -5702,7 +5721,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list } //Reject Sword bugreport:4493 by Daegaladh if (wd.damage != 0 && tsc != NULL && tsc->data[SC_SWORDREJECT] != NULL - && (sd == NULL || sd->weapontype1 == W_DAGGER || sd->weapontype1 == W_1HSWORD || sd->status.weapon == W_2HSWORD) + && (sd == NULL || sd->weapontype1 == W_DAGGER || sd->weapontype1 == W_1HSWORD || sd->weapontype == W_2HSWORD) && rnd()%100 < tsc->data[SC_SWORDREJECT]->val2 ) { ATK_RATER(50); @@ -5725,7 +5744,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list /*========================================== * Battle main entry, from skill->attack *------------------------------------------*/ -struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,uint16 skill_id,uint16 skill_lv,int count) +static struct Damage battle_calc_attack(int attack_type, struct block_list *bl, struct block_list *target, uint16 skill_id, uint16 skill_lv, int count) { struct Damage d; struct map_session_data *sd=BL_CAST(BL_PC,bl); @@ -5787,7 +5806,8 @@ struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct bl } //Performs reflect damage (magic (maya) is performed over skill.c). -void battle_reflect_damage(struct block_list *target, struct block_list *src, struct Damage *wd,uint16 skill_id) { +static void battle_reflect_damage(struct block_list *target, struct block_list *src, struct Damage *wd, uint16 skill_id) +{ int64 damage, rdamage = 0, trdamage = 0; struct map_session_data *sd, *tsd; struct status_change *sc; @@ -5995,7 +6015,38 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st #undef NORMALIZE_RDAMAGE } -void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int boss) +/** + * Reflects damage from certain traps, if battle_config.trap_reflect is true. + * @param target : Player who triggered the trap + * @param src : Player who set the trap + * @param md : Trap damage structure + * @param skill_id : Trap skill ID + */ +static void battle_reflect_trap(struct block_list *target, struct block_list *src, struct Damage *md, uint16 skill_id) +{ + if (battle_config.trap_reflect == true) { + if (src != target) { // Don't reflect your own damage + switch (skill_id) { + case HT_CLAYMORETRAP: + case HT_LANDMINE: + case HT_FREEZINGTRAP: + case HT_BLASTMINE: + // Needs official info + //case RA_CLUSTERBOMB: + //case RA_FIRINGTRAP: + //case RA_ICEBOUNDTRAP: + //case GN_THORNS_TRAP: + //case KO_MAKIBISHI: + case MA_LANDMINE: + case MA_FREEZINGTRAP: + battle->reflect_damage(target, src, md, skill_id); + break; + } + } + } +} + +static void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int boss) { struct weapon_data *wd; int type, thp = 0, tsp = 0, rhp = 0, rsp = 0, hp, sp, i; @@ -6048,13 +6099,15 @@ void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rda if (!thp && !tsp) return; - status->heal(&sd->bl, thp, tsp, battle_config.show_hp_sp_drain ? 3 : 1); + status->heal(&sd->bl, thp, tsp, STATUS_HEAL_FORCED | (battle_config.show_hp_sp_drain ? STATUS_HEAL_SHOWEFFECT : STATUS_HEAL_DEFAULT)); if (rhp || rsp) status_zap(tbl, rhp, rsp); } + // Deals the same damage to targets in area. [pakpil] -int battle_damage_area(struct block_list *bl, va_list ap) { +static int battle_damage_area(struct block_list *bl, va_list ap) +{ int64 tick; int amotion, dmotion, damage; struct block_list *src; @@ -6088,21 +6141,21 @@ int battle_damage_area(struct block_list *bl, va_list ap) { return 0; } -bool battle_check_arrows(struct map_session_data *sd) +static bool battle_check_arrows(struct map_session_data *sd) { int index = sd->equip_index[EQI_AMMO]; if (index < 0) { if (sd->weapontype1 > W_KATAR && sd->weapontype1 < W_HUUMA) - clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0); + clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0, 0); else clif->arrow_fail(sd, 0); return false; } //Ammo check by Ishizu-chan if (sd->inventory_data[index]) { - switch (sd->status.weapon) { + switch (sd->weapontype) { case W_BOW: - if (sd->inventory_data[index]->look != A_ARROW) { + if (sd->inventory_data[index]->subtype != A_ARROW) { clif->arrow_fail(sd, 0); return false; } @@ -6111,14 +6164,14 @@ bool battle_check_arrows(struct map_session_data *sd) case W_RIFLE: case W_GATLING: case W_SHOTGUN: - if (sd->inventory_data[index]->look != A_BULLET) { - clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0); + if (sd->inventory_data[index]->subtype != A_BULLET) { + clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0, 0); return false; } break; case W_GRENADE: - if (sd->inventory_data[index]->look != A_GRENADE) { - clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0); + if (sd->inventory_data[index]->subtype != A_GRENADE) { + clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0, 0); return false; } break; @@ -6131,7 +6184,8 @@ bool battle_check_arrows(struct map_session_data *sd) * 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) { +static 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; struct status_change *sc, *tsc; @@ -6161,7 +6215,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t if (sd) { - sd->state.arrow_atk = (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)); + sd->state.arrow_atk = (sd->weapontype == W_BOW || (sd->weapontype >= W_REVOLVER && sd->weapontype <= W_GRENADE)); if (sd->state.arrow_atk) { if (battle->check_arrows(sd) == false) @@ -6187,7 +6241,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t return ATK_BLOCK; } } - if( tsc && tsc->data[SC_BLADESTOP_WAIT] && !is_boss(src) && (src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->status.weapon == W_FIST ? 1 : 2)) ) + if( tsc && tsc->data[SC_BLADESTOP_WAIT] && !is_boss(src) && (src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->weapontype == W_FIST ? 1 : 2)) ) { uint16 skill_lv = tsc->data[SC_BLADESTOP_WAIT]->val1; int duration = skill->get_time2(MO_BLADESTOP,skill_lv); @@ -6385,7 +6439,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t } if( type != CAST_GROUND ) { - clif->skill_fail(sd,r_skill,USESKILL_FAIL_LEVEL,0); + clif->skill_fail(sd, r_skill, USESKILL_FAIL_LEVEL, 0, 0); map->freeblock_unlock(); return wd.dmg_lv; } @@ -6441,7 +6495,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t #undef GET_NORMAL_ATTACK #undef GET_NORMAL_ATTACK2 -bool battle_check_undead(int race,int element) +static bool battle_check_undead(int race, int element) { if(battle_config.undead_detect_type == 0) { if(element == ELE_UNDEAD) @@ -6459,7 +6513,7 @@ bool battle_check_undead(int race,int element) } //Returns the upmost level master starting with the given object -struct block_list *battle_get_master(struct block_list *src) +static struct block_list *battle_get_master(struct block_list *src) { struct block_list *prev = NULL; //Used for infinite loop check (master of yourself?) nullpo_retr(NULL, src); @@ -6523,7 +6577,7 @@ struct block_list *battle_get_master(struct block_list *src) * -1: flag fails * 0: Invalid target (non-targetable ever) *------------------------------------------*/ -int battle_check_target( struct block_list *src, struct block_list *target,int flag) +static int battle_check_target(struct block_list *src, struct block_list *target, int flag) { int16 m; //map int state = 0; //Initial state none @@ -6679,7 +6733,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if (t_bl == s_bl) break; - if( sd->state.monster_ignore && flag&BCT_ENEMY ) + if (sd->block_action.immune && flag&BCT_ENEMY) return 0; // Global immunity only to Attacks if (sd->status.karma && s_bl->type == BL_PC && BL_UCCAST(BL_PC, s_bl)->status.karma) state |= BCT_ENEMY; // Characters with bad karma may fight amongst them @@ -6804,37 +6858,55 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f return (flag&state)?1:-1; } - if( map_flag_vs(m) ) { + if (map_flag_vs(m)) { //Check rivalry settings. - int sbg_id = 0, tbg_id = 0; - if( map->list[m].flag.battleground ) { + int sbg_id = 0, tbg_id = 0, s_clan = 0, t_clan = 0; + if (map->list[m].flag.battleground) { sbg_id = bg->team_get_id(s_bl); tbg_id = bg->team_get_id(t_bl); + } else if (map->list[m].flag.cvc) { + s_clan = clan->get_id(s_bl); + t_clan = clan->get_id(t_bl); } - if( flag&(BCT_PARTY|BCT_ENEMY) ) { + if (flag & (BCT_PARTY | BCT_ENEMY)) { int s_party = status->get_party_id(s_bl); int s_guild = status->get_guild_id(s_bl); + int t_guild = status->get_guild_id(t_bl); - if( s_party && s_party == status->get_party_id(t_bl) - && !(map->list[m].flag.pvp && map->list[m].flag.pvp_noparty) - && !(map_flag_gvg(m) && map->list[m].flag.gvg_noparty && !( s_guild && s_guild == status->get_guild_id(t_bl) )) - && (!map->list[m].flag.battleground || sbg_id == tbg_id) ) - state |= BCT_PARTY; - else + if (s_party != 0 && s_party == status->get_party_id(t_bl)) { + if (map_flag_gvg(m) && map->list[m].flag.gvg_noparty) { + if (s_guild != 0 && t_guild != 0 && (s_guild == t_guild || guild->isallied(s_guild, t_guild))) + state |= BCT_PARTY; + else + state |= flag & BCT_ENEMY ? BCT_ENEMY : BCT_PARTY; + } else if (!(map->list[m].flag.pvp && map->list[m].flag.pvp_noparty) + && (!map->list[m].flag.battleground || sbg_id == tbg_id)) { + state |= BCT_PARTY; + } else if (!map->list[m].flag.cvc || s_clan == t_clan) { + state |= BCT_PARTY; + } else { + state |= BCT_ENEMY; + } + } else { state |= BCT_ENEMY; + } } - if( flag&(BCT_GUILD|BCT_ENEMY) ) { + if (flag & (BCT_GUILD | BCT_ENEMY)) { int s_guild = status->get_guild_id(s_bl); int t_guild = status->get_guild_id(t_bl); - if( !(map->list[m].flag.pvp && map->list[m].flag.pvp_noguild) + if (!(map->list[m].flag.pvp && map->list[m].flag.pvp_noguild) && s_guild && t_guild - && (s_guild == t_guild || (!(flag&BCT_SAMEGUILD) && guild->isallied(s_guild, t_guild))) - && (!map->list[m].flag.battleground || sbg_id == tbg_id) ) + && (s_guild == t_guild || (!(flag & BCT_SAMEGUILD) && guild->isallied(s_guild, t_guild))) + && (!map->list[m].flag.battleground || sbg_id == tbg_id) + && (!map->list[m].flag.cvc || s_clan == t_clan) + ) { state |= BCT_GUILD; - else + } else { state |= BCT_ENEMY; + } } - if( state&BCT_ENEMY && map->list[m].flag.battleground && sbg_id && sbg_id == tbg_id ) + + if (state & BCT_ENEMY && ((map->list[m].flag.battleground && sbg_id && sbg_id == tbg_id) || (map->list[m].flag.cvc && s_clan && s_clan == t_clan))) state &= ~BCT_ENEMY; if (state&BCT_ENEMY && battle_config.pk_mode && !map_flag_gvg(m) && s_bl->type == BL_PC && t_bl->type == BL_PC) { @@ -6874,11 +6946,12 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f return (flag&state)?1:-1; } + /*========================================== * Check if can attack from this range * Basic check then calling path->search for obstacle etc.. *------------------------------------------*/ -bool battle_check_range(struct block_list *src, struct block_list *bl, int range) +static bool battle_check_range(struct block_list *src, struct block_list *bl, int range) { int d; nullpo_retr(false, src); @@ -6966,7 +7039,7 @@ static const struct battle_data { { "chase_range_rate", &battle_config.chase_range_rate, 100, 0, INT_MAX, }, { "gtb_sc_immunity", &battle_config.gtb_sc_immunity, 50, 0, INT_MAX, }, { "guild_max_castles", &battle_config.guild_max_castles, 0, 0, INT_MAX, }, - { "guild_skill_relog_delay", &battle_config.guild_skill_relog_delay, 0, 0, 1, }, + { "guild_skill_relog_delay", &battle_config.guild_skill_relog_delay, 0, 0, 2, }, { "emergency_call", &battle_config.emergency_call, 11, 0, 31, }, { "atcommand_spawn_quantity_limit", &battle_config.atc_spawn_quantity_limit, 100, 0, INT_MAX, }, { "atcommand_slave_clone_limit", &battle_config.atc_slave_clone_limit, 25, 0, INT_MAX, }, @@ -7025,14 +7098,15 @@ static const struct battle_data { { "max_heal_lv", &battle_config.max_heal_lv, 11, 1, INT_MAX, }, { "max_heal", &battle_config.max_heal, 9999, 0, INT_MAX, }, { "combo_delay_rate", &battle_config.combo_delay_rate, 100, 0, INT_MAX, }, - { "item_check", &battle_config.item_check, 0, 0, 1, }, + { "item_check", &battle_config.item_check, 0, 0, 0xF, }, { "item_use_interval", &battle_config.item_use_interval, 100, 0, INT_MAX, }, - { "cashfood_use_interval", &battle_config.cashfood_use_interval, 60000, 0, INT_MAX, }, { "wedding_modifydisplay", &battle_config.wedding_modifydisplay, 0, 0, 1, }, { "wedding_ignorepalette", &battle_config.wedding_ignorepalette, 0, 0, 1, }, { "xmas_ignorepalette", &battle_config.xmas_ignorepalette, 0, 0, 1, }, { "summer_ignorepalette", &battle_config.summer_ignorepalette, 0, 0, 1, }, { "hanbok_ignorepalette", &battle_config.hanbok_ignorepalette, 0, 0, 1, }, + { "oktoberfest_ignorepalette", &battle_config.oktoberfest_ignorepalette, 0, 0, 1, }, + { "summer2_ignorepalette", &battle_config.summer2_ignorepalette, 0, 0, 1, }, { "natural_healhp_interval", &battle_config.natural_healhp_interval, 6000, NATURAL_HEAL_INTERVAL, INT_MAX, }, { "natural_healsp_interval", &battle_config.natural_healsp_interval, 8000, NATURAL_HEAL_INTERVAL, INT_MAX, }, { "natural_heal_skill_interval", &battle_config.natural_heal_skill_interval, 10000, NATURAL_HEAL_INTERVAL, INT_MAX, }, @@ -7087,6 +7161,7 @@ static const struct battle_data { { "vending_over_max", &battle_config.vending_over_max, 1, 0, 1, }, { "show_steal_in_same_party", &battle_config.show_steal_in_same_party, 0, 0, 1, }, { "party_hp_mode", &battle_config.party_hp_mode, 0, 0, 1, }, + { "party_change_leader_same_map", &battle_config.party_change_leader_same_map, 0, 0, 1, }, { "show_party_share_picker", &battle_config.party_show_share_picker, 1, 0, 1, }, { "show_picker_item_type", &battle_config.show_picker_item_type, 112, 0, INT_MAX, }, { "party_update_interval", &battle_config.party_update_interval, 1000, 100, INT_MAX, }, @@ -7168,6 +7243,7 @@ static const struct battle_data { { "vcast_stat_scale", &battle_config.vcast_stat_scale, 530, 1, INT_MAX, }, { "area_size", &battle_config.area_size, 14, 0, INT_MAX, }, { "chat_area_size", &battle_config.chat_area_size, 9, 0, INT_MAX, }, + { "dead_area_size", &battle_config.dead_area_size, 32, 0, INT_MAX, }, { "zeny_from_mobs", &battle_config.zeny_from_mobs, 0, 0, 1, }, { "mobs_level_up", &battle_config.mobs_level_up, 0, 0, 1, }, { "mobs_level_up_exp_rate", &battle_config.mobs_level_up_exp_rate, 1, 1, INT_MAX, }, @@ -7201,7 +7277,6 @@ static const struct battle_data { { "mob_npc_event_type", &battle_config.mob_npc_event_type, 1, 0, 1, }, { "character_size", &battle_config.character_size, 1|2, 0, 1|2, }, { "retaliate_to_master", &battle_config.retaliate_to_master, 1, 0, 1, }, - { "rare_drop_announce", &battle_config.rare_drop_announce, 0, 0, 10000, }, { "duel_allow_pvp", &battle_config.duel_allow_pvp, 0, 0, 1, }, { "duel_allow_gvg", &battle_config.duel_allow_gvg, 0, 0, 1, }, { "duel_allow_teleport", &battle_config.duel_allow_teleport, 0, 0, 1, }, @@ -7275,6 +7350,7 @@ static const struct battle_data { { "atcommand_max_stat_bypass", &battle_config.atcommand_max_stat_bypass, 0, 0, 100, }, { "skill_amotion_leniency", &battle_config.skill_amotion_leniency, 90, 0, 300 }, { "mvp_tomb_enabled", &battle_config.mvp_tomb_enabled, 1, 0, 1 }, + { "mvp_tomb_spawn_delay", &battle_config.mvp_tomb_spawn_delay, 10000, 0, INT_MAX }, { "features/atcommand_suggestions", &battle_config.atcommand_suggestions_enabled, 0, 0, 1 }, { "min_npc_vendchat_distance", &battle_config.min_npc_vendchat_distance, 3, 0, 100 }, { "vendchat_near_hiddennpc", &battle_config.vendchat_near_hiddennpc, 0, 0, 1 }, @@ -7287,6 +7363,7 @@ static const struct battle_data { * Hercules **/ { "skill_trap_type", &battle_config.skill_trap_type, 0, 0, 1, }, + { "trap_reflect", &battle_config.trap_reflect, 1, 0, 1, }, { "item_restricted_consumption_type", &battle_config.item_restricted_consumption_type,1, 0, 1, }, { "unequip_restricted_equipment", &battle_config.unequip_restricted_equipment, 0, 0, 3, }, { "max_walk_path", &battle_config.max_walk_path, 17, 1, MAX_WALKPATH, }, @@ -7319,173 +7396,26 @@ static const struct battle_data { { "max_body_style", &battle_config.max_body_style, 4, 0, SHRT_MAX, }, { "save_body_style", &battle_config.save_body_style, 0, 0, 1, }, { "player_warp_keep_direction", &battle_config.player_warp_keep_direction, 0, 0, 1, }, - { "atcommand_levelup_events", &battle_config.atcommand_levelup_events, 0, 0, 1, }, + { "atcommand_levelup_events", &battle_config.atcommand_levelup_events, 0, 0, 1, }, + { "bow_unequip_arrow", &battle_config.bow_unequip_arrow, 1, 0, 1, }, { "max_summoner_parameter", &battle_config.max_summoner_parameter, 120, 10, 10000, }, + { "mvp_exp_reward_message", &battle_config.mvp_exp_reward_message, 0, 0, 1, }, + { "monster_eye_range_bonus", &battle_config.mob_eye_range_bonus, 0, 0, 10, }, + { "prevent_logout_trigger", &battle_config.prevent_logout_trigger, 0xE, 0, 0xF, }, + { "boarding_halter_speed", &battle_config.boarding_halter_speed, 25, 0, 100, }, + { "features/rodex", &battle_config.feature_rodex, 1, 0, 1, }, + { "features/rodex_use_accountmail", &battle_config.feature_rodex_use_accountmail, 0, 0, 1, }, + { "features/enable_homun_autofeed", &battle_config.feature_enable_homun_autofeed, 1, 0, 1, }, + { "features/enable_pet_autofeed", &battle_config.feature_enable_pet_autofeed, 1, 0, 1, }, + { "storage_use_item", &battle_config.storage_use_item, 0, 0, 1, }, + { "features/enable_attendance_system", &battle_config.feature_enable_attendance_system,1, 0, 1, }, + { "features/feature_attendance_endtime",&battle_config.feature_attendance_endtime, 1, 0, 99999999, }, + { "min_item_buy_price", &battle_config.min_item_buy_price, 1, 0, INT_MAX, }, + { "min_item_sell_price", &battle_config.min_item_sell_price, 0, 0, INT_MAX, }, + { "display_fake_hp_when_dead", &battle_config.display_fake_hp_when_dead, 1, 0, 1, }, }; -#ifndef STATS_OPT_OUT -/** - * Hercules anonymous statistic usage report -- packet is built here, and sent to char server to report. - **/ -void Hercules_report(char* date, char *time_c) { - int i, bd_size = ARRAYLENGTH(battle_data); - unsigned int config = 0; - char timestring[25]; - time_t curtime; - char* buf; - - enum config_table { - C_CIRCULAR_AREA = 0x0001, - C_CELLNOSTACK = 0x0002, - C_CONSOLE_INPUT = 0x0004, - C_SCRIPT_CALLFUNC_CHECK = 0x0008, - C_OFFICIAL_WALKPATH = 0x0010, - C_RENEWAL = 0x0020, - C_RENEWAL_CAST = 0x0040, - C_RENEWAL_DROP = 0x0080, - C_RENEWAL_EXP = 0x0100, - C_RENEWAL_LVDMG = 0x0200, - C_RENEWAL_EDP = 0x0400, - C_RENEWAL_ASPD = 0x0800, - C_SECURE_NPCTIMEOUT = 0x1000, - //C_SQL_DB_ITEM = 0x2000, - C_SQL_LOGS = 0x4000, - C_MEMWATCH = 0x8000, - C_DMALLOC = 0x10000, - C_GCOLLECT = 0x20000, - C_SEND_SHORTLIST = 0x40000, - //C_SQL_DB_MOB = 0x80000, - //C_SQL_DB_MOBSKILL = 0x100000, - C_PACKETVER_RE = 0x200000, - }; - - /* we get the current time */ - time(&curtime); - strftime(timestring, 24, "%Y-%m-%d %H:%M:%S", localtime(&curtime)); - -#ifdef CIRCULAR_AREA - config |= C_CIRCULAR_AREA; -#endif -#ifdef CELL_NOSTACK - config |= C_CELLNOSTACK; -#endif - -#ifdef CONSOLE_INPUT - config |= C_CONSOLE_INPUT; -#endif - -#ifdef SCRIPT_CALLFUNC_CHECK - config |= C_SCRIPT_CALLFUNC_CHECK; -#endif - -#ifdef OFFICIAL_WALKPATH - config |= C_OFFICIAL_WALKPATH; -#endif - -#ifdef RENEWAL - config |= C_RENEWAL; -#endif - -#ifdef RENEWAL_CAST - config |= C_RENEWAL_CAST; -#endif - -#ifdef RENEWAL_DROP - config |= C_RENEWAL_DROP; -#endif - -#ifdef RENEWAL_EXP - config |= C_RENEWAL_EXP; -#endif - -#ifdef RENEWAL_LVDMG - config |= C_RENEWAL_LVDMG; -#endif - -#ifdef RENEWAL_EDP - config |= C_RENEWAL_EDP; -#endif - -#ifdef RENEWAL_ASPD - config |= C_RENEWAL_ASPD; -#endif - -#ifdef SECURE_NPCTIMEOUT - config |= C_SECURE_NPCTIMEOUT; -#endif - -#ifdef PACKETVER_RE - config |= C_PACKETVER_RE; -#endif - - /* non-define part */ - if( logs->config.sql_logs ) - config |= C_SQL_LOGS; - -#ifdef MEMWATCH - config |= C_MEMWATCH; -#endif -#ifdef DMALLOC - config |= C_DMALLOC; -#endif -#ifdef GCOLLECT - config |= C_GCOLLECT; -#endif - -#ifdef SEND_SHORTLIST - config |= C_SEND_SHORTLIST; -#endif - -#define BFLAG_LENGTH 35 - - CREATE(buf, char, 262 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) + 1 ); - - /* build packet */ - - WBUFW(buf,0) = 0x3000; - WBUFW(buf,2) = 262 + ( bd_size * ( BFLAG_LENGTH + 4 ) ); - WBUFW(buf,4) = 0x9f; - - safestrncpy(WBUFP(buf,6), date, 12); - safestrncpy(WBUFP(buf,18), time_c, 9); - safestrncpy(WBUFP(buf,27), timestring, 24); - - safestrncpy(WBUFP(buf,51), sysinfo->platform(), 16); - safestrncpy(WBUFP(buf,67), sysinfo->osversion(), 50); - safestrncpy(WBUFP(buf,117), sysinfo->cpu(), 32); - WBUFL(buf,149) = sysinfo->cpucores(); - safestrncpy(WBUFP(buf,153), sysinfo->arch(), 8); - WBUFB(buf,161) = sysinfo->vcstypeid(); - WBUFB(buf,162) = sysinfo->is64bit(); - safestrncpy(WBUFP(buf,163), sysinfo->vcsrevision_src(), 41); - safestrncpy(WBUFP(buf,204), sysinfo->vcsrevision_scripts(), 41); - WBUFB(buf,245) = (sysinfo->is_superuser()? 1 : 0); - WBUFL(buf,246) = map->getusers(); - - WBUFL(buf,250) = config; - WBUFL(buf,254) = PACKETVER; - - WBUFL(buf,258) = bd_size; - for( i = 0; i < bd_size; i++ ) { - safestrncpy(WBUFP(buf,262 + ( i * ( BFLAG_LENGTH + 4 ) ) ), battle_data[i].str, BFLAG_LENGTH); - WBUFL(buf,262 + BFLAG_LENGTH + ( i * ( BFLAG_LENGTH + 4 ) ) ) = *battle_data[i].val; - } - - chrif->send_report(buf, 262 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) ); - - aFree(buf); - -#undef BFLAG_LENGTH -} -static int Hercules_report_timer(int tid, int64 tick, int id, intptr_t data) { - if( chrif->isconnected() ) {/* char server relays it, so it must be online. */ - Hercules_report(__DATE__,__TIME__); - } - return 0; -} -#endif - -bool battle_set_value_sub(int index, int value) +static bool battle_set_value_sub(int index, int value) { Assert_retr(false, index >= 0); if (value < battle_data[index].min || value > battle_data[index].max) { @@ -7497,7 +7427,7 @@ bool battle_set_value_sub(int index, int value) return true; } -bool battle_set_value(const char *param, const char *value) +static bool battle_set_value(const char *param, const char *value) { int val; int i; @@ -7517,7 +7447,7 @@ bool battle_set_value(const char *param, const char *value) return battle->config_set_value_sub(i, val); } -bool battle_get_value(const char *w1, int *value) +static bool battle_get_value(const char *w1, int *value) { int i; @@ -7536,13 +7466,15 @@ bool battle_get_value(const char *w1, int *value) return false; } -void battle_set_defaults(void) { +static void battle_set_defaults(void) +{ int i; for (i = 0; i < ARRAYLENGTH(battle_data); i++) *battle_data[i].val = battle_data[i].defval; } -void battle_adjust_conf(void) { +static void battle_adjust_conf(void) +{ battle_config.monster_max_aspd = 2000 - battle_config.monster_max_aspd*10; battle_config.max_aspd = 2000 - battle_config.max_aspd*10; battle_config.max_third_aspd = 2000 - battle_config.max_third_aspd*10; @@ -7599,6 +7531,13 @@ void battle_adjust_conf(void) { } #endif +#if PACKETVER < 20131223 + if (battle_config.mvp_exp_reward_message) { + ShowWarning("conf/map/battle/client.conf MVP EXP reward message is enabled but it requires PACKETVER 2013-12-23 or newer, disabling...\n"); + battle_config.mvp_exp_reward_message = 0; + } +#endif + #ifndef CELL_NOSTACK if (battle_config.custom_cell_stack_limit != 1) ShowWarning("Battle setting 'custom_cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n"); @@ -7612,7 +7551,7 @@ void battle_adjust_conf(void) { * @param imported Whether the current config is imported from another file. * @retval false in case of error. */ -bool battle_config_read(const char *filename, bool imported) +static bool battle_config_read(const char *filename, bool imported) { struct config_t config; const struct config_setting_t *setting = NULL; @@ -7679,26 +7618,23 @@ bool battle_config_read(const char *filename, bool imported) return retval; } -void do_init_battle(bool minimal) { +static void do_init_battle(bool minimal) +{ if (minimal) return; battle->delay_damage_ers = ers_new(sizeof(struct delay_damage),"battle.c::delay_damage_ers",ERS_OPT_CLEAR); timer->add_func_list(battle->delay_damage_sub, "battle_delay_damage_sub"); - -#ifndef STATS_OPT_OUT - timer->add_func_list(Hercules_report_timer, "Hercules_report_timer"); - timer->add_interval(timer->gettick()+30000, Hercules_report_timer, 0, 0, 60000 * 30); -#endif - } -void do_final_battle(void) { +static void do_final_battle(void) +{ ers_destroy(battle->delay_damage_ers); } /* initialize the interface */ -void battle_defaults(void) { +void battle_defaults(void) +{ battle = &battle_s; battle->bc = &battle_config; @@ -7720,6 +7656,7 @@ void battle_defaults(void) { battle->delay_damage = battle_delay_damage; battle->drain = battle_drain; battle->reflect_damage = battle_reflect_damage; + battle->reflect_trap = battle_reflect_trap; battle->attr_ratio = battle_attr_ratio; battle->attr_fix = battle_attr_fix; battle->calc_cardfix = battle_calc_cardfix; |