summaryrefslogtreecommitdiff
path: root/src/map/battle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/battle.c')
-rw-r--r--src/map/battle.c2751
1 files changed, 890 insertions, 1861 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 00ca5a9e0..077e5fc9b 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -12,6 +12,7 @@
#include "map.h"
#include "pc.h"
+#include "status.h"
#include "skill.h"
#include "mob.h"
#include "itemdb.h"
@@ -55,1259 +56,21 @@ int battle_counttargeted(struct block_list *bl,struct block_list *src,int target
return mob_counttargeted((struct mob_data *)bl,src,target_lv);
return 0;
}
-/*==========================================
- * 対象のClassを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_class(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data *)bl)->class;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->status.class;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return ((struct pet_data *)bl)->class;
- else
- return 0;
-}
-/*==========================================
- * 対象の方向を返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_dir(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data *)bl)->dir;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->dir;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return ((struct pet_data *)bl)->dir;
- else
- return 0;
-}
-/*==========================================
- * 対象のレベルを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_lv(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data *)bl)->level;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->status.base_level;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return ((struct pet_data *)bl)->msd->pet.level;
- else
- return 0;
-}
-/*==========================================
- * 対象の射程を返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_range(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].range;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->attackrange;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return mob_db[((struct pet_data *)bl)->class].range;
- else
- return 0;
-}
-/*==========================================
- * 対象のHPを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_hp(struct block_list *bl)
-{
- nullpo_retr(1, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data *)bl)->hp;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->status.hp;
- else
- return 1;
-}
-/*==========================================
- * 対象のMHPを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_max_hp(struct block_list *bl)
-{
- nullpo_retr(1, bl);
- if(bl->type==BL_PC && ((struct map_session_data *)bl))
- return ((struct map_session_data *)bl)->status.max_hp;
- else {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int max_hp=1;
- if(bl->type==BL_MOB && ((struct mob_data*)bl)) {
- max_hp = mob_db[((struct mob_data*)bl)->class].max_hp;
- if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris]
- max_hp+=(((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv)*battle_get_vit(bl);
- if(mob_db[((struct mob_data*)bl)->class].mexp > 0) {
- if(battle_config.mvp_hp_rate != 100)
- max_hp = (max_hp * battle_config.mvp_hp_rate)/100;
- }
- else {
- if(battle_config.monster_hp_rate != 100)
- max_hp = (max_hp * battle_config.monster_hp_rate)/100;
- }
- }
- else if(bl->type==BL_PET && ((struct pet_data*)bl)) {
- max_hp = mob_db[((struct pet_data*)bl)->class].max_hp;
- if(mob_db[((struct pet_data*)bl)->class].mexp > 0) {
- if(battle_config.mvp_hp_rate != 100)
- max_hp = (max_hp * battle_config.mvp_hp_rate)/100;
- }
- else {
- if(battle_config.monster_hp_rate != 100)
- max_hp = (max_hp * battle_config.monster_hp_rate)/100;
- }
- }
- if(sc_data) {
- if(sc_data[SC_APPLEIDUN].timer!=-1)
- max_hp += ((5+sc_data[SC_APPLEIDUN].val1*2+((sc_data[SC_APPLEIDUN].val2+1)>>1)
- +sc_data[SC_APPLEIDUN].val3/10) * max_hp)/100;
- }
- if(max_hp < 1) max_hp = 1;
- return max_hp;
- }
- return 1;
-}
-/*==========================================
- * 対象のStrを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_str(struct block_list *bl)
-{
- int str=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && ((struct mob_data *)bl)) {
- str = mob_db[((struct mob_data *)bl)->class].str;
- if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris]
- str+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && ((struct map_session_data *)bl))
- return ((struct map_session_data *)bl)->paramc[0];
- else if(bl->type==BL_PET && ((struct pet_data *)bl))
- str = mob_db[((struct pet_data *)bl)->class].str;
-
- if(sc_data) {
- if(sc_data[SC_LOUD].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1 && bl->type != BL_PC)
- str += 4;
- if( sc_data[SC_BLESSING].timer != -1 && bl->type != BL_PC){ // ブレッシング
- int race=battle_get_race(bl);
- if(battle_check_undead(race,battle_get_elem_type(bl)) || race==6 ) str >>= 1; // 悪 魔/不死
- else str += sc_data[SC_BLESSING].val1; // その他
- }
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // トゥルーサイト
- str += 5;
- }
- if(str < 0) str = 0;
- return str;
-}
-/*==========================================
- * 対象のAgiを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-
-int battle_get_agi(struct block_list *bl)
-{
- int agi=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl) {
- agi=mob_db[((struct mob_data *)bl)->class].agi;
- if(battle_config.mobs_level_up) // increase of mobs leveling up [Valaris]
- agi+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- agi=((struct map_session_data *)bl)->paramc[1];
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- agi=mob_db[((struct pet_data *)bl)->class].agi;
-
- if(sc_data) {
- if( sc_data[SC_INCREASEAGI].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1 &&
- bl->type != BL_PC) // 速度増加(PCはpc.cで)
- agi += 2+sc_data[SC_INCREASEAGI].val1;
-
- if(sc_data[SC_CONCENTRATE].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1 && bl->type != BL_PC)
- agi += agi*(2+sc_data[SC_CONCENTRATE].val1)/100;
-
- if(sc_data[SC_DECREASEAGI].timer!=-1) // 速度減少
- agi -= 2+sc_data[SC_DECREASEAGI].val1;
-
- if(sc_data[SC_QUAGMIRE].timer!=-1 ) { // クァグマイア
- //agi >>= 1;
- int agib = agi*(sc_data[SC_QUAGMIRE].val1*10)/100;
- agi -= agib > 50 ? 50 : agib;
- }
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // トゥルーサイト
- agi += 5;
- }
- if(agi < 0) agi = 0;
- return agi;
-}
-/*==========================================
- * 対象のVitを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_vit(struct block_list *bl)
-{
- int vit=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl) {
- vit=mob_db[((struct mob_data *)bl)->class].vit;
- if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
- vit+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- vit=((struct map_session_data *)bl)->paramc[2];
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- vit=mob_db[((struct pet_data *)bl)->class].vit;
- if(sc_data) {
- if(sc_data[SC_STRIPARMOR].timer != -1 && bl->type!=BL_PC)
- vit = vit*60/100;
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // トゥルーサイト
- vit += 5;
- }
-
- if(vit < 0) vit = 0;
- return vit;
-}
-/*==========================================
- * 対象のIntを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_int(struct block_list *bl)
-{
- int int_=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl){
- int_=mob_db[((struct mob_data *)bl)->class].int_;
- if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
- int_+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- int_=((struct map_session_data *)bl)->paramc[3];
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- int_=mob_db[((struct pet_data *)bl)->class].int_;
-
- if(sc_data) {
- if( sc_data[SC_BLESSING].timer != -1 && bl->type != BL_PC){ // ブレッシング
- int race=battle_get_race(bl);
- if(battle_check_undead(race,battle_get_elem_type(bl)) || race==6 ) int_ >>= 1; // 悪 魔/不死
- else int_ += sc_data[SC_BLESSING].val1; // その他
- }
- if( sc_data[SC_STRIPHELM].timer != -1 && bl->type != BL_PC)
- int_ = int_*60/100;
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // トゥルーサイト
- int_ += 5;
- }
- if(int_ < 0) int_ = 0;
- return int_;
-}
-/*==========================================
- * 対象のDexを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_dex(struct block_list *bl)
-{
- int dex=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl) {
- dex=mob_db[((struct mob_data *)bl)->class].dex;
- if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
- dex+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- dex=((struct map_session_data *)bl)->paramc[4];
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- dex=mob_db[((struct pet_data *)bl)->class].dex;
-
- if(sc_data) {
- if(sc_data[SC_CONCENTRATE].timer!=-1 && sc_data[SC_QUAGMIRE].timer == -1 && bl->type != BL_PC)
- dex += dex*(2+sc_data[SC_CONCENTRATE].val1)/100;
-
- if( sc_data[SC_BLESSING].timer != -1 && bl->type != BL_PC){ // ブレッシング
- int race=battle_get_race(bl);
- if(battle_check_undead(race,battle_get_elem_type(bl)) || race==6 ) dex >>= 1; // 悪 魔/不死
- else dex += sc_data[SC_BLESSING].val1; // その他
- }
-
- if(sc_data[SC_QUAGMIRE].timer!=-1 ) { // クァグマイア
- // dex >>= 1;
- int dexb = dex*(sc_data[SC_QUAGMIRE].val1*10)/100;
- dex -= dexb > 50 ? 50 : dexb;
- }
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // トゥルーサイト
- dex += 5;
- }
- if(dex < 0) dex = 0;
- return dex;
-}
-/*==========================================
- * 対象のLukを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_luk(struct block_list *bl)
-{
- int luk=0;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl) {
- luk=mob_db[((struct mob_data *)bl)->class].luk;
- if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
- luk+=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- luk=((struct map_session_data *)bl)->paramc[5];
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- luk=mob_db[((struct pet_data *)bl)->class].luk;
-
- if(sc_data) {
- if(sc_data[SC_GLORIA].timer!=-1 && bl->type != BL_PC) // グロリア(PCはpc.cで)
- luk += 30;
- if(sc_data[SC_CURSE].timer!=-1 ) // 呪い
- luk=0;
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // トゥルーサイト
- luk += 5;
- }
- if(luk < 0) luk = 0;
- return luk;
-}
-
-/*==========================================
- * 対象のFleeを返す(汎用)
- * 戻りは整数で1以上
- *------------------------------------------
- */
-int battle_get_flee(struct block_list *bl)
-{
- int flee=1;
- struct status_change *sc_data;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- flee=((struct map_session_data *)bl)->flee;
- else
- flee=battle_get_agi(bl) + battle_get_lv(bl);
-
- if(sc_data) {
- if(sc_data[SC_WHISTLE].timer!=-1 && bl->type != BL_PC)
- flee += flee*(sc_data[SC_WHISTLE].val1+sc_data[SC_WHISTLE].val2
- +(sc_data[SC_WHISTLE].val3>>16))/100;
- if(sc_data[SC_BLIND].timer!=-1 && bl->type != BL_PC)
- flee -= flee*25/100;
- if(sc_data[SC_WINDWALK].timer!=-1 && bl->type != BL_PC) // ウィンドウォーク
- flee += flee*(sc_data[SC_WINDWALK].val2)/100;
- if(sc_data[SC_SPIDERWEB].timer!=-1 && bl->type != BL_PC) //スパイダーウェブ
- flee -= flee*50/100;
- }
- if(flee < 1) flee = 1;
- return flee;
-}
-/*==========================================
- * 対象のHitを返す(汎用)
- * 戻りは整数で1以上
- *------------------------------------------
- */
-int battle_get_hit(struct block_list *bl)
-{
- int hit=1;
- struct status_change *sc_data;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- hit=((struct map_session_data *)bl)->hit;
- else
- hit=battle_get_dex(bl) + battle_get_lv(bl);
-
- if(sc_data) {
- if(sc_data[SC_HUMMING].timer!=-1 && bl->type != BL_PC) //
- hit += hit*(sc_data[SC_HUMMING].val1*2+sc_data[SC_HUMMING].val2
- +sc_data[SC_HUMMING].val3)/100;
- if(sc_data[SC_BLIND].timer!=-1 && bl->type != BL_PC) // 呪い
- hit -= hit*25/100;
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) // トゥルーサイト
- hit += 3*(sc_data[SC_TRUESIGHT].val1);
- if(sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC) //コンセントレーション
- hit += (hit*(10*(sc_data[SC_CONCENTRATION].val1)))/100;
- }
- if(hit < 1) hit = 1;
- return hit;
-}
-/*==========================================
- * 対象の完全回避を返す(汎用)
- * 戻りは整数で1以上
- *------------------------------------------
- */
-int battle_get_flee2(struct block_list *bl)
-{
- int flee2=1;
- struct status_change *sc_data;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl){
- flee2 = battle_get_luk(bl) + 10;
- flee2 += ((struct map_session_data *)bl)->flee2 - (((struct map_session_data *)bl)->paramc[5] + 10);
- }
- else
- flee2=battle_get_luk(bl)+1;
-
- if(sc_data) {
- if(sc_data[SC_WHISTLE].timer!=-1 && bl->type != BL_PC)
- flee2 += (sc_data[SC_WHISTLE].val1+sc_data[SC_WHISTLE].val2
- +(sc_data[SC_WHISTLE].val3&0xffff))*10;
- }
- if(flee2 < 1) flee2 = 1;
- return flee2;
-}
-/*==========================================
- * 対象のクリティカルを返す(汎用)
- * 戻りは整数で1以上
- *------------------------------------------
- */
-int battle_get_critical(struct block_list *bl)
-{
- int critical=1;
- struct status_change *sc_data;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl){
- critical = battle_get_luk(bl)*3 + 10;
- critical += ((struct map_session_data *)bl)->critical - ((((struct map_session_data *)bl)->paramc[5]*3) + 10);
- }
- else
- critical=battle_get_luk(bl)*3 + 1;
-
- if(sc_data) {
- if(sc_data[SC_FORTUNE].timer!=-1 && bl->type != BL_PC)
- critical += (10+sc_data[SC_FORTUNE].val1+sc_data[SC_FORTUNE].val2
- +sc_data[SC_FORTUNE].val3)*10;
- if(sc_data[SC_EXPLOSIONSPIRITS].timer!=-1 && bl->type != BL_PC)
- critical += sc_data[SC_EXPLOSIONSPIRITS].val2;
- if(sc_data[SC_TRUESIGHT].timer!=-1 && bl->type != BL_PC) //トゥルーサイト
- critical += critical*sc_data[SC_TRUESIGHT].val1/100;
- }
- if(critical < 1) critical = 1;
- return critical;
-}
-/*==========================================
- * base_atkの取得
- * 戻りは整数で1以上
- *------------------------------------------
- */
-int battle_get_baseatk(struct block_list *bl)
-{
- struct status_change *sc_data;
- int batk=1;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- batk = ((struct map_session_data *)bl)->base_atk; //設定されているbase_atk
- else { //それ以外なら
- int str,dstr;
- str = battle_get_str(bl); //STR
- dstr = str/10;
- batk = dstr*dstr + str; //base_atkを計算する
- }
- if(sc_data) { //状態異常あり
- if(sc_data[SC_PROVOKE].timer!=-1 && bl->type != BL_PC) //PCでプロボック(SM_PROVOKE)状態
- batk = batk*(100+2*sc_data[SC_PROVOKE].val1)/100; //base_atk増加
- if(sc_data[SC_CURSE].timer!=-1 ) //呪われていたら
- batk -= batk*25/100; //base_atkが25%減少
- if(sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC) //コンセントレーション
- batk += batk*(5*sc_data[SC_CONCENTRATION].val1)/100;
- if(sc_data[SC_EDP].timer != -1) // [Celest]
- batk += batk*(50+50*sc_data[SC_EDP].val1)/100;
- }
- if(batk < 1) batk = 1; //base_atkは最低でも1
- return batk;
-}
-/*==========================================
- * 対象のAtkを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_atk(struct block_list *bl)
-{
- struct status_change *sc_data;
- int atk=0;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- atk = ((struct map_session_data*)bl)->watk;
- else if(bl->type==BL_MOB && (struct mob_data *)bl)
- atk = mob_db[((struct mob_data*)bl)->class].atk1;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- atk = mob_db[((struct pet_data*)bl)->class].atk1;
-
- if(sc_data) {
- if(sc_data[SC_PROVOKE].timer!=-1 && bl->type != BL_PC)
- atk = atk*(100+2*sc_data[SC_PROVOKE].val1)/100;
- if(sc_data[SC_CURSE].timer!=-1 )
- atk -= atk*25/100;
- if(sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC) //コンセントレーション
- atk += atk*(5*sc_data[SC_CONCENTRATION].val1)/100;
- }
- if(atk < 0) atk = 0;
- return atk;
-}
-/*==========================================
- * 対象の左手Atkを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_atk_(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl){
- int atk=((struct map_session_data*)bl)->watk_;
-
- if(((struct map_session_data *)bl)->sc_data[SC_CURSE].timer!=-1 )
- atk -= atk*25/100;
- return atk;
- }
- else
- return 0;
-}
-/*==========================================
- * 対象のAtk2を返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_atk2(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data*)bl)->watk2;
- else {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int atk2=0;
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- atk2 = mob_db[((struct mob_data*)bl)->class].atk2;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- atk2 = mob_db[((struct pet_data*)bl)->class].atk2;
- if(sc_data) {
- if( sc_data[SC_IMPOSITIO].timer!=-1)
- atk2 += sc_data[SC_IMPOSITIO].val1*5;
- if( sc_data[SC_PROVOKE].timer!=-1 )
- atk2 = atk2*(100+2*sc_data[SC_PROVOKE].val1)/100;
- if( sc_data[SC_CURSE].timer!=-1 )
- atk2 -= atk2*25/100;
- if(sc_data[SC_DRUMBATTLE].timer!=-1)
- atk2 += sc_data[SC_DRUMBATTLE].val2;
- if(sc_data[SC_NIBELUNGEN].timer!=-1 && (battle_get_element(bl)/10) >= 8 )
- atk2 += sc_data[SC_NIBELUNGEN].val2;
- if(sc_data[SC_STRIPWEAPON].timer!=-1)
- atk2 = atk2*90/100;
- if(sc_data[SC_CONCENTRATION].timer!=-1) //コンセントレーション
- atk2 += atk2*(5*sc_data[SC_CONCENTRATION].val1)/100;
- }
- if(atk2 < 0) atk2 = 0;
- return atk2;
- }
- return 0;
-}
-/*==========================================
- * 対象の左手Atk2を返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_atk_2(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data*)bl)->watk_2;
- else
- return 0;
-}
-/*==========================================
- * 対象のMAtk1を返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_matk1(struct block_list *bl)
-{
- struct status_change *sc_data;
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_MOB){
- int matk,int_=battle_get_int(bl);
- matk = int_+(int_/5)*(int_/5);
-
- if(sc_data)
- if(sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100;
- return matk;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->matk1;
- else if(bl->type==BL_PET){
- int matk,int_=battle_get_int(bl);
- matk = int_+(int_/5)*(int_/5);
-
- if(sc_data)
- if(sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100;
- return matk;
- }
- else
- return 0;
-}
-/*==========================================
- * 対象のMAtk2を返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_matk2(struct block_list *bl)
-{
- struct status_change *sc_data=battle_get_sc_data(bl);
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB){
- int matk,int_=battle_get_int(bl);
- matk = int_+(int_/7)*(int_/7);
-
- if(sc_data)
- if(sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100;
- return matk;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->matk2;
- else if(bl->type==BL_PET){
- int matk,int_=battle_get_int(bl);
- matk = int_+(int_/7)*(int_/7);
- if(sc_data)
- if(sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- matk = matk*(100+2*sc_data[SC_MINDBREAKER].val1)/100;
- return matk;
- }
- else
- return 0;
-}
-/*==========================================
- * 対象のDefを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_def(struct block_list *bl)
-{
- struct status_change *sc_data;
- int def=0,skilltimer=-1,skillid=0;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl){
- def = ((struct map_session_data *)bl)->def;
- skilltimer = ((struct map_session_data *)bl)->skilltimer;
- skillid = ((struct map_session_data *)bl)->skillid;
- }
- else if(bl->type==BL_MOB && (struct mob_data *)bl) {
- def = mob_db[((struct mob_data *)bl)->class].def;
- skilltimer = ((struct mob_data *)bl)->skilltimer;
- skillid = ((struct mob_data *)bl)->skillid;
- }
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- def = mob_db[((struct pet_data *)bl)->class].def;
-
- if(def < 1000000) {
- if(sc_data) {
- //キーピング時はDEF100
- if( sc_data[SC_KEEPING].timer!=-1)
- def = 100;
- //プロボック時は減算
- if( sc_data[SC_PROVOKE].timer!=-1 && bl->type != BL_PC)
- def = (def*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100;
- //戦太鼓の響き時は加算
- if( sc_data[SC_DRUMBATTLE].timer!=-1 && bl->type != BL_PC)
- def += sc_data[SC_DRUMBATTLE].val3;
- //毒にかかっている時は減算
- if(sc_data[SC_POISON].timer!=-1 && bl->type != BL_PC)
- def = def*75/100;
- //ストリップシールド時は減算
- if(sc_data[SC_STRIPSHIELD].timer!=-1 && bl->type != BL_PC)
- def = def*85/100;
- //シグナムクルシス時は減算
- if(sc_data[SC_SIGNUMCRUCIS].timer!=-1 && bl->type != BL_PC)
- def = def * (100 - sc_data[SC_SIGNUMCRUCIS].val2)/100;
- //永遠の混沌時はDEF0になる
- if(sc_data[SC_ETERNALCHAOS].timer!=-1 && bl->type != BL_PC)
- def = 0;
- //凍結、石化時は右シフト
- if(sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0))
- def >>= 1;
- //コンセントレーション時は減算
- if( sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC)
- def = (def*(100 - 5*sc_data[SC_CONCENTRATION].val1))/100;
- }
- //詠唱中は詠唱時減算率に基づいて減算
- if(skilltimer != -1) {
- int def_rate = skill_get_castdef(skillid);
- if(def_rate != 0)
- def = (def * (100 - def_rate))/100;
- }
- }
- if(def < 0) def = 0;
- return def;
-}
-/*==========================================
- * 対象のMDefを返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_mdef(struct block_list *bl)
-{
- struct status_change *sc_data;
- int mdef=0;
-
- nullpo_retr(0, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- mdef = ((struct map_session_data *)bl)->mdef;
- else if(bl->type==BL_MOB && (struct mob_data *)bl)
- mdef = mob_db[((struct mob_data *)bl)->class].mdef;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- mdef = mob_db[((struct pet_data *)bl)->class].mdef;
-
- if(mdef < 1000000) {
- if(sc_data) {
- //バリアー状態時はMDEF100
- if(sc_data[SC_BARRIER].timer != -1)
- mdef = 100;
- //凍結、石化時は1.25倍
- if(sc_data[SC_FREEZE].timer != -1 || (sc_data[SC_STONE].timer != -1 && sc_data[SC_STONE].val2 == 0))
- mdef = mdef*125/100;
- if( sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- mdef -= (mdef*6*sc_data[SC_MINDBREAKER].val1)/100;
- }
- }
- if(mdef < 0) mdef = 0;
- return mdef;
-}
-/*==========================================
- * 対象のDef2を返す(汎用)
- * 戻りは整数で1以上
- *------------------------------------------
- */
-int battle_get_def2(struct block_list *bl)
-{
- struct status_change *sc_data;
- int def2=1;
-
- nullpo_retr(1, bl);
- sc_data=battle_get_sc_data(bl);
- if(bl->type==BL_PC)
- def2 = ((struct map_session_data *)bl)->def2;
- else if(bl->type==BL_MOB)
- def2 = mob_db[((struct mob_data *)bl)->class].vit;
- else if(bl->type==BL_PET)
- def2 = mob_db[((struct pet_data *)bl)->class].vit;
-
- if(sc_data) {
- if( sc_data[SC_ANGELUS].timer!=-1 && bl->type != BL_PC)
- def2 = def2*(110+5*sc_data[SC_ANGELUS].val1)/100;
- if( sc_data[SC_PROVOKE].timer!=-1 && bl->type != BL_PC)
- def2 = (def2*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100;
- if(sc_data[SC_POISON].timer!=-1 && bl->type != BL_PC)
- def2 = def2*75/100;
- //コンセントレーション時は減算
- if( sc_data[SC_CONCENTRATION].timer!=-1 && bl->type != BL_PC)
- def2 = def2*(100 - 5*sc_data[SC_CONCENTRATION].val1)/100;
- }
- if(def2 < 1) def2 = 1;
- return def2;
-}
-/*==========================================
- * 対象のMDef2を返す(汎用)
- * 戻りは整数で0以上
- *------------------------------------------
- */
-int battle_get_mdef2(struct block_list *bl)
-{
- int mdef2=0;
- struct status_change *sc_data=battle_get_sc_data(bl);
-
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB)
- mdef2 = mob_db[((struct mob_data *)bl)->class].int_ + (mob_db[((struct mob_data *)bl)->class].vit>>1);
- else if(bl->type==BL_PC)
- mdef2 = ((struct map_session_data *)bl)->mdef2 + (((struct map_session_data *)bl)->paramc[2]>>1);
- else if(bl->type==BL_PET)
- mdef2 = mob_db[((struct pet_data *)bl)->class].int_ + (mob_db[((struct pet_data *)bl)->class].vit>>1);
- if(sc_data) {
- if( sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
- mdef2 -= (mdef2*6*sc_data[SC_MINDBREAKER].val1)/100;
- }
- if(mdef2 < 0) mdef2 = 0;
- return mdef2;
-}
-/*==========================================
- * 対象のSpeed(移動速度)を返す(汎用)
- * 戻りは整数で1以上
- * Speedは小さいほうが移動速度が速い
- *------------------------------------------
- */
-int battle_get_speed(struct block_list *bl)
-{
- nullpo_retr(1000, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->speed;
- else {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int speed = 1000;
- if(bl->type==BL_MOB && (struct mob_data *)bl) {
- speed = ((struct mob_data *)bl)->speed;
- if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
- speed-=((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class].lv;
- }
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- speed = ((struct pet_data *)bl)->msd->petDB->speed;
-
- if(sc_data) {
- //速度増加時は25%減算
- if(sc_data[SC_INCREASEAGI].timer!=-1 && sc_data[SC_DONTFORGETME].timer == -1)
- speed -= speed*25/100;
- //速度減少時は25%加算
- if(sc_data[SC_DECREASEAGI].timer!=-1)
- speed = speed*125/100;
- //クァグマイア時は50%加算
- if(sc_data[SC_QUAGMIRE].timer!=-1)
- speed = speed*3/2;
- //私を忘れないで…時は加算
- if(sc_data[SC_DONTFORGETME].timer!=-1)
- speed = speed*(100+sc_data[SC_DONTFORGETME].val1*2 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3&0xffff))/100;
- //金剛時は25%加算
- if(sc_data[SC_STEELBODY].timer!=-1)
- speed = speed*125/100;
- //ディフェンダー時は加算
- if(sc_data[SC_DEFENDER].timer!=-1)
- speed = (speed * (155 - sc_data[SC_DEFENDER].val1*5)) / 100;
- //踊り状態は4倍遅い
- if(sc_data[SC_DANCING].timer!=-1 )
- speed*=4;
- //呪い時は450加算
- if(sc_data[SC_CURSE].timer!=-1)
- speed = speed + 450;
- //ウィンドウォーク時はLv*2%減算
- if(sc_data[SC_WINDWALK].timer!=-1)
- speed -= (speed*(sc_data[SC_WINDWALK].val1*2))/100;
- if(sc_data[SC_SLOWDOWN].timer!=-1)
- speed = speed*150/100;
- }
- if(speed < 1) speed = 1;
- return speed;
- }
-
- return 1000;
-}
-/*==========================================
- * 対象のaDelay(攻撃時ディレイ)を返す(汎用)
- * aDelayは小さいほうが攻撃速度が速い
- *------------------------------------------
- */
-int battle_get_adelay(struct block_list *bl)
-{
- nullpo_retr(4000, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return (((struct map_session_data *)bl)->aspd<<1);
- else {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int adelay=4000,aspd_rate = 100,i;
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- adelay = mob_db[((struct mob_data *)bl)->class].adelay;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- adelay = mob_db[((struct pet_data *)bl)->class].adelay;
-
- if(sc_data) {
- //ツーハンドクイッケン使用時でクァグマイアでも私を忘れないで…でもない時は3割減算
- if(sc_data[SC_TWOHANDQUICKEN].timer != -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // 2HQ
- aspd_rate -= 30;
- //アドレナリンラッシュ使用時でツーハンドクイッケンでもクァグマイアでも私を忘れないで…でもない時は
- if(sc_data[SC_ADRENALINE].timer != -1 && sc_data[SC_TWOHANDQUICKEN].timer == -1 &&
- sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) { // アドレナリンラッシュ
- //使用者とパーティメンバーで格差が出る設定でなければ3割減算
- if(sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penaly)
- aspd_rate -= 30;
- //そうでなければ2.5割減算
- else
- aspd_rate -= 25;
- }
- //スピアクィッケン時は減算
- if(sc_data[SC_SPEARSQUICKEN].timer != -1 && sc_data[SC_ADRENALINE].timer == -1 &&
- sc_data[SC_TWOHANDQUICKEN].timer == -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // スピアクィッケン
- aspd_rate -= sc_data[SC_SPEARSQUICKEN].val2;
- //夕日のアサシンクロス時は減算
- if(sc_data[SC_ASSNCROS].timer!=-1 && // 夕陽のアサシンクロス
- sc_data[SC_TWOHANDQUICKEN].timer==-1 && sc_data[SC_ADRENALINE].timer==-1 && sc_data[SC_SPEARSQUICKEN].timer==-1 &&
- sc_data[SC_DONTFORGETME].timer == -1)
- aspd_rate -= 5+sc_data[SC_ASSNCROS].val1+sc_data[SC_ASSNCROS].val2+sc_data[SC_ASSNCROS].val3;
- //私を忘れないで…時は加算
- if(sc_data[SC_DONTFORGETME].timer!=-1) // 私を忘れないで
- aspd_rate += sc_data[SC_DONTFORGETME].val1*3 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3>>16);
- //金剛時25%加算
- if(sc_data[SC_STEELBODY].timer!=-1) // 金剛
- aspd_rate += 25;
- //増速ポーション使用時は減算
- if( sc_data[i=SC_SPEEDPOTION2].timer!=-1 || sc_data[i=SC_SPEEDPOTION1].timer!=-1 || sc_data[i=SC_SPEEDPOTION0].timer!=-1)
- aspd_rate -= sc_data[i].val2;
- //ディフェンダー時は加算
- if(sc_data[SC_DEFENDER].timer != -1)
- adelay += (1100 - sc_data[SC_DEFENDER].val1*100);
- }
- if(aspd_rate != 100)
- adelay = adelay*aspd_rate/100;
- if(adelay < battle_config.monster_max_aspd<<1) adelay = battle_config.monster_max_aspd<<1;
- return adelay;
- }
- return 4000;
-}
-int battle_get_amotion(struct block_list *bl)
-{
- nullpo_retr(2000, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->amotion;
- else {
- struct status_change *sc_data=battle_get_sc_data(bl);
- int amotion=2000,aspd_rate = 100,i;
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- amotion = mob_db[((struct mob_data *)bl)->class].amotion;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- amotion = mob_db[((struct pet_data *)bl)->class].amotion;
-
- if(sc_data) {
- if(sc_data[SC_TWOHANDQUICKEN].timer != -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // 2HQ
- aspd_rate -= 30;
- if(sc_data[SC_ADRENALINE].timer != -1 && sc_data[SC_TWOHANDQUICKEN].timer == -1 &&
- sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) { // アドレナリンラッシュ
- if(sc_data[SC_ADRENALINE].val2 || !battle_config.party_skill_penaly)
- aspd_rate -= 30;
- else
- aspd_rate -= 25;
- }
- if(sc_data[SC_SPEARSQUICKEN].timer != -1 && sc_data[SC_ADRENALINE].timer == -1 &&
- sc_data[SC_TWOHANDQUICKEN].timer == -1 && sc_data[SC_QUAGMIRE].timer == -1 && sc_data[SC_DONTFORGETME].timer == -1) // スピアクィッケン
- aspd_rate -= sc_data[SC_SPEARSQUICKEN].val2;
- if(sc_data[SC_ASSNCROS].timer!=-1 && // 夕陽のアサシンクロス
- sc_data[SC_TWOHANDQUICKEN].timer==-1 && sc_data[SC_ADRENALINE].timer==-1 && sc_data[SC_SPEARSQUICKEN].timer==-1 &&
- sc_data[SC_DONTFORGETME].timer == -1)
- aspd_rate -= 5+sc_data[SC_ASSNCROS].val1+sc_data[SC_ASSNCROS].val2+sc_data[SC_ASSNCROS].val3;
- if(sc_data[SC_DONTFORGETME].timer!=-1) // 私を忘れないで
- aspd_rate += sc_data[SC_DONTFORGETME].val1*3 + sc_data[SC_DONTFORGETME].val2 + (sc_data[SC_DONTFORGETME].val3>>16);
- if(sc_data[SC_STEELBODY].timer!=-1) // 金剛
- aspd_rate += 25;
- if( sc_data[i=SC_SPEEDPOTION2].timer!=-1 || sc_data[i=SC_SPEEDPOTION1].timer!=-1 || sc_data[i=SC_SPEEDPOTION0].timer!=-1)
- aspd_rate -= sc_data[i].val2;
- if(sc_data[SC_DEFENDER].timer != -1)
- amotion += (550 - sc_data[SC_DEFENDER].val1*50);
- }
- if(aspd_rate != 100)
- amotion = amotion*aspd_rate/100;
- if(amotion < battle_config.monster_max_aspd) amotion = battle_config.monster_max_aspd;
- return amotion;
- }
- return 2000;
-}
-int battle_get_dmotion(struct block_list *bl)
-{
- int ret;
- struct status_change *sc_data;
-
- nullpo_retr(0, bl);
- sc_data = battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl){
- ret=mob_db[((struct mob_data *)bl)->class].dmotion;
- if(battle_config.monster_damage_delay_rate != 100)
- ret = ret*battle_config.monster_damage_delay_rate/400;
- }
- else if(bl->type==BL_PC && (struct map_session_data *)bl){
- ret=((struct map_session_data *)bl)->dmotion;
- if(battle_config.pc_damage_delay_rate != 100)
- ret = ret*battle_config.pc_damage_delay_rate/400;
- }
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- ret=mob_db[((struct pet_data *)bl)->class].dmotion;
- else
- return 2000;
-
- if((sc_data && (sc_data[SC_ENDURE].timer!=-1 || sc_data[SC_BERSERK].timer!=-1)) ||
- (bl->type == BL_PC && ((struct map_session_data *)bl)->special_state.infinite_endure))
- ret=0;
-
- return ret;
-}
-int battle_get_element(struct block_list *bl)
-{
- int ret = 20;
- struct status_change *sc_data;
-
- nullpo_retr(ret, bl);
- sc_data = battle_get_sc_data(bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl) // 10の位=Lv*2、1の位=属性
- ret=((struct mob_data *)bl)->def_ele;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- ret=20+((struct map_session_data *)bl)->def_ele; // 防御属性Lv1
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- ret = mob_db[((struct pet_data *)bl)->class].element;
-
- if(sc_data) {
- if( sc_data[SC_BENEDICTIO].timer!=-1 ) // 聖体降福
- ret=26;
- if( sc_data[SC_FREEZE].timer!=-1 ) // 凍結
- ret=21;
- if( sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0)
- ret=22;
- }
-
- return ret;
-}
-int battle_get_attack_element(struct block_list *bl)
-{
- int ret = 0;
- struct status_change *sc_data=battle_get_sc_data(bl);
-
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- ret=0;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- ret=((struct map_session_data *)bl)->atk_ele;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- ret=0;
-
- if(sc_data) {
- if( sc_data[SC_FROSTWEAPON].timer!=-1) // フロストウェポン
- ret=1;
- if( sc_data[SC_SEISMICWEAPON].timer!=-1) // サイズミックウェポン
- ret=2;
- if( sc_data[SC_FLAMELAUNCHER].timer!=-1) // フレームランチャー
- ret=3;
- if( sc_data[SC_LIGHTNINGLOADER].timer!=-1) // ライトニングローダー
- ret=4;
- if( sc_data[SC_ENCPOISON].timer!=-1) // エンチャントポイズン
- ret=5;
- if( sc_data[SC_ASPERSIO].timer!=-1) // アスペルシオ
- ret=6;
- }
-
- return ret;
-}
-int battle_get_attack_element2(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl) {
- int ret = ((struct map_session_data *)bl)->atk_ele_;
- struct status_change *sc_data = ((struct map_session_data *)bl)->sc_data;
-
- if(sc_data) {
- if( sc_data[SC_FROSTWEAPON].timer!=-1) // フロストウェポン
- ret=1;
- if( sc_data[SC_SEISMICWEAPON].timer!=-1) // サイズミックウェポン
- ret=2;
- if( sc_data[SC_FLAMELAUNCHER].timer!=-1) // フレームランチャー
- ret=3;
- if( sc_data[SC_LIGHTNINGLOADER].timer!=-1) // ライトニングローダー
- ret=4;
- if( sc_data[SC_ENCPOISON].timer!=-1) // エンチャントポイズン
- ret=5;
- if( sc_data[SC_ASPERSIO].timer!=-1) // アスペルシオ
- ret=6;
- }
- return ret;
- }
- return 0;
-}
-int battle_get_party_id(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->status.party_id;
- else if(bl->type==BL_MOB && (struct mob_data *)bl){
- struct mob_data *md=(struct mob_data *)bl;
- if( md->master_id>0 )
- return -md->master_id;
- return -md->bl.id;
- }
- else if(bl->type==BL_SKILL && (struct skill_unit *)bl)
- return ((struct skill_unit *)bl)->group->party_id;
- else
- return 0;
-}
-int battle_get_guild_id(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data *)bl)->status.guild_id;
- else if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data *)bl)->class;
- else if(bl->type==BL_SKILL && (struct skill_unit *)bl)
- return ((struct skill_unit *)bl)->group->guild_id;
- else
- return 0;
-}
-int battle_get_race(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].race;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return 7;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return mob_db[((struct pet_data *)bl)->class].race;
- else
- return 0;
-}
-int battle_get_size(struct block_list *bl)
-{
- nullpo_retr(1, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].size;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return 1;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return mob_db[((struct pet_data *)bl)->class].size;
- else
- return 1;
-}
-int battle_get_mode(struct block_list *bl)
-{
- nullpo_retr(0x01, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].mode;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return mob_db[((struct pet_data *)bl)->class].mode;
- else
- return 0x01; // とりあえず動くということで1
-}
-
-int battle_get_mexp(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].mexp;
- else if(bl->type==BL_PET && (struct pet_data *)bl)
- return mob_db[((struct pet_data *)bl)->class].mexp;
- else
- return 0;
-}
-
-// StatusChange系の所得
-struct status_change *battle_get_sc_data(struct block_list *bl)
-{
- nullpo_retr(NULL, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return ((struct mob_data*)bl)->sc_data;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return ((struct map_session_data*)bl)->sc_data;
- return NULL;
-}
-short *battle_get_sc_count(struct block_list *bl)
-{
- nullpo_retr(NULL, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return &((struct mob_data*)bl)->sc_count;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return &((struct map_session_data*)bl)->sc_count;
- return NULL;
-}
-short *battle_get_opt1(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return &((struct mob_data*)bl)->opt1;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return &((struct map_session_data*)bl)->opt1;
- else if(bl->type==BL_NPC && (struct npc_data *)bl)
- return &((struct npc_data*)bl)->opt1;
- return 0;
-}
-short *battle_get_opt2(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return &((struct mob_data*)bl)->opt2;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return &((struct map_session_data*)bl)->opt2;
- else if(bl->type==BL_NPC && (struct npc_data *)bl)
- return &((struct npc_data*)bl)->opt2;
- return 0;
-}
-short *battle_get_opt3(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return &((struct mob_data*)bl)->opt3;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return &((struct map_session_data*)bl)->opt3;
- else if(bl->type==BL_NPC && (struct npc_data *)bl)
- return &((struct npc_data*)bl)->opt3;
- return 0;
-}
-short *battle_get_option(struct block_list *bl)
-{
- nullpo_retr(0, bl);
- if(bl->type==BL_MOB && (struct mob_data *)bl)
- return &((struct mob_data*)bl)->option;
- else if(bl->type==BL_PC && (struct map_session_data *)bl)
- return &((struct map_session_data*)bl)->status.option;
- else if(bl->type==BL_NPC && (struct npc_data *)bl)
- return &((struct npc_data*)bl)->option;
- return 0;
-}
-
-//-------------------------------------------------------------------
// ダメージの遅延
struct battle_delay_damage_ {
- struct block_list *src,*target;
+ struct block_list *src;
+ int target;
int damage;
int flag;
};
int battle_delay_damage_sub(int tid,unsigned int tick,int id,int data)
{
struct battle_delay_damage_ *dat=(struct battle_delay_damage_ *)data;
- if( dat && map_id2bl(id)==dat->src && dat->target->prev!=NULL)
- battle_damage(dat->src,dat->target,dat->damage,dat->flag);
- free(dat);
+ struct block_list *target=map_id2bl(dat->target);
+ if( dat && map_id2bl(id)==dat->src && target && target->prev!=NULL)
+ battle_damage(dat->src,target,dat->damage,dat->flag);
+ aFree(dat);
return 0;
}
int battle_delay_damage(unsigned int tick,struct block_list *src,struct block_list *target,int damage,int flag)
@@ -1319,7 +82,7 @@ int battle_delay_damage(unsigned int tick,struct block_list *src,struct block_li
dat->src=src;
- dat->target=target;
+ dat->target=target->id;
dat->damage=damage;
dat->flag=flag;
add_timer(tick,battle_delay_damage_sub,src->id,(int)dat);
@@ -1330,7 +93,7 @@ int battle_delay_damage(unsigned int tick,struct block_list *src,struct block_li
int battle_damage(struct block_list *bl,struct block_list *target,int damage,int flag)
{
struct map_session_data *sd=NULL;
- struct status_change *sc_data=battle_get_sc_data(target);
+ struct status_change *sc_data=status_get_sc_data(target);
short *sc_count;
int i;
@@ -1353,14 +116,14 @@ int battle_damage(struct block_list *bl,struct block_list *target,int damage,int
if(damage<0)
return battle_heal(bl,target,-damage,0,flag);
- if(!flag && (sc_count=battle_get_sc_count(target))!=NULL && *sc_count>0){
+ if(!flag && (sc_count=status_get_sc_count(target))!=NULL && *sc_count>0){
// 凍結、石化、睡眠を消去
if(sc_data[SC_FREEZE].timer!=-1)
- skill_status_change_end(target,SC_FREEZE,-1);
+ status_change_end(target,SC_FREEZE,-1);
if(sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0)
- skill_status_change_end(target,SC_STONE,-1);
+ status_change_end(target,SC_STONE,-1);
if(sc_data[SC_SLEEP].timer!=-1)
- skill_status_change_end(target,SC_SLEEP,-1);
+ status_change_end(target,SC_SLEEP,-1);
}
if(target->type==BL_MOB){ // MOB
@@ -1479,29 +242,35 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
struct mob_data *md=NULL;
struct status_change *sc_data,*sc;
short *sc_count;
- int class;
+ int class_;
nullpo_retr(0, bl);
- class = battle_get_class(bl);
+ class_ = status_get_class(bl);
if(bl->type==BL_MOB) md=(struct mob_data *)bl;
else sd=(struct map_session_data *)bl;
- sc_data=battle_get_sc_data(bl);
- sc_count=battle_get_sc_count(bl);
+ sc_data=status_get_sc_data(bl);
+ sc_count=status_get_sc_count(bl);
if(sc_count!=NULL && *sc_count>0){
-
- if(sc_data[SC_SAFETYWALL].timer!=-1 && damage>0 && flag&BF_WEAPON && flag&BF_SHORT && skill_num != NPC_GUIDEDATTACK){
+ if (sc_data[SC_SAFETYWALL].timer!=-1 && damage>0 && flag&BF_WEAPON &&
+ flag&BF_SHORT && skill_num != NPC_GUIDEDATTACK) {
// セーフティウォール
- struct skill_unit *unit=(struct skill_unit*)sc_data[SC_SAFETYWALL].val2;
- if( unit && unit->alive && (--unit->group->val2)<=0 )
- skill_delunit(unit);
- skill_unit_move(bl,gettick(),1); // 重ね掛けチェック
- damage=0;
+ struct skill_unit *unit;
+ unit = (struct skill_unit *)sc_data[SC_SAFETYWALL].val2;
+ if (unit) {
+ if (unit->group && (--unit->group->val2)<=0)
+ skill_delunit(unit);
+ damage=0;
+ } else {
+ status_change_end(bl,SC_SAFETYWALL,-1);
+ }
}
- if(sc_data[SC_PNEUMA].timer!=-1 && damage>0 && ((flag&BF_WEAPON && flag&BF_LONG && skill_num != NPC_GUIDEDATTACK) ||
- (flag&BF_MISC && (skill_num == HT_BLITZBEAT || skill_num == SN_FALCONASSAULT)))){ // [DracoRPG]
+ if(sc_data[SC_PNEUMA].timer!=-1 && damage>0 &&
+ ((flag&BF_WEAPON && flag&BF_LONG && skill_num != NPC_GUIDEDATTACK) ||
+ (flag&BF_MISC && (skill_num == HT_BLITZBEAT || skill_num == SN_FALCONASSAULT)) ||
+ (flag&BF_MAGIC && skill_num == ASC_BREAKER))){ // [DracoRPG]
// ニューマ
damage=0;
}
@@ -1514,29 +283,35 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
if(sc_data[SC_AETERNA].timer!=-1 && damage>0){ // レックスエーテルナ
damage<<=1;
- skill_status_change_end( bl,SC_AETERNA,-1 );
+ status_change_end( bl,SC_AETERNA,-1 );
}
//属性場のダメージ増加
if(sc_data[SC_VOLCANO].timer!=-1){ // ボルケーノ
if(flag&BF_SKILL && skill_get_pl(skill_num)==3)
- damage += damage*sc_data[SC_VOLCANO].val4/100;
- else if(!flag&BF_SKILL && battle_get_attack_element(bl)==3)
- damage += damage*sc_data[SC_VOLCANO].val4/100;
+ //damage += damage*sc_data[SC_VOLCANO].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_VOLCANO].val1-1] /100;
+ else if(!flag&BF_SKILL && status_get_attack_element(bl)==3)
+ //damage += damage*sc_data[SC_VOLCANO].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_VOLCANO].val1-1] /100;
}
if(sc_data[SC_VIOLENTGALE].timer!=-1){ // バイオレントゲイル
if(flag&BF_SKILL && skill_get_pl(skill_num)==4)
- damage += damage*sc_data[SC_VIOLENTGALE].val4/100;
- else if(!flag&BF_SKILL && battle_get_attack_element(bl)==4)
- damage += damage*sc_data[SC_VIOLENTGALE].val4/100;
+ //damage += damage*sc_data[SC_VIOLENTGALE].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_VIOLENTGALE].val1-1] /100;
+ else if(!flag&BF_SKILL && status_get_attack_element(bl)==4)
+ //damage += damage*sc_data[SC_VIOLENTGALE].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_VIOLENTGALE].val1-1] /100;
}
if(sc_data[SC_DELUGE].timer!=-1){ // デリュージ
if(flag&BF_SKILL && skill_get_pl(skill_num)==1)
- damage += damage*sc_data[SC_DELUGE].val4/100;
- else if(!flag&BF_SKILL && battle_get_attack_element(bl)==1)
- damage += damage*sc_data[SC_DELUGE].val4/100;
+ //damage += damage*sc_data[SC_DELUGE].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_DELUGE].val1-1] /100;
+ else if(!flag&BF_SKILL && status_get_attack_element(bl)==1)
+ //damage += damage*sc_data[SC_DELUGE].val4/100;
+ damage += damage * enchant_eff[sc_data[SC_DELUGE].val1-1] /100;
}
if(sc_data[SC_ENERGYCOAT].timer!=-1 && damage>0 && flag&BF_WEAPON){ // エナジーコート
@@ -1549,7 +324,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
clif_updatestatus(sd,SP_SP);
}
if(sd->status.sp<=0)
- skill_status_change_end( bl,SC_ENERGYCOAT,-1 );
+ status_change_end( bl,SC_ENERGYCOAT,-1 );
}
else
damage -= damage * (sc_data[SC_ENERGYCOAT].val1 * 6) / 100;
@@ -1563,7 +338,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
else damage=-sc->val2;
}
if((--sc->val3)<=0 || (sc->val2<=0) || skill_num == AL_HOLYLIGHT)
- skill_status_change_end(bl, SC_KYRIE, -1);
+ status_change_end(bl, SC_KYRIE, -1);
}
if(sc_data[SC_BASILICA].timer!=-1 && damage > 0){
@@ -1577,12 +352,21 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
if(sc_data[SC_AUTOGUARD].timer != -1 && damage > 0 && flag&BF_WEAPON) {
if(rand()%100 < sc_data[SC_AUTOGUARD].val2) {
+ int delay;
+
damage = 0;
clif_skill_nodamage(bl,bl,CR_AUTOGUARD,sc_data[SC_AUTOGUARD].val1,1);
+ // different delay depending on skill level [celest]
+ if (sc_data[SC_AUTOGUARD].val1 <= 5)
+ delay = 300;
+ else if (sc_data[SC_AUTOGUARD].val1 > 5 && sc_data[SC_AUTOGUARD].val1 <= 9)
+ delay = 200;
+ else
+ delay = 100;
if(sd)
- sd->canmove_tick = gettick() + 300;
+ sd->canmove_tick = gettick() + delay;
else if(md)
- md->canmove_tick = gettick() + 300;
+ md->canmove_tick = gettick() + delay;
}
}
// -- moonsoul (chance to block attacks with new Lord Knight skill parrying)
@@ -1595,39 +379,43 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
}
// リジェクトソード
if(sc_data[SC_REJECTSWORD].timer!=-1 && damage > 0 && flag&BF_WEAPON &&
- ((src->type==BL_PC && ((struct map_session_data *)src)->status.weapon == (1 || 2 || 3)) || src->type==BL_MOB )){
+ // Fixed the condition check [Aalye]
+ (src->type==BL_MOB || (src->type==BL_PC && (((struct map_session_data *)src)->status.weapon == 1 ||
+ ((struct map_session_data *)src)->status.weapon == 2 ||
+ ((struct map_session_data *)src)->status.weapon == 3)))){
if(rand()%100 < (15*sc_data[SC_REJECTSWORD].val1)){ //反射確率は15*Lv
damage = damage*50/100;
+ clif_damage(bl,src,gettick(),0,0,damage,0,0,0);
battle_damage(bl,src,damage,0);
//ダメージを与えたのは良いんだが、ここからどうして表示するんだかわかんねぇ
//エフェクトもこれでいいのかわかんねぇ
clif_skill_nodamage(bl,bl,ST_REJECTSWORD,sc_data[SC_REJECTSWORD].val1,1);
if((--sc_data[SC_REJECTSWORD].val2)<=0)
- skill_status_change_end(bl, SC_REJECTSWORD, -1);
+ status_change_end(bl, SC_REJECTSWORD, -1);
}
}
if(sc_data[SC_SPIDERWEB].timer!=-1 && damage > 0) // [Celest]
if ((flag&BF_SKILL && skill_get_pl(skill_num)==3) ||
- (!flag&BF_SKILL && battle_get_attack_element(src)==3)) {
+ (!flag&BF_SKILL && status_get_attack_element(src)==3)) {
damage<<=1;
- skill_status_change_end(bl, SC_SPIDERWEB, -1);
+ status_change_end(bl, SC_SPIDERWEB, -1);
}
-
+
if(sc_data[SC_FOGWALL].timer != -1 && flag&BF_MAGIC)
- if(rand()%100 < sc_data[SC_FOGWALL].val2)
+ if(rand()%100 < 75)
damage = 0;
}
- if(class == 1288 || class == 1287 || class == 1286 || class == 1285) {
-// if(class == 1288) {
- if(class == 1288 && flag&BF_SKILL)
+ if(class_ == 1288 || class_ == 1287 || class_ == 1286 || class_ == 1285) {
+// if(class_ == 1288) {
+ if(class_ == 1288 && (flag&BF_SKILL || skill_num == ASC_BREAKER || skill_num == PA_SACRIFICE))
damage=0;
if(src->type == BL_PC) {
struct guild *g=guild_search(((struct map_session_data *)src)->status.guild_id);
struct guild_castle *gc=guild_mapname2gc(map[bl->m].name);
if(!((struct map_session_data *)src)->status.guild_id)
damage=0;
- if(gc && agit_flag==0 && class != 1288) // guardians cannot be damaged during non-woe [Valaris]
+ if(gc && agit_flag==0 && class_ != 1288) // guardians cannot be damaged during non-woe [Valaris]
damage=0; // end woe check [Valaris]
if(g == NULL)
damage=0;//ギルド未加入ならダメージ無し
@@ -1636,12 +424,18 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
else if(g && guild_checkskill(g,GD_APPROVAL) <= 0)
damage=0;//正規ギルド承認がないとダメージ無し
else if (battle_config.guild_max_castles != 0 && guild_checkcastles(g)>=battle_config.guild_max_castles)
- damage = 0; // [MouseJstr]
+ damage = 0; // [MouseJstr]
+ else if (g && gc && guild_check_alliance(gc->guild_id, g->guild_id, 0) == 1)
+ return 0;
}
else damage = 0;
}
if(map[bl->m].flag.gvg && damage > 0) { //GvG
+ if(bl->type == BL_MOB){ //defenseがあればダメージが減るらしい?
+ struct guild_castle *gc=guild_mapname2gc(map[bl->m].name);
+ if (gc) damage -= damage*(gc->defense/100)*(battle_config.castle_defense_rate/100);
+ }
if(flag&BF_WEAPON) {
if(flag&BF_SHORT)
damage=damage*battle_config.gvg_short_damage_rate/100;
@@ -1671,20 +465,47 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
}
/*==========================================
+ * HP/SP吸収の計算
+ *------------------------------------------
+ */
+int battle_calc_drain(int damage, int rate, int per, int val)
+{
+ int diff = 0;
+
+ if (damage <= 0 || rate <= 0)
+ return 0;
+
+ if (per && rand()%100 < rate) {
+ diff = (damage * per) / 100;
+ if (diff == 0) {
+ if (per > 0)
+ diff = 1;
+ else
+ diff = -1;
+ }
+ }
+
+ if (val && rand()%100 < rate) {
+ diff += val;
+ }
+ return diff;
+}
+
+/*==========================================
* 修練ダメージ
*------------------------------------------
*/
int battle_addmastery(struct map_session_data *sd,struct block_list *target,int dmg,int type)
{
int damage,skill;
- int race=battle_get_race(target);
+ int race=status_get_race(target);
int weapon;
damage = 0;
nullpo_retr(0, sd);
// デーモンベイン(+3 〜 +30) vs 不死 or 悪魔 (死人は含めない?)
- if((skill = pc_checkskill(sd,AL_DEMONBANE)) > 0 && (battle_check_undead(race,battle_get_elem_type(target)) || race==6) )
+ if((skill = pc_checkskill(sd,AL_DEMONBANE)) > 0 && (battle_check_undead(race,status_get_elem_type(target)) || race==6) )
damage += (skill*(int)(3+(sd->status.base_level+1)*0.05)); // submitted by orn
//damage += (skill * 3);
@@ -1698,7 +519,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
weapon = sd->weapontype2;
switch(weapon)
{
- case 0x01: // 短剣 (Updated By AppleGirl)
+ case 0x01: // 短剣 Knife
case 0x02: // 1HS
{
// 剣修練(+4 〜 +40) 片手剣 短剣含む
@@ -1716,16 +537,6 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
break;
}
case 0x04: // 1HL
- {
- // 槍修練(+4 〜 +40,+5 〜 +50) 槍
- if((skill = pc_checkskill(sd,KN_SPEARMASTERY)) > 0) {
- if(!pc_isriding(sd))
- damage += (skill * 4); // ペコに乗ってない
- else
- damage += (skill * 5); // ペコに乗ってる
- }
- break;
- }
case 0x05: // 2HL
{
// 槍修練(+4 〜 +40,+5 〜 +50) 槍
@@ -1737,13 +548,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
}
break;
}
- case 0x06: // 片手斧
- {
- if((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0) {
- damage += (skill * 3);
- }
- break;
- }
+ case 0x06: // 片手斧
case 0x07: // Axe by Tato
{
if((skill = pc_checkskill(sd,AM_AXEMASTERY)) > 0) {
@@ -1765,7 +570,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
break;
case 0x0b: // 弓
break;
- case 0x00: // 素手
+ case 0x00: // 素手 Bare Hands
case 0x0c: // Knuckles
{
// 鉄拳(+3 〜 +30) 素手,ナックル
@@ -1819,14 +624,16 @@ static struct Damage battle_calc_pet_weapon_attack(
struct mob_data *tmd=NULL;
int hitrate,flee,cri = 0,atkmin,atkmax;
int luk,target_count = 1;
- int def1 = battle_get_def(target);
- int def2 = battle_get_def2(target);
- int t_vit = battle_get_vit(target);
+ int def1 = status_get_def(target);
+ int def2 = status_get_def2(target);
+ int t_vit = status_get_vit(target);
struct Damage wd;
int damage,damage2=0,type,div_,blewcount=skill_get_blewcount(skill_num,skill_lv);
int flag,dmg_lv=0;
int t_mode=0,t_race=0,t_size=1,s_race=0,s_ele=0;
struct status_change *t_sc_data;
+ int div_flag=0; // 0: total damage is to be divided by div_
+ // 1: damage is distributed,and has to be multiplied by div_ [celest]
//return前の処理があるので情報出力部のみ変更
if( target == NULL || pd == NULL ){ //srcは内容に直接触れていないのでスルーしてみる
@@ -1835,8 +642,8 @@ static struct Damage battle_calc_pet_weapon_attack(
return wd;
}
- s_race=battle_get_race(src);
- s_ele=battle_get_attack_element(src);
+ s_race=status_get_race(src);
+ s_ele=status_get_attack_element(src);
// ターゲット
if(target->type == BL_MOB)
@@ -1845,61 +652,70 @@ static struct Damage battle_calc_pet_weapon_attack(
memset(&wd,0,sizeof(wd));
return wd;
}
- t_race=battle_get_race( target );
- t_size=battle_get_size( target );
- t_mode=battle_get_mode( target );
- t_sc_data=battle_get_sc_data( target );
+ t_race=status_get_race( target );
+ t_size=status_get_size( target );
+ t_mode=status_get_mode( target );
+ t_sc_data=status_get_sc_data( target );
flag=BF_SHORT|BF_WEAPON|BF_NORMAL; // 攻撃の種類の設定
// 回避率計算、回避判定は後で
- flee = battle_get_flee(target);
- if(battle_config.agi_penaly_type > 0 || battle_config.vit_penaly_type > 0)
- target_count += battle_counttargeted(target,src,battle_config.agi_penaly_count_lv);
- if(battle_config.agi_penaly_type > 0) {
- if(target_count >= battle_config.agi_penaly_count) {
- if(battle_config.agi_penaly_type == 1)
- flee = (flee * (100 - (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num))/100;
- else if(battle_config.agi_penaly_type == 2)
- flee -= (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num;
+ flee = status_get_flee(target);
+ if(battle_config.agi_penalty_type > 0 || battle_config.vit_penalty_type > 0)
+ target_count += battle_counttargeted(target,src,battle_config.agi_penalty_count_lv);
+ if(battle_config.agi_penalty_type > 0) {
+ if(target_count >= battle_config.agi_penalty_count) {
+ if(battle_config.agi_penalty_type == 1)
+ flee = (flee * (100 - (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
+ else if(battle_config.agi_penalty_type == 2)
+ flee -= (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
if(flee < 1) flee = 1;
}
}
- hitrate=battle_get_hit(src) - flee + 80;
+ hitrate=status_get_hit(src) - flee + 80;
type=0; // normal
- div_ = 1; // single attack
+ if (skill_num > 0) {
+ div_ = skill_get_num(skill_num,skill_lv);
+ if (div_ < 1) div_ = 1; //Avoid the rare case where the db says div_ is 0 and below
+ }
+ else div_ = 1; // single attack
- luk=battle_get_luk(src);
+ luk=status_get_luk(src);
if(battle_config.pet_str)
- damage = battle_get_baseatk(src);
+ damage = status_get_baseatk(src);
else
damage = 0;
if(skill_num==HW_MAGICCRASHER){ /* マジッククラッシャーはMATKで殴る */
- atkmin = battle_get_matk1(src);
- atkmax = battle_get_matk2(src);
+ atkmin = status_get_matk1(src);
+ atkmax = status_get_matk2(src);
}else{
- atkmin = battle_get_atk(src);
- atkmax = battle_get_atk2(src);
+ atkmin = status_get_atk(src);
+ atkmax = status_get_atk2(src);
}
- if(mob_db[pd->class].range>3 )
+ if(mob_db[pd->class_].range>3 )
flag=(flag&~BF_RANGEMASK)|BF_LONG;
if(atkmin > atkmax) atkmin = atkmax;
- cri = battle_get_critical(src);
- cri -= battle_get_luk(target) * 2; // luk/5*10 => target_luk*2 not target_luk*3
+ cri = status_get_critical(src);
+ cri -= status_get_luk(target) * 2; // luk/5*10 => target_luk*2 not target_luk*3
if(battle_config.enemy_critical_rate != 100) {
cri = cri*battle_config.enemy_critical_rate/100;
if(cri < 1)
cri = 1;
}
- if(t_sc_data != NULL && t_sc_data[SC_SLEEP].timer!=-1 )
- cri <<=1;
+ if(t_sc_data) {
+ if (t_sc_data[SC_SLEEP].timer!=-1)
+ cri <<=1;
+ if(t_sc_data[SC_JOINTBEAT].timer != -1 &&
+ t_sc_data[SC_JOINTBEAT].val2 == 6) // Always take crits with Neck broken by Joint Beat [DracoRPG]
+ cri = 1000;
+ }
- if(skill_num == 0 && skill_lv >= 0 && battle_config.enemy_critical && (rand() % 1000) < cri)
+ if(skill_num == 0 && battle_config.enemy_critical && (rand() % 1000) < cri)
{
damage += atkmax;
type = 0x0a;
@@ -1930,14 +746,14 @@ static struct Damage battle_calc_pet_weapon_attack(
hitrate = (hitrate*(100+5*skill_lv))/100;
break;
case SM_MAGNUM: // マグナムブレイク
- damage = damage*(5*skill_lv +(wflag)?65:115 )/100;
+ damage = damage*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100;
+ hitrate = (hitrate*(100+10*skill_lv))/100;
break;
case MC_MAMMONITE: // メマーナイト
damage = damage*(100+ 50*skill_lv)/100;
break;
case AC_DOUBLE: // ダブルストレイフィング
damage = damage*(180+ 20*skill_lv)/100;
- div_=2;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case AC_SHOWER: // アローシャワー
@@ -1952,7 +768,7 @@ static struct Damage battle_calc_pet_weapon_attack(
damage = damage*(100+ 10*skill_lv)/100;
hitrate = hitrate*(100+5*skill_lv)/100;
div_=t_size+1;
- damage*=div_;
+ div_flag = 1;
break;
case KN_SPEARSTAB: // スピアスタブ
damage = damage*(100+ 15*skill_lv)/100;
@@ -1970,14 +786,13 @@ static struct Damage battle_calc_pet_weapon_attack(
if(skill_lv>9 && wflag==2) damage2+=damage/4;
if(skill_lv>9 && wflag==3) damage2+=damage/2;
damage +=damage2;
- blewcount=0;
break;
case KN_BOWLINGBASH: // ボウリングバッシュ
damage = damage*(100+ 50*skill_lv)/100;
blewcount=0;
break;
case AS_GRIMTOOTH:
- damage = damage*(100+ 20*skill_lv)/100;
+ damage = damage*(100+ 20*skill_lv)/100;
break;
case AS_POISONREACT: // celest
s_ele = 0;
@@ -1985,7 +800,6 @@ static struct Damage battle_calc_pet_weapon_attack(
break;
case AS_SONICBLOW: // ソニックブロウ
damage = damage*(300+ 50*skill_lv)/100;
- div_=8;
break;
case TF_SPRINKLESAND: // 砂まき
damage = damage*125/100;
@@ -1995,8 +809,7 @@ static struct Damage battle_calc_pet_weapon_attack(
break;
// 以下MOB
case NPC_COMBOATTACK: // 多段攻撃
- div_=skill_get_num(skill_num,skill_lv);
- damage *= div_;
+ div_flag = 1;
break;
case NPC_RANDOMATTACK: // ランダムATK攻撃
damage = damage*(50+rand()%150)/100;
@@ -2009,6 +822,7 @@ static struct Damage battle_calc_pet_weapon_attack(
case NPC_POISONATTACK:
case NPC_HOLYATTACK:
case NPC_DARKNESSATTACK:
+ case NPC_UNDEADATTACK:
case NPC_TELEKINESISATTACK:
div_= pd->skillduration; // [Valaris]
break;
@@ -2043,27 +857,27 @@ static struct Damage battle_calc_pet_weapon_attack(
break;
case CR_HOLYCROSS: // ホーリークロス
damage = damage*(100+ 35*skill_lv)/100;
- div_=2;
break;
case CR_GRANDCROSS:
hitrate= 1000000;
break;
case AM_DEMONSTRATION: // デモンストレーション
+ hitrate= 1000000;
damage = damage*(100+ 20*skill_lv)/100;
damage2 = damage2*(100+ 20*skill_lv)/100;
break;
case AM_ACIDTERROR: // アシッドテラー
+ hitrate = 1000000;
damage = damage*(100+ 40*skill_lv)/100;
damage2 = damage2*(100+ 40*skill_lv)/100;
break;
case MO_FINGEROFFENSIVE: //指弾
damage = damage * (125 + 25 * skill_lv) / 100;
- div_ = 1;
flag=(flag&~BF_RANGEMASK)|BF_LONG; //orn
break;
case MO_INVESTIGATE: // 発 勁
if(def1 < 1000000)
- damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/100;
+ damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/50;
hitrate = 1000000;
s_ele = 0;
break;
@@ -2074,32 +888,30 @@ static struct Damage battle_calc_pet_weapon_attack(
break;
case MO_CHAINCOMBO: // 連打掌
damage = damage*(150+ 50*skill_lv)/100;
- div_=4;
break;
case MO_COMBOFINISH: // 猛龍拳
damage = damage*(240+ 60*skill_lv)/100;
break;
case DC_THROWARROW: // 矢撃ち
- damage = damage*(100+ 50 * skill_lv)/100;
+ damage = damage*(60+ 40 * skill_lv)/100;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case BA_MUSICALSTRIKE: // ミュージカルストライク
- damage = damage*(100+ 50 * skill_lv)/100;
+ damage = damage*(60+ 40 * skill_lv)/100;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case CH_TIGERFIST: // 伏虎拳
- damage = damage*(100+ 60*skill_lv)/100;
+ damage = damage*(40+ 100*skill_lv)/100;
break;
case CH_CHAINCRUSH: // 連柱崩撃
- damage = damage*(100+ 60*skill_lv)/100;
- div_=skill_get_num(skill_num,skill_lv);
+ damage = damage*(400+ 100*skill_lv)/100;
break;
case CH_PALMSTRIKE: // 猛虎硬派山
- damage = damage*(50+ 100*skill_lv)/100;
+ damage = damage*(200+ 100*skill_lv)/100;
break;
case LK_SPIRALPIERCE: /* スパイラルピアース */
damage = damage*(100+ 50*skill_lv)/100; //増加量が分からないので適当に
- div_=5;
+ flag=(flag&~BF_RANGEMASK)|BF_LONG;
if(target->type == BL_PC)
((struct map_session_data *)target)->canmove_tick = gettick() + 1000;
else if(target->type == BL_MOB)
@@ -2119,31 +931,35 @@ static struct Damage battle_calc_pet_weapon_attack(
break;
case CG_ARROWVULCAN: /* アローバルカン */
damage = damage*(200+100*skill_lv)/100;
- div_=9;
break;
case AS_SPLASHER: /* ベナムスプラッシャー */
damage = damage*(200+20*skill_lv)/100;
+ hitrate = 1000000;
break;
}
+ if (div_flag && div_ > 1) { // [Skotlex]
+ damage *= div_;
+ damage2 *= div_;
+ }
}
if( skill_num!=NPC_CRITICALSLASH ){
// 対 象の防御力によるダメージの減少
// ディバインプロテクション(ここでいいのかな?)
- if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && def1 < 1000000 ) { //DEF, VIT無視
+ if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000 ) { //DEF, VIT無視
int t_def;
- target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penaly_count_lv);
- if(battle_config.vit_penaly_type > 0) {
- if(target_count >= battle_config.vit_penaly_count) {
- if(battle_config.vit_penaly_type == 1) {
- def1 = (def1 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- def2 = (def2 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
+ target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv);
+ if(battle_config.vit_penalty_type > 0) {
+ if(target_count >= battle_config.vit_penalty_count) {
+ if(battle_config.vit_penalty_type == 1) {
+ 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;
+ t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
}
- else if(battle_config.vit_penaly_type == 2) {
- def1 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- def2 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- t_vit -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
+ else if(battle_config.vit_penalty_type == 2) {
+ 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;
+ t_vit -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
}
if(def1 < 0) def1 = 0;
if(def2 < 1) def2 = 1;
@@ -2168,10 +984,10 @@ static struct Damage battle_calc_pet_weapon_attack(
// 回避修正
if( hitrate < 1000000 && t_sc_data ) { // 必中攻撃
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- hitrate -= 50;
+ hitrate -= 75;
if (t_sc_data[SC_SLEEP].timer!=-1 || // 睡眠は必中
t_sc_data[SC_STAN].timer!=-1 || // スタンは必中
- t_sc_data[SC_FREEZE].timer!=-1 ||
+ t_sc_data[SC_FREEZE].timer!=-1 ||
(t_sc_data[SC_STONE].timer!=-1 && t_sc_data[SC_STONE].val2==0)) // 凍結は必中
hitrate = 1000000;
}
@@ -2184,13 +1000,13 @@ static struct Damage battle_calc_pet_weapon_attack(
dmg_lv = ATK_DEF;
}
-
+
if(t_sc_data) {
int cardfix=100;
if(t_sc_data[SC_DEFENDER].timer != -1 && flag&BF_LONG)
cardfix=cardfix*(100-t_sc_data[SC_DEFENDER].val2)/100;
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- cardfix=cardfix*(100-t_sc_data[SC_FOGWALL].val2)/100;
+ cardfix=cardfix*50/100;
if(cardfix != 100)
damage=damage*cardfix/100;
}
@@ -2198,22 +1014,22 @@ static struct Damage battle_calc_pet_weapon_attack(
// 属 性の適用
if(skill_num != 0 || s_ele != 0 || !battle_config.pet_attack_attr_none)
- damage=battle_attr_fix(damage, s_ele, battle_get_element(target) );
+ damage=battle_attr_fix(damage, s_ele, status_get_element(target) );
if(skill_num==PA_PRESSURE) /* プレッシャー 必中? */
damage = 500+300*skill_lv;
// インベナム修正
if(skill_num==TF_POISON){
- damage = battle_attr_fix(damage + 15*skill_lv, s_ele, battle_get_element(target) );
+ damage = battle_attr_fix(damage + 15*skill_lv, s_ele, status_get_element(target) );
}
if(skill_num==MC_CARTREVOLUTION){
- damage = battle_attr_fix(damage, 0, battle_get_element(target) );
+ damage = battle_attr_fix(damage, 0, status_get_element(target) );
}
// 完全回避の判定
if(battle_config.enemy_perfect_flee) {
- if(skill_num == 0 && skill_lv >= 0 && tmd!=NULL && rand()%1000 < battle_get_flee2(target) ){
+ if(skill_num == 0 && tmd!=NULL && rand()%1000 < status_get_flee2(target) ){
damage=0;
type=0x0b;
dmg_lv = ATK_LUCKY;
@@ -2231,10 +1047,10 @@ static struct Damage battle_calc_pet_weapon_attack(
wd.damage2=0;
wd.type=type;
wd.div_=div_;
- wd.amotion=battle_get_amotion(src);
+ wd.amotion=status_get_amotion(src);
if(skill_num == KN_AUTOCOUNTER)
wd.amotion >>= 1;
- wd.dmotion=battle_get_dmotion(target);
+ wd.dmotion=status_get_dmotion(target);
wd.blewcount=blewcount;
wd.flag=flag;
wd.dmg_lv=dmg_lv;
@@ -2249,16 +1065,18 @@ static struct Damage battle_calc_mob_weapon_attack(
struct mob_data* md=(struct mob_data *)src,*tmd=NULL;
int hitrate,flee,cri = 0,atkmin,atkmax;
int luk,target_count = 1;
- int def1 = battle_get_def(target);
- int def2 = battle_get_def2(target);
- int t_vit = battle_get_vit(target);
+ int def1 = status_get_def(target);
+ int def2 = status_get_def2(target);
+ int t_vit = status_get_vit(target);
struct Damage wd;
int damage,damage2=0,type,div_,blewcount=skill_get_blewcount(skill_num,skill_lv);
int flag,skill,ac_flag = 0,dmg_lv = 0;
- int t_mode=0,t_race=0,t_size=1,s_race=0,s_ele=0;
+ int t_mode=0,t_race=0,t_size=1,s_race=0,s_ele=0,s_size=0,s_race2=0;
struct status_change *sc_data,*t_sc_data;
short *sc_count;
short *option, *opt1, *opt2;
+ int div_flag=0; // 0: total damage is to be divided by div_
+ // 1: damage is distributed,and has to be multiplied by div_ [celest]
//return前の処理があるので情報出力部のみ変更
if( src == NULL || target == NULL || md == NULL ){
@@ -2267,35 +1085,37 @@ static struct Damage battle_calc_mob_weapon_attack(
return wd;
}
- s_race=battle_get_race(src);
- s_ele=battle_get_attack_element(src);
- sc_data=battle_get_sc_data(src);
- sc_count=battle_get_sc_count(src);
- option=battle_get_option(src);
- opt1=battle_get_opt1(src);
- opt2=battle_get_opt2(src);
+ s_race = status_get_race(src);
+ s_ele = status_get_attack_element(src);
+ s_size = status_get_size(src);
+ sc_data = status_get_sc_data(src);
+ sc_count = status_get_sc_count(src);
+ option = status_get_option(src);
+ opt1 = status_get_opt1(src);
+ opt2 = status_get_opt2(src);
+ s_race2 = status_get_race2(src);
// ターゲット
- if(target->type==BL_PC)
- tsd=(struct map_session_data *)target;
- else if(target->type==BL_MOB)
- tmd=(struct mob_data *)target;
- t_race=battle_get_race( target );
- t_size=battle_get_size( target );
- t_mode=battle_get_mode( target );
- t_sc_data=battle_get_sc_data( target );
-
- if((skill_num == 0 || (target->type == BL_PC && battle_config.pc_auto_counter_type&2) ||
- (target->type == BL_MOB && battle_config.monster_auto_counter_type&2)) && skill_lv >= 0) {
+ if(target->type == BL_PC)
+ tsd = (struct map_session_data *)target;
+ else if(target->type == BL_MOB)
+ tmd = (struct mob_data *)target;
+ t_race = status_get_race( target );
+ t_size = status_get_size( target );
+ t_mode = status_get_mode( target );
+ t_sc_data = status_get_sc_data( target );
+
+ if(skill_num == 0 || (target->type == BL_PC && battle_config.pc_auto_counter_type&2) ||
+ (target->type == BL_MOB && battle_config.monster_auto_counter_type&2)) {
if(skill_num != CR_GRANDCROSS && t_sc_data && t_sc_data[SC_AUTOCOUNTER].timer != -1) {
- int dir = map_calc_dir(src,target->x,target->y),t_dir = battle_get_dir(target);
+ int dir = map_calc_dir(src,target->x,target->y),t_dir = status_get_dir(target);
int dist = distance(src->x,src->y,target->x,target->y);
if(dist <= 0 || map_check_dir(dir,t_dir) ) {
memset(&wd,0,sizeof(wd));
t_sc_data[SC_AUTOCOUNTER].val3 = 0;
t_sc_data[SC_AUTOCOUNTER].val4 = 1;
if(sc_data && sc_data[SC_AUTOCOUNTER].timer == -1) {
- int range = battle_get_range(target);
+ int range = status_get_range(target);
if((target->type == BL_PC && ((struct map_session_data *)target)->status.weapon != 11 && dist <= range+1) ||
(target->type == BL_MOB && range <= 3 && dist <= range+1) )
t_sc_data[SC_AUTOCOUNTER].val3 = src->id;
@@ -2312,37 +1132,40 @@ static struct Damage battle_calc_mob_weapon_attack(
flag=BF_SHORT|BF_WEAPON|BF_NORMAL; // 攻撃の種類の設定
// 回避率計算、回避判定は後で
- flee = battle_get_flee(target);
- if(battle_config.agi_penaly_type > 0 || battle_config.vit_penaly_type > 0)
- target_count += battle_counttargeted(target,src,battle_config.agi_penaly_count_lv);
- if(battle_config.agi_penaly_type > 0) {
- if(target_count >= battle_config.agi_penaly_count) {
- if(battle_config.agi_penaly_type == 1)
- flee = (flee * (100 - (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num))/100;
- else if(battle_config.agi_penaly_type == 2)
- flee -= (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num;
+ flee = status_get_flee(target);
+ if(battle_config.agi_penalty_type > 0 || battle_config.vit_penalty_type > 0)
+ target_count += battle_counttargeted(target,src,battle_config.agi_penalty_count_lv);
+ if(battle_config.agi_penalty_type > 0) {
+ if(target_count >= battle_config.agi_penalty_count) {
+ if(battle_config.agi_penalty_type == 1)
+ flee = (flee * (100 - (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
+ else if(battle_config.agi_penalty_type == 2)
+ flee -= (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
if(flee < 1) flee = 1;
}
}
- hitrate=battle_get_hit(src) - flee + 80;
+ hitrate=status_get_hit(src) - flee + 80;
type=0; // normal
- div_ = 1; // single attack
+ if (skill_num > 0) {
+ div_ = skill_get_num(skill_num,skill_lv);
+ if (div_ < 1) div_ = 1; //Avoid the rare case where the db says div_ is 0 and below
+ } else div_ = 1; // single attack
- luk=battle_get_luk(src);
+ luk=status_get_luk(src);
if(battle_config.enemy_str)
- damage = battle_get_baseatk(src);
+ damage = status_get_baseatk(src);
else
damage = 0;
if(skill_num==HW_MAGICCRASHER){ /* マジッククラッシャーはMATKで殴る */
- atkmin = battle_get_matk1(src);
- atkmax = battle_get_matk2(src);
+ atkmin = status_get_matk1(src);
+ atkmax = status_get_matk2(src);
}else{
- atkmin = battle_get_atk(src);
- atkmax = battle_get_atk2(src);
+ atkmin = status_get_atk(src);
+ atkmax = status_get_atk2(src);
}
- if(mob_db[md->class].range>3 )
+ if(mob_db[md->class_].range>3 )
flag=(flag&~BF_RANGEMASK)|BF_LONG;
if(atkmin > atkmax) atkmin = atkmax;
@@ -2351,15 +1174,20 @@ static struct Damage battle_calc_mob_weapon_attack(
atkmin=atkmax;
}
- cri = battle_get_critical(src);
- cri -= battle_get_luk(target) * 3;
+ cri = status_get_critical(src);
+ cri -= status_get_luk(target) * 3;
if(battle_config.enemy_critical_rate != 100) {
cri = cri*battle_config.enemy_critical_rate/100;
if(cri < 1)
cri = 1;
}
- if(t_sc_data != NULL && t_sc_data[SC_SLEEP].timer!=-1 ) // 睡眠中はクリティカルが倍に
- cri <<=1;
+ if(t_sc_data) {
+ if (t_sc_data[SC_SLEEP].timer!=-1 ) // 睡眠中はクリティカルが倍に
+ cri <<=1;
+ if(t_sc_data[SC_JOINTBEAT].timer != -1 &&
+ t_sc_data[SC_JOINTBEAT].val2 == 6) // Always take crits with Neck broken by Joint Beat [DracoRPG]
+ cri = 1000;
+ }
if(ac_flag) cri = 1000;
@@ -2395,9 +1223,9 @@ static struct Damage battle_calc_mob_weapon_attack(
// ソニックブロー
if(sc_data){ //状態異常中のダメージ追加
if(sc_data[SC_OVERTHRUST].timer!=-1) // オーバートラスト
- damage += damage*(5*sc_data[SC_OVERTHRUST].val1)/100;
+ damage += damage*(5*sc_data[SC_OVERTHRUST].val1)/100;
if(sc_data[SC_TRUESIGHT].timer!=-1) // トゥルーサイト
- damage += damage*(2*sc_data[SC_TRUESIGHT].val1)/100;
+ damage += damage*(2*sc_data[SC_TRUESIGHT].val1)/100;
if(sc_data[SC_BERSERK].timer!=-1) // バーサーク
damage += damage*2;
if(sc_data && sc_data[SC_AURABLADE].timer!=-1) //[DracoRPG]
@@ -2416,14 +1244,14 @@ static struct Damage battle_calc_mob_weapon_attack(
hitrate = (hitrate*(100+5*skill_lv))/100;
break;
case SM_MAGNUM: // マグナムブレイク
- damage = damage*(5*skill_lv +(wflag)?65:115 )/100;
+ damage = damage*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100;
+ hitrate = (hitrate*(100+10*skill_lv))/100;
break;
case MC_MAMMONITE: // メマーナイト
damage = damage*(100+ 50*skill_lv)/100;
break;
case AC_DOUBLE: // ダブルストレイフィング
damage = damage*(180+ 20*skill_lv)/100;
- div_=2;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case AC_SHOWER: // アローシャワー
@@ -2436,9 +1264,9 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
case KN_PIERCE: // ピアース
damage = damage*(100+ 10*skill_lv)/100;
- hitrate=hitrate*(100+5*skill_lv)/100;
- div_=t_size+1;
- damage*=div_;
+ hitrate = hitrate*(100+5*skill_lv)/100;
+ div_ = t_size+1;
+ div_flag = 1;
break;
case KN_SPEARSTAB: // スピアスタブ
damage = damage*(100+ 15*skill_lv)/100;
@@ -2456,7 +1284,6 @@ static struct Damage battle_calc_mob_weapon_attack(
if(skill_lv>9 && wflag==2) damage2+=damage/4;
if(skill_lv>9 && wflag==3) damage2+=damage/2;
damage +=damage2;
- blewcount=0;
break;
case KN_BOWLINGBASH: // ボウリングバッシュ
damage = damage*(100+ 50*skill_lv)/100;
@@ -2470,7 +1297,7 @@ static struct Damage battle_calc_mob_weapon_attack(
flag=(flag&~BF_SKILLMASK)|BF_NORMAL;
break;
case AS_GRIMTOOTH:
- damage = damage*(100+ 20*skill_lv)/100;
+ damage = damage*(100+ 20*skill_lv)/100;
break;
case AS_POISONREACT: // celest
s_ele = 0;
@@ -2478,7 +1305,6 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
case AS_SONICBLOW: // ソニックブロウ
damage = damage*(300+ 50*skill_lv)/100;
- div_=8;
break;
case TF_SPRINKLESAND: // 砂まき
damage = damage*125/100;
@@ -2488,8 +1314,7 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
// 以下MOB
case NPC_COMBOATTACK: // 多段攻撃
- div_=skill_get_num(skill_num,skill_lv);
- damage *= div_;
+ div_flag = 1;
break;
case NPC_RANDOMATTACK: // ランダムATK攻撃
damage = damage*(50+rand()%150)/100;
@@ -2502,6 +1327,7 @@ static struct Damage battle_calc_mob_weapon_attack(
case NPC_POISONATTACK:
case NPC_HOLYATTACK:
case NPC_DARKNESSATTACK:
+ case NPC_UNDEADATTACK:
case NPC_TELEKINESISATTACK:
damage = damage*(100+25*(skill_lv-1))/100;
break;
@@ -2536,27 +1362,27 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
case CR_HOLYCROSS: // ホーリークロス
damage = damage*(100+ 35*skill_lv)/100;
- div_=2;
break;
case CR_GRANDCROSS:
hitrate= 1000000;
break;
case AM_DEMONSTRATION: // デモンストレーション
+ hitrate = 1000000;
damage = damage*(100+ 20*skill_lv)/100;
damage2 = damage2*(100+ 20*skill_lv)/100;
break;
case AM_ACIDTERROR: // アシッドテラー
+ hitrate = 1000000;
damage = damage*(100+ 40*skill_lv)/100;
damage2 = damage2*(100+ 40*skill_lv)/100;
break;
case MO_FINGEROFFENSIVE: //指弾
damage = damage * (125 + 25 * skill_lv) / 100;
- div_ = 1;
flag=(flag&~BF_RANGEMASK)|BF_LONG; //orn
break;
case MO_INVESTIGATE: // 発 勁
if(def1 < 1000000)
- damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/100;
+ damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/50;
hitrate = 1000000;
s_ele = 0;
break;
@@ -2567,32 +1393,30 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
case MO_CHAINCOMBO: // 連打掌
damage = damage*(150+ 50*skill_lv)/100;
- div_=4;
break;
case BA_MUSICALSTRIKE: // ミュージカルストライク
- damage = damage*(100+ 50 * skill_lv)/100;
+ damage = damage*(60+ 40 * skill_lv)/100;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case DC_THROWARROW: // 矢撃ち
- damage = damage*(100+ 50 * skill_lv)/100;
+ damage = damage*(60+ 40 * skill_lv)/100;
flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case MO_COMBOFINISH: // 猛龍拳
damage = damage*(240+ 60*skill_lv)/100;
break;
case CH_TIGERFIST: // 伏虎拳
- damage = damage*(100+ 20*skill_lv)/100;
+ damage = damage*(40+ 100*skill_lv)/100;
break;
case CH_CHAINCRUSH: // 連柱崩撃
- damage = damage*(100+ 60*skill_lv)/100;
- div_=skill_get_num(skill_num,skill_lv);
+ damage = damage*(400+ 100*skill_lv)/100;
break;
case CH_PALMSTRIKE: // 猛虎硬派山
- damage = damage*(50+ 100*skill_lv)/100;
+ damage = damage*(200+ 100*skill_lv)/100;
break;
case LK_SPIRALPIERCE: /* スパイラルピアース */
damage = damage*(100+ 50*skill_lv)/100; //増加量が分からないので適当に
- div_=5;
+ flag=(flag&~BF_RANGEMASK)|BF_LONG;
if(tsd)
tsd->canmove_tick = gettick() + 1000;
else if(tmd)
@@ -2612,31 +1436,35 @@ static struct Damage battle_calc_mob_weapon_attack(
break;
case CG_ARROWVULCAN: /* アローバルカン */
damage = damage*(200+100*skill_lv)/100;
- div_=9;
break;
case AS_SPLASHER: /* ベナムスプラッシャー */
damage = damage*(200+20*skill_lv)/100;
+ hitrate = 1000000;
break;
}
+ if (div_flag && div_ > 1) { // [Skotlex]
+ damage *= div_;
+ damage2 *= div_;
+ }
}
if( skill_num!=NPC_CRITICALSLASH ){
// 対 象の防御力によるダメージの減少
// ディバインプロテクション(ここでいいのかな?)
- if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && def1 < 1000000) { //DEF, VIT無視
+ if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000) { //DEF, VIT無視
int t_def;
- target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penaly_count_lv);
- if(battle_config.vit_penaly_type > 0) {
- if(target_count >= battle_config.vit_penaly_count) {
- if(battle_config.vit_penaly_type == 1) {
- def1 = (def1 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- def2 = (def2 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
+ target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv);
+ if(battle_config.vit_penalty_type > 0) {
+ if(target_count >= battle_config.vit_penalty_count) {
+ if(battle_config.vit_penalty_type == 1) {
+ 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;
+ t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
}
- else if(battle_config.vit_penaly_type == 2) {
- def1 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- def2 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- t_vit -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
+ else if(battle_config.vit_penalty_type == 2) {
+ 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;
+ t_vit -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
}
if(def1 < 0) def1 = 0;
if(def2 < 1) def2 = 1;
@@ -2644,7 +1472,7 @@ static struct Damage battle_calc_mob_weapon_attack(
}
}
t_def = def2*8/10;
- if(battle_check_undead(s_race,battle_get_elem_type(src)) || s_race==6)
+ if(battle_check_undead(s_race,status_get_elem_type(src)) || s_race==6)
if(tsd && (skill=pc_checkskill(tsd,AL_DP)) > 0 )
t_def += skill* (int) (3 + (tsd->status.base_level+1)*0.04); // submitted by orn
//t_def += skill*3;
@@ -2666,10 +1494,10 @@ static struct Damage battle_calc_mob_weapon_attack(
// 回避修正
if( hitrate < 1000000 && t_sc_data ) { // 必中攻撃
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- hitrate -= 50;
+ hitrate -= 75;
if (t_sc_data[SC_SLEEP].timer!=-1 || // 睡眠は必中
t_sc_data[SC_STAN].timer!=-1 || // スタンは必中
- t_sc_data[SC_FREEZE].timer!=-1 ||
+ t_sc_data[SC_FREEZE].timer!=-1 ||
(t_sc_data[SC_STONE].timer!=-1 && t_sc_data[SC_STONE].val2==0)) // 凍結は必中
hitrate = 1000000;
}
@@ -2686,16 +1514,24 @@ static struct Damage battle_calc_mob_weapon_attack(
int cardfix=100,i;
cardfix=cardfix*(100-tsd->subele[s_ele])/100; // 属 性によるダメージ耐性
cardfix=cardfix*(100-tsd->subrace[s_race])/100; // 種族によるダメージ耐性
- if(mob_db[md->class].mode & 0x20)
+ cardfix=cardfix*(100-tsd->subsize[s_size])/100;
+ cardfix=cardfix*(100-tsd->subrace2[s_race2])/100; // 種族によるダメージ耐性
+ if(mob_db[md->class_].mode & 0x20)
cardfix=cardfix*(100-tsd->subrace[10])/100;
else
cardfix=cardfix*(100-tsd->subrace[11])/100;
for(i=0;i<tsd->add_def_class_count;i++) {
- if(tsd->add_def_classid[i] == md->class) {
+ if(tsd->add_def_classid[i] == md->class_) {
cardfix=cardfix*(100-tsd->add_def_classrate[i])/100;
break;
}
}
+ for(i=0;i<tsd->add_damage_class_count2;i++) {
+ if(tsd->add_damage_classid2[i] == md->class_) {
+ cardfix=cardfix*(100+tsd->add_damage_classrate2[i])/100;
+ break;
+ }
+ }
if(flag&BF_LONG)
cardfix=cardfix*(100-tsd->long_attack_def_rate)/100;
if(flag&BF_SHORT)
@@ -2707,7 +1543,7 @@ static struct Damage battle_calc_mob_weapon_attack(
if(t_sc_data[SC_DEFENDER].timer != -1 && flag&BF_LONG)
cardfix=cardfix*(100-t_sc_data[SC_DEFENDER].val2)/100;
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- cardfix=cardfix*(100-t_sc_data[SC_FOGWALL].val2)/100;
+ cardfix=cardfix*50/100;
if(cardfix != 100)
damage=damage*cardfix/100;
}
@@ -2721,11 +1557,11 @@ static struct Damage battle_calc_mob_weapon_attack(
if(damage < 0) damage = 0;
// 属 性の適用
- if (!((battle_config.mob_ghostring_fix == 1) &&
- (battle_get_element(target) == 8) &&
- (target->type==BL_PC))) // [MouseJstr]
- if(skill_num != 0 || s_ele != 0 || !battle_config.mob_attack_attr_none)
- damage=battle_attr_fix(damage, s_ele, battle_get_element(target) );
+ if (!((battle_config.mob_ghostring_fix == 1) &&
+ (status_get_elem_type(target) == 8) &&
+ (target->type==BL_PC))) // [MouseJstr]
+ if(skill_num != 0 || s_ele != 0 || !battle_config.mob_attack_attr_none)
+ damage=battle_attr_fix(damage, s_ele, status_get_element(target) );
//if(sc_data && sc_data[SC_AURABLADE].timer!=-1) /* オーラブレード 必中 */
// damage += sc_data[SC_AURABLADE].val1 * 10;
@@ -2734,21 +1570,21 @@ static struct Damage battle_calc_mob_weapon_attack(
// インベナム修正
if(skill_num==TF_POISON){
- damage = battle_attr_fix(damage + 15*skill_lv, s_ele, battle_get_element(target) );
+ damage = battle_attr_fix(damage + 15*skill_lv, s_ele, status_get_element(target) );
}
if(skill_num==MC_CARTREVOLUTION){
- damage = battle_attr_fix(damage, 0, battle_get_element(target) );
+ damage = battle_attr_fix(damage, 0, status_get_element(target) );
}
// 完全回避の判定
- if(skill_num == 0 && skill_lv >= 0 && tsd!=NULL && rand()%1000 < battle_get_flee2(target) ){
+ if(skill_num == 0 && tsd!=NULL && rand()%1000 < status_get_flee2(target) ){
damage=0;
type=0x0b;
dmg_lv = ATK_LUCKY;
}
if(battle_config.enemy_perfect_flee) {
- if(skill_num == 0 && skill_lv >= 0 && tmd!=NULL && rand()%1000 < battle_get_flee2(target) ){
+ if(skill_num == 0 && tmd!=NULL && rand()%1000 < status_get_flee2(target) ){
damage=0;
type=0x0b;
dmg_lv = ATK_LUCKY;
@@ -2769,10 +1605,10 @@ static struct Damage battle_calc_mob_weapon_attack(
wd.damage2=0;
wd.type=type;
wd.div_=div_;
- wd.amotion=battle_get_amotion(src);
+ wd.amotion=status_get_amotion(src);
if(skill_num == KN_AUTOCOUNTER)
wd.amotion >>= 1;
- wd.dmotion=battle_get_dmotion(target);
+ wd.dmotion=status_get_dmotion(target);
wd.blewcount=blewcount;
wd.flag=flag;
wd.dmg_lv=dmg_lv;
@@ -2791,14 +1627,14 @@ static struct Damage battle_calc_pc_weapon_attack(
int hitrate,flee,cri = 0,atkmin,atkmax;
int dex,luk,target_count = 1;
int no_cardfix=0;
- int def1 = battle_get_def(target);
- int def2 = battle_get_def2(target);
-// int mdef1, mdef2;
- int t_vit = battle_get_vit(target);
+ int def1 = status_get_def(target);
+ int def2 = status_get_def2(target);
+ int t_vit = status_get_vit(target);
struct Damage wd;
int damage,damage2,damage3=0,damage4=0,type,div_,blewcount=skill_get_blewcount(skill_num,skill_lv);
int flag,skill,dmg_lv = 0;
- int t_mode=0,t_race=0,t_size=1,s_race=7,s_ele=0;
+ int t_mode=0,t_race=0,t_size=1,s_race=7,s_ele=0,s_size=1;
+ int t_race2=0;
struct status_change *sc_data,*t_sc_data;
short *sc_count;
short *option, *opt1, *opt2;
@@ -2806,6 +1642,8 @@ static struct Damage battle_calc_pc_weapon_attack(
int watk,watk_,cardfix,t_ele;
int da=0,i,t_class,ac_flag = 0;
int idef_flag=0,idef_flag_=0;
+ int div_flag=0; // 0: total damage is to be divided by div_
+ // 1: damage is distributed,and has to be multiplied by div_ [celest]
//return前の処理があるので情報出力部のみ変更
if( src == NULL || target == NULL || sd == NULL ){
@@ -2816,14 +1654,16 @@ static struct Damage battle_calc_pc_weapon_attack(
// アタッカー
- s_race=battle_get_race(src); //種族
- s_ele=battle_get_attack_element(src); //属性
- s_ele_=battle_get_attack_element2(src); //左手属性
- sc_data=battle_get_sc_data(src); //ステータス異常
- sc_count=battle_get_sc_count(src); //ステータス異常の数
- option=battle_get_option(src); //鷹とかペコとかカートとか
- opt1=battle_get_opt1(src); //石化、凍結、スタン、睡眠、暗闇
- opt2=battle_get_opt2(src); //毒、呪い、沈黙、暗闇?
+ s_race=status_get_race(src); //種族
+ s_ele=status_get_attack_element(src); //属性
+ s_ele_=status_get_attack_element2(src); //左手属性
+ s_size=status_get_size(src);
+ sc_data=status_get_sc_data(src); //ステータス異常
+ sc_count=status_get_sc_count(src); //ステータス異常の数
+ option=status_get_option(src); //鷹とかペコとかカートとか
+ opt1=status_get_opt1(src); //石化、凍結、スタン、睡眠、暗闇
+ opt2=status_get_opt2(src); //毒、呪い、沈黙、暗闇?
+ t_race2=status_get_race2(target);
if(skill_num != CR_GRANDCROSS) //グランドクロスでないなら
sd->state.attack_type = BF_WEAPON; //攻撃タイプは武器攻撃
@@ -2833,24 +1673,24 @@ static struct Damage battle_calc_pc_weapon_attack(
tsd=(struct map_session_data *)target; //tsdに代入(tmdはNULL)
else if(target->type==BL_MOB) //対象がMobなら
tmd=(struct mob_data *)target; //tmdに代入(tsdはNULL)
- t_race=battle_get_race( target ); //対象の種族
- t_ele=battle_get_elem_type(target); //対象の属性
- t_size=battle_get_size( target ); //対象のサイズ
- t_mode=battle_get_mode( target ); //対象のMode
- t_sc_data=battle_get_sc_data( target ); //対象のステータス異常
+ t_race=status_get_race( target ); //対象の種族
+ t_ele=status_get_elem_type(target); //対象の属性
+ t_size=status_get_size( target ); //対象のサイズ
+ t_mode=status_get_mode( target ); //対象のMode
+ t_sc_data=status_get_sc_data( target ); //対象のステータス異常
//オートカウンター処理ここから
- if((skill_num == 0 || (target->type == BL_PC && battle_config.pc_auto_counter_type&2) ||
- (target->type == BL_MOB && battle_config.monster_auto_counter_type&2)) && skill_lv >= 0) {
+ if(skill_num == 0 || (target->type == BL_PC && battle_config.pc_auto_counter_type&2) ||
+ (target->type == BL_MOB && battle_config.monster_auto_counter_type&2)) {
if(skill_num != CR_GRANDCROSS && t_sc_data && t_sc_data[SC_AUTOCOUNTER].timer != -1) { //グランドクロスでなく、対象がオートカウンター状態の場合
- int dir = map_calc_dir(src,target->x,target->y),t_dir = battle_get_dir(target);
+ int dir = map_calc_dir(src,target->x,target->y),t_dir = status_get_dir(target);
int dist = distance(src->x,src->y,target->x,target->y);
if(dist <= 0 || map_check_dir(dir,t_dir) ) { //対象との距離が0以下、または対象の正面?
memset(&wd,0,sizeof(wd));
t_sc_data[SC_AUTOCOUNTER].val3 = 0;
t_sc_data[SC_AUTOCOUNTER].val4 = 1;
if(sc_data && sc_data[SC_AUTOCOUNTER].timer == -1) { //自分がオートカウンター状態
- int range = battle_get_range(target);
+ int range = status_get_range(target);
if((target->type == BL_PC && ((struct map_session_data *)target)->status.weapon != 11 && dist <= range+1) || //対象がPCで武器が弓矢でなく射程内
(target->type == BL_MOB && range <= 3 && dist <= range+1) ) //または対象がMobで射程が3以下で射程内
t_sc_data[SC_AUTOCOUNTER].val3 = src->id;
@@ -2869,32 +1709,35 @@ static struct Damage battle_calc_pc_weapon_attack(
flag=BF_SHORT|BF_WEAPON|BF_NORMAL; // 攻撃の種類の設定
// 回避率計算、回避判定は後で
- flee = battle_get_flee(target);
- if(battle_config.agi_penaly_type > 0 || battle_config.vit_penaly_type > 0) //AGI、VITペナルティ設定が有効
- target_count += battle_counttargeted(target,src,battle_config.agi_penaly_count_lv); //対象の数を算出
- if(battle_config.agi_penaly_type > 0) {
- if(target_count >= battle_config.agi_penaly_count) { //ペナルティ設定より対象が多い
- if(battle_config.agi_penaly_type == 1) //回避率がagi_penaly_num%ずつ減少
- flee = (flee * (100 - (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num))/100;
- else if(battle_config.agi_penaly_type == 2) //回避率がagi_penaly_num分減少
- flee -= (target_count - (battle_config.agi_penaly_count - 1))*battle_config.agi_penaly_num;
+ flee = status_get_flee(target);
+ if(battle_config.agi_penalty_type > 0 || battle_config.vit_penalty_type > 0) //AGI、VITペナルティ設定が有効
+ target_count += battle_counttargeted(target,src,battle_config.agi_penalty_count_lv); //対象の数を算出
+ if(battle_config.agi_penalty_type > 0) {
+ if(target_count >= battle_config.agi_penalty_count) { //ペナルティ設定より対象が多い
+ if(battle_config.agi_penalty_type == 1) //回避率がagi_penalty_num%ずつ減少
+ flee = (flee * (100 - (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
+ else if(battle_config.agi_penalty_type == 2) //回避率がagi_penalty_num分減少
+ flee -= (target_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
if(flee < 1) flee = 1; //回避率は最低でも1
}
}
- hitrate=battle_get_hit(src) - flee + 80; //命中率計算
+ hitrate=status_get_hit(src) - flee + 80; //命中率計算
type=0; // normal
- div_ = 1; // single attack
+ if (skill_num > 0) {
+ div_=skill_get_num(skill_num,skill_lv);
+ if (div_ < 1) div_ = 1; //Avoid the rare case where the db says div_ is 0 and below
+ } else div_ = 1; // single attack
- dex=battle_get_dex(src); //DEX
- luk=battle_get_luk(src); //LUK
- watk = battle_get_atk(src); //ATK
- watk_ = battle_get_atk_(src); //ATK左手
+ dex=status_get_dex(src); //DEX
+ luk=status_get_luk(src); //LUK
+ watk = status_get_atk(src); //ATK
+ watk_ = status_get_atk_(src); //ATK左手
if(skill_num==HW_MAGICCRASHER){ /* マジッククラッシャーはMATKで殴る */
- damage = damage2 = battle_get_matk1(src); //damega,damega2初登場、base_atkの取得
+ damage = damage2 = status_get_matk1(src); //damega,damega2初登場、base_atkの取得
}else{
- damage = damage2 = battle_get_baseatk(&sd->bl); //damega,damega2初登場、base_atkの取得
+ damage = damage2 = status_get_baseatk(&sd->bl); //damega,damega2初登場、base_atkの取得
}
atkmin = atkmin_ = dex; //最低ATKはDEXで初期化?
sd->state.arrow_atk = 0; //arrow_atk初期化
@@ -2942,11 +1785,12 @@ static struct Damage battle_calc_pc_weapon_attack(
}
//三段掌
- if(skill_num == 0 && skill_lv >= 0 && (skill = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0 && sd->status.weapon <= 16 && !sd->state.arrow_atk) {
+ //if(skill_num == 0 && skill_lv >= 0 && (skill = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0 && sd->status.weapon <= 16 && !sd->state.arrow_atk) {
+ if(skill_num == 0 && (skill = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0 && sd->status.weapon <= 16) { // triple blow works with bows ^^ [celest]
da = (rand()%100 < (30 - skill)) ? 2:0;
}
- if(sd->double_rate > 0 && da == 0 && skill_num == 0 && skill_lv >= 0)
+ if(sd->double_rate > 0 && da == 0 && skill_num == 0)
da = (rand()%100 < sd->double_rate) ? 1:0;
// 過剰精錬ボーナス
@@ -2957,16 +1801,22 @@ static struct Damage battle_calc_pc_weapon_attack(
if(da == 0){ //ダブルアタックが発動していない
// クリティカル計算
- cri = battle_get_critical(src);
+ cri = status_get_critical(src);
+ cri += sd->critaddrace[t_race];
if(sd->state.arrow_atk)
cri += sd->arrow_cri;
if(sd->status.weapon == 16)
// カタールの場合、クリティカルを倍に
cri <<=1;
- cri -= battle_get_luk(target) * 3;
- if(t_sc_data != NULL && t_sc_data[SC_SLEEP].timer!=-1 ) // 睡眠中はクリティカルが倍に
- cri <<=1;
+ cri -= status_get_luk(target) * 3;
+ if(t_sc_data) {
+ if (t_sc_data[SC_SLEEP].timer!=-1 ) // 睡眠中はクリティカルが倍に
+ cri <<=1;
+ if(t_sc_data[SC_JOINTBEAT].timer != -1 &&
+ t_sc_data[SC_JOINTBEAT].val2 == 6) // Always take crits with Neck broken by Joint Beat [DracoRPG]
+ cri = 1000;
+ }
if(ac_flag) cri = 1000;
if(skill_num == KN_AUTOCOUNTER) {
@@ -2975,25 +1825,29 @@ static struct Damage battle_calc_pc_weapon_attack(
else
cri <<= 1;
}
-
- if(skill_num == SN_SHARPSHOOTING && rand()%100 < 50)
+ if(skill_num == SN_SHARPSHOOTING)
cri += 200;
}
if(tsd && tsd->critical_def)
cri = cri * (100-tsd->critical_def) / 100;
- if(da == 0 && (skill_num==0 || skill_num == KN_AUTOCOUNTER || skill_num == SN_SHARPSHOOTING) && skill_lv >= 0 && //ダブルアタックが発動していない
+ if(da == 0 && (skill_num==0 || skill_num == KN_AUTOCOUNTER || skill_num == SN_SHARPSHOOTING) && //ダブルアタックが発動していない
(rand() % 1000) < cri) // 判定(スキルの場合は無視)
{
damage += atkmax;
damage2 += atkmax_;
- if(sd->atk_rate != 100) {
- damage = (damage * sd->atk_rate)/100;
- damage2 = (damage2 * sd->atk_rate)/100;
+ if(sd->atk_rate != 100 || sd->weapon_atk_rate != 0) {
+ if (sd->status.weapon < 16) {
+ damage = (damage * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100;
+ damage2 = (damage2 * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100;
+ }
}
if(sd->state.arrow_atk)
damage += sd->arrow_atk;
+
+ damage += damage * sd->crit_atk_rate / 100;
+
type = 0x0a;
/* if(def1 < 1000000) {
@@ -3038,9 +1892,11 @@ static struct Damage battle_calc_pc_weapon_attack(
damage2 += atkmin_ + rand() % (atkmax_-atkmin_ + 1);
else
damage2 += atkmin_ ;
- if(sd->atk_rate != 100) {
- damage = (damage * sd->atk_rate)/100;
- damage2 = (damage2 * sd->atk_rate)/100;
+ if(sd->atk_rate != 100 || sd->weapon_atk_rate != 0) {
+ if (sd->status.weapon < 16) {
+ damage = (damage * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100;
+ damage2 = (damage2 * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100;
+ }
}
if(sd->state.arrow_atk) {
@@ -3119,8 +1975,10 @@ static struct Damage battle_calc_pc_weapon_attack(
hitrate = (hitrate*(100+5*skill_lv))/100;
break;
case SM_MAGNUM: // マグナムブレイク
- damage = damage*(5*skill_lv +(wflag)?65:115 )/100;
- damage2 = damage2*(5*skill_lv +(wflag)?65:115 )/100;
+ // 20*skill level+100? i think this will do for now [based on jRO info]
+ damage = damage*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100;
+ damage2 = damage2*(wflag > 1 ? 5*skill_lv+115 : 30*skill_lv+100)/100;
+ hitrate = (hitrate*(100+10*skill_lv))/100;
break;
case MC_MAMMONITE: // メマーナイト
damage = damage*(100+ 50*skill_lv)/100;
@@ -3134,7 +1992,6 @@ static struct Damage battle_calc_pc_weapon_attack(
}
damage = damage*(180+ 20*skill_lv)/100;
damage2 = damage2*(180+ 20*skill_lv)/100;
- div_=2;
if(sd->arrow_ele > 0) {
s_ele = sd->arrow_ele;
s_ele_ = sd->arrow_ele;
@@ -3177,12 +2034,12 @@ static struct Damage battle_calc_pc_weapon_attack(
damage2 = damage2*(100+ 10*skill_lv)/100;
hitrate=hitrate*(100+5*skill_lv)/100;
div_=t_size+1;
- damage*=div_;
- damage2*=div_;
+ div_flag=1;
break;
case KN_SPEARSTAB: // スピアスタブ
damage = damage*(100+ 15*skill_lv)/100;
damage2 = damage2*(100+ 15*skill_lv)/100;
+ blewcount=0;
break;
case KN_SPEARBOOMERANG: // スピアブーメラン
damage = damage*(100+ 50*skill_lv)/100;
@@ -3206,7 +2063,6 @@ static struct Damage battle_calc_pc_weapon_attack(
if(skill_lv>9 && wflag==2) damage4+=damage2/4;
if(skill_lv>9 && wflag==3) damage4+=damage2/2;
damage2 +=damage4;
- blewcount=0;
break;
case KN_BOWLINGBASH: // ボウリングバッシュ
damage = damage*(100+ 50*skill_lv)/100;
@@ -3233,7 +2089,6 @@ static struct Damage battle_calc_pc_weapon_attack(
hitrate+=30; // hitrate +30, thanks to midas
damage = damage*(300+ 50*skill_lv)/100;
damage2 = damage2*(300+ 50*skill_lv)/100;
- div_=8;
break;
case TF_SPRINKLESAND: // 砂まき
damage = damage*125/100;
@@ -3241,8 +2096,10 @@ static struct Damage battle_calc_pc_weapon_attack(
break;
case MC_CARTREVOLUTION: // カートレボリューション
if(sd->cart_max_weight > 0 && sd->cart_weight > 0) {
- damage = (damage*(150 + pc_checkskill(sd,BS_WEAPONRESEARCH) + (sd->cart_weight*100/sd->cart_max_weight) ) )/100;
- damage2 = (damage2*(150 + pc_checkskill(sd,BS_WEAPONRESEARCH) + (sd->cart_weight*100/sd->cart_max_weight) ) )/100;
+ damage = ( damage*(150 + sd->cart_weight/800) )/100; //fixed CARTREV damage [Lupus] // should be 800, not 80... weight is *10 ^_- [celest]
+ damage2 = ( damage2*(150 + sd->cart_weight/800) )/100;
+ //damage = (damage*(150 + pc_checkskill(sd,BS_WEAPONRESEARCH) + (sd->cart_weight*100/sd->cart_max_weight) ) )/100;
+ //damage2 = (damage2*(150 + pc_checkskill(sd,BS_WEAPONRESEARCH) + (sd->cart_weight*100/sd->cart_max_weight) ) )/100;
}
else {
damage = (damage*150)/100;
@@ -3251,9 +2108,7 @@ static struct Damage battle_calc_pc_weapon_attack(
break;
// 以下MOB
case NPC_COMBOATTACK: // 多段攻撃
- div_=skill_get_num(skill_num,skill_lv);
- damage *= div_;
- damage2 *= div_;
+ div_flag=1;
break;
case NPC_RANDOMATTACK: // ランダムATK攻撃
damage = damage*(50+rand()%150)/100;
@@ -3267,6 +2122,7 @@ static struct Damage battle_calc_pc_weapon_attack(
case NPC_POISONATTACK:
case NPC_HOLYATTACK:
case NPC_DARKNESSATTACK:
+ case NPC_UNDEADATTACK:
case NPC_TELEKINESISATTACK:
damage = damage*(100+25*skill_lv)/100;
damage2 = damage2*(100+25*skill_lv)/100;
@@ -3313,7 +2169,6 @@ static struct Damage battle_calc_pc_weapon_attack(
case CR_HOLYCROSS: // ホーリークロス
damage = damage*(100+ 35*skill_lv)/100;
damage2 = damage2*(100+ 35*skill_lv)/100;
- div_=2;
break;
case CR_GRANDCROSS:
hitrate= 1000000;
@@ -3324,28 +2179,30 @@ static struct Damage battle_calc_pc_weapon_attack(
case AM_DEMONSTRATION: // デモンストレーション
damage = damage*(100+ 20*skill_lv)/100;
damage2 = damage2*(100+ 20*skill_lv)/100;
+ no_cardfix = 1;
break;
case AM_ACIDTERROR: // アシッドテラー
+ hitrate = 1000000;
damage = damage*(100+ 40*skill_lv)/100;
damage2 = damage2*(100+ 40*skill_lv)/100;
+ s_ele = 0;
+ s_ele_ = 0;
+ no_cardfix = 1;
break;
case MO_FINGEROFFENSIVE: //指弾
+ damage = damage * (125 + 25 * skill_lv) / 100;
+ damage2 = damage2 * (125 + 25 * skill_lv) / 100;
if(battle_config.finger_offensive_type == 0) {
- damage = damage * (125 + 25 * skill_lv) / 100 * sd->spiritball_old;
- damage2 = damage2 * (125 + 25 * skill_lv) / 100 * sd->spiritball_old;
div_ = sd->spiritball_old;
+ div_flag = 1;
}
- else {
- damage = damage * (125 + 25 * skill_lv) / 100;
- damage2 = damage2 * (125 + 25 * skill_lv) / 100;
- div_ = 1;
- }
+ else div_ = 1;
flag=(flag&~BF_RANGEMASK)|BF_LONG; //orn
break;
case MO_INVESTIGATE: // 発 勁
if(def1 < 1000000) {
- damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/100;
- damage2 = damage2*(100+ 75*skill_lv)/100 * (def1 + def2)/100;
+ damage = damage*(100+ 75*skill_lv)/100 * (def1 + def2)/50;
+ damage2 = damage2*(100+ 75*skill_lv)/100 * (def1 + def2)/50;
}
hitrate = 1000000;
s_ele = 0;
@@ -3363,26 +2220,19 @@ static struct Damage battle_calc_pc_weapon_attack(
case MO_CHAINCOMBO: // 連打掌
damage = damage*(150+ 50*skill_lv)/100;
damage2 = damage2*(150+ 50*skill_lv)/100;
- div_=4;
break;
case MO_COMBOFINISH: // 猛龍拳
damage = damage*(240+ 60*skill_lv)/100;
damage2 = damage2*(240+ 60*skill_lv)/100;
break;
case BA_MUSICALSTRIKE: // ミュージカルストライク
- if(!sd->state.arrow_atk && sd->arrow_atk > 0) {
- int arr = rand()%(sd->arrow_atk+1);
- damage += arr;
- damage2 += arr;
- }
- damage = damage*(100+ 50 * skill_lv)/100;
- damage2 = damage2*(100+ 50 * skill_lv)/100;
+ damage = damage*(60+ 40 * skill_lv)/100;
+ damage2 = damage2*(60+ 40 * skill_lv)/100;
if(sd->arrow_ele > 0) {
s_ele = sd->arrow_ele;
s_ele_ = sd->arrow_ele;
}
flag=(flag&~BF_RANGEMASK)|BF_LONG;
- sd->state.arrow_atk = 1;
break;
case DC_THROWARROW: // 矢撃ち
if(!sd->state.arrow_atk && sd->arrow_atk > 0) {
@@ -3400,22 +2250,21 @@ static struct Damage battle_calc_pc_weapon_attack(
sd->state.arrow_atk = 1;
break;
case CH_TIGERFIST: // 伏虎拳
- damage = damage*(100+ 20*skill_lv)/100;
- damage2 = damage2*(100+ 20*skill_lv)/100;
+ damage = damage*(40+ 100*skill_lv)/100;
+ damage2 = damage*(40+ 100*skill_lv)/100;
break;
case CH_CHAINCRUSH: // 連柱崩撃
- damage = damage*(100+ 60*skill_lv)/100;
- damage2 = damage2*(100+ 60*skill_lv)/100;
- div_=skill_get_num(skill_num,skill_lv);
+ damage = damage*(400+ 100*skill_lv)/100;
+ damage2 = damage*(400+ 100*skill_lv)/100;
break;
case CH_PALMSTRIKE: // 猛虎硬派山
- damage = damage*(50+ 100*skill_lv)/100;
- damage2 = damage2*(50+ 100*skill_lv)/100;
+ damage = damage*(200+ 100*skill_lv)/100;
+ damage2 = damage*(200+ 100*skill_lv)/100;
break;
case LK_SPIRALPIERCE: /* スパイラルピアース */
damage = damage*(100+ 50*skill_lv)/100; //増加量が分からないので適当に
damage2 = damage2*(100+ 50*skill_lv)/100; //増加量が分からないので適当に
- div_=5;
+ flag=(flag&~BF_RANGEMASK)|BF_LONG;
if(tsd)
tsd->canmove_tick = gettick() + 1000;
else if(tmd)
@@ -3441,35 +2290,33 @@ static struct Damage battle_calc_pc_weapon_attack(
case CG_ARROWVULCAN: /* アローバルカン */
damage = damage*(200+100*skill_lv)/100;
damage2 = damage2*(200+100*skill_lv)/100;
- div_=9;
+ if(sd->arrow_ele > 0) {
+ s_ele = sd->arrow_ele;
+ s_ele_ = sd->arrow_ele;
+ }
+ flag=(flag&~BF_RANGEMASK)|BF_LONG;
break;
case AS_SPLASHER: /* ベナムスプラッシャー */
damage = damage*(200+20*skill_lv+20*pc_checkskill(sd,AS_POISONREACT))/100;
damage2 = damage2*(200+20*skill_lv+20*pc_checkskill(sd,AS_POISONREACT))/100;
- break;
- case PA_SACRIFICE:
- if(sd){
- int hp, mhp, damage3;
- hp = battle_get_hp(src);
- mhp = battle_get_max_hp(src);
- damage3 = mhp*9/100;
- damage = damage*damage3*(90+10*skill_lv)/10000;
- damage2 = damage2*damage3*(90+10*skill_lv)/10000;
- }
+ no_cardfix = 1;
+ hitrate = 1000000;
break;
case ASC_BREAKER: // -- moonsoul (special damage for ASC_BREAKER skill)
if(sd){
- int damage3;
- int mdef1=battle_get_mdef(target);
- int mdef2=battle_get_mdef2(target);
- int imdef_flag=0;
-
- damage = ((damage * 5) + (skill_lv * battle_get_int(src) * 5) + rand()%500 + 500) /2;
- damage2 = ((damage2 * 5) + (skill_lv * battle_get_int(src) * 5) + rand()%500 + 500) /2;
- damage3 = damage;
- hitrate = 1000000;
-
- if(sd->ignore_mdef_ele & (1<<t_ele) || sd->ignore_mdef_race & (1<<t_race))
+ // calculate physical part of damage
+#ifndef TWILIGHT
+ damage = damage * skill_lv;
+ damage2 = damage2 * skill_lv;
+#else /* TWILIGHT */
+ damage = damage * skill_lv * 0.5; //Halved by Krel
+ damage2 = damage2 * skill_lv * 0.5; //Halved by Krel
+ // element modifier added right after this
+
+ // calculate magic part of damage
+ damage3 = skill_lv * status_get_int(src) * 5 * 0.5; //Krel
+ // ignores magic defense now [Celest]
+ /*if(sd->ignore_mdef_ele & (1<<t_ele) || sd->ignore_mdef_race & (1<<t_race))
imdef_flag = 1;
if(t_mode & 0x20) {
if(sd->ignore_mdef_race & (1<<10))
@@ -3487,14 +2334,23 @@ static struct Damage battle_calc_pc_weapon_attack(
damage3 = (damage3*(100-mdef1))/100 - mdef2;
}
}
-
+
if(damage3<1)
damage3=1;
- damage3=battle_attr_fix(damage2,s_ele_, battle_get_element(target) );
+ damage3=battle_attr_fix(damage2,s_ele_, status_get_element(target) );*/
+
+#endif /* TWILIGHT */
+ flag=(flag&~BF_RANGEMASK)|BF_LONG;
}
break;
}
+ if (div_flag && div_ > 1) { // [Skotlex]
+ damage *= div_;
+ damage2 *= div_;
+ }
+ if (sd && skill_num > 0 && sd->skillatk[0] == skill_num)
+ damage += damage*sd->skillatk[1]/100;
}
if(da == 2) { //三段掌が発動しているか
type = 0x08;
@@ -3505,20 +2361,20 @@ static struct Damage battle_calc_pc_weapon_attack(
if( skill_num!=NPC_CRITICALSLASH ){
// 対 象の防御力によるダメージの減少
// ディバインプロテクション(ここでいいのかな?)
- if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && def1 < 1000000) { //DEF, VIT無視
+ if ( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST && skill_num != KN_AUTOCOUNTER && skill_num != AM_ACIDTERROR && def1 < 1000000) { //DEF, VIT無視
int t_def;
- target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penaly_count_lv);
- if(battle_config.vit_penaly_type > 0) {
- if(target_count >= battle_config.vit_penaly_count) {
- if(battle_config.vit_penaly_type == 1) {
- def1 = (def1 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- def2 = (def2 * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
- t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num))/100;
+ target_count = 1 + battle_counttargeted(target,src,battle_config.vit_penalty_count_lv);
+ if(battle_config.vit_penalty_type > 0) {
+ if(target_count >= battle_config.vit_penalty_count) {
+ if(battle_config.vit_penalty_type == 1) {
+ 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;
+ t_vit = (t_vit * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
}
- else if(battle_config.vit_penaly_type == 2) {
- def1 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- def2 -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
- t_vit -= (target_count - (battle_config.vit_penaly_count - 1))*battle_config.vit_penaly_num;
+ else if(battle_config.vit_penalty_type == 2) {
+ 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;
+ t_vit -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
}
if(def1 < 0) def1 = 0;
if(def2 < 1) def2 = 1;
@@ -3527,6 +2383,19 @@ static struct Damage battle_calc_pc_weapon_attack(
}
t_def = def2*8/10;
vitbonusmax = (t_vit/20)*(t_vit/20)-1;
+ if (tmd) {
+ if(t_mode & 0x20) {
+ if(sd->ignore_def_mob & 2)
+ idef_flag = 1;
+ if(sd->ignore_def_mob_ & 2)
+ idef_flag_ = 1;
+ } else {
+ if(sd->ignore_def_mob & 1)
+ idef_flag = 1;
+ if(sd->ignore_def_mob_ & 1)
+ idef_flag_ = 1;
+ }
+ }
if(sd->ignore_def_ele & (1<<t_ele) || sd->ignore_def_race & (1<<t_race))
idef_flag = 1;
if(sd->ignore_def_ele_ & (1<<t_ele) || sd->ignore_def_race_ & (1<<t_race))
@@ -3567,24 +2436,39 @@ static struct Damage battle_calc_pc_weapon_attack(
// 状態異常中のダメージ追加でクリティカルにも有効なスキル
if (sc_data) {
// エンチャントデッドリーポイズン
- if(sc_data[SC_EDP].timer != -1) {
+ if(!no_cardfix && sc_data[SC_EDP].timer != -1 && skill_num != ASC_BREAKER && skill_num != ASC_METEORASSAULT) {
damage += damage * (150 + sc_data[SC_EDP].val1 * 50) / 100;
- damage2 += damage2 * (150 + sc_data[SC_EDP].val1 * 50) / 100;
no_cardfix = 1;
}
+ // sacrifice works on boss monsters, and does 9% damage to self [Celest]
+ if (!skill_num && /*!(t_mode&0x20) &&*/ sc_data[SC_SACRIFICE].timer != -1) {
+ int mhp = status_get_max_hp(src);
+ int dmg = mhp * 9/100;
+ pc_heal(sd, -dmg, 0);
+ damage = dmg * (90 + sc_data[SC_SACRIFICE].val1 * 10) / 100;
+ damage2 = 0;
+ hitrate = 1000000;
+ s_ele = 0;
+ s_ele_ = 0;
+ skill_num = PA_SACRIFICE;
+ //clif_skill_nodamage(src,target,skill_num,skill_lv,1); // this doesn't show effect either.. hmm =/
+ sc_data[SC_SACRIFICE].val2 --;
+ if (sc_data[SC_SACRIFICE].val2 == 0)
+ status_change_end(src, SC_SACRIFICE,-1);
+ }
}
// 精錬ダメージの追加
if( skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST) { //DEF, VIT無視
- damage += battle_get_atk2(src);
- damage2 += battle_get_atk_2(src);
+ damage += status_get_atk2(src);
+ damage2 += status_get_atk_2(src);
}
if(skill_num == CR_SHIELDBOOMERANG) {
if(sd->equip_index[8] >= 0) {
int index = sd->equip_index[8];
if(sd->inventory_data[index] && sd->inventory_data[index]->type == 5) {
damage += sd->inventory_data[index]->weight/10;
- damage += sd->status.inventory[index].refine * pc_getrefinebonus(0,1);
+ damage += sd->status.inventory[index].refine * status_getrefinebonus(0,1);
}
}
}
@@ -3593,7 +2477,7 @@ static struct Damage battle_calc_pc_weapon_attack(
int index = sd->equip_index[9];
if(sd->inventory_data[index] && sd->inventory_data[index]->type == 4) {
damage += (int)(double)(sd->inventory_data[index]->weight*(0.8*skill_lv*4/10));
- damage += sd->status.inventory[index].refine * pc_getrefinebonus(0,1);
+ damage += sd->status.inventory[index].refine * status_getrefinebonus(0,1);
}
}
}
@@ -3617,10 +2501,10 @@ static struct Damage battle_calc_pc_weapon_attack(
// 回避修正
if( hitrate < 1000000 && t_sc_data ) { // 必中攻撃
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- hitrate -= 50;
+ hitrate -= 75;
if (t_sc_data[SC_SLEEP].timer!=-1 || // 睡眠は必中
t_sc_data[SC_STAN].timer!=-1 || // スタンは必中
- t_sc_data[SC_FREEZE].timer!=-1 ||
+ t_sc_data[SC_FREEZE].timer!=-1 ||
(t_sc_data[SC_STONE].timer!=-1 && t_sc_data[SC_STONE].val2==0)) // 凍結は必中
hitrate = 1000000;
}
@@ -3653,17 +2537,20 @@ static struct Damage battle_calc_pc_weapon_attack(
cardfix=cardfix*(100+sd->addrace[t_race])/100; // 種族によるダメージ修正
cardfix=cardfix*(100+sd->addele[t_ele])/100; // 属性によるダメージ修正
cardfix=cardfix*(100+sd->addsize[t_size])/100; // サイズによるダメージ修正
+ cardfix=cardfix*(100+sd->addrace2[t_race2])/100;
}
else {
cardfix=cardfix*(100+sd->addrace[t_race]+sd->addrace_[t_race])/100; // 種族によるダメージ修正(左手による追加あり)
cardfix=cardfix*(100+sd->addele[t_ele]+sd->addele_[t_ele])/100; // 属性によるダメージ修正(左手による追加あり)
cardfix=cardfix*(100+sd->addsize[t_size]+sd->addsize_[t_size])/100; // サイズによるダメージ修正(左手による追加あり)
+ cardfix=cardfix*(100+sd->addrace2[t_race2]+sd->addrace2_[t_race2])/100;
}
}
else { //弓矢
cardfix=cardfix*(100+sd->addrace[t_race]+sd->arrow_addrace[t_race])/100; // 種族によるダメージ修正(弓矢による追加あり)
cardfix=cardfix*(100+sd->addele[t_ele]+sd->arrow_addele[t_ele])/100; // 属性によるダメージ修正(弓矢による追加あり)
cardfix=cardfix*(100+sd->addsize[t_size]+sd->arrow_addsize[t_size])/100; // サイズによるダメージ修正(弓矢による追加あり)
+ cardfix=cardfix*(100+sd->addrace2[t_race2])/100;
}
if(t_mode & 0x20) { //ボス
if(!sd->state.arrow_atk) { //弓矢攻撃以外なら
@@ -3686,7 +2573,7 @@ static struct Damage battle_calc_pc_weapon_attack(
cardfix=cardfix*(100+sd->addrace[11]+sd->arrow_addrace[11])/100; //ボス以外モンスターに追加ダメージ(弓矢による追加あり)
}
//特定Class用補正処理(少女の日記→ボンゴン用?)
- t_class = battle_get_class(target);
+ t_class = status_get_class(target);
for(i=0;i<sd->add_damage_class_count;i++) {
if(sd->add_damage_classid[i] == t_class) {
cardfix=cardfix*(100+sd->add_damage_classrate[i])/100;
@@ -3703,6 +2590,7 @@ static struct Damage battle_calc_pc_weapon_attack(
cardfix=cardfix*(100+sd->addrace_[t_race])/100; // 種族によるダメージ修正左手
cardfix=cardfix*(100+sd->addele_[t_ele])/100; // 属 性によるダメージ修正左手
cardfix=cardfix*(100+sd->addsize_[t_size])/100; // サイズによるダメージ修正左手
+ cardfix=cardfix*(100+sd->addrace2_[t_race2])/100;
if(t_mode & 0x20) //ボス
cardfix=cardfix*(100+sd->addrace_[10])/100; //ボスモンスターに追加ダメージ左手
else
@@ -3716,27 +2604,24 @@ static struct Damage battle_calc_pc_weapon_attack(
}
}
if(!no_cardfix)
-
damage2=damage2*cardfix/100;
+
//カード補正による左手ダメージ増加
//カードによるダメージ増加処理(左手)ここまで
-// -- moonsoul (cardfix for magic damage portion of ASC_BREAKER)
- if(skill_num == ASC_BREAKER)
- damage3 = damage3 * cardfix / 100;
-
//カードによるダメージ減衰処理ここから
if(tsd){ //対象がPCの場合
cardfix=100;
cardfix=cardfix*(100-tsd->subrace[s_race])/100; // 種族によるダメージ耐性
cardfix=cardfix*(100-tsd->subele[s_ele])/100; // 属性によるダメージ耐性
- if(battle_get_mode(src) & 0x20)
+ cardfix=cardfix*(100-tsd->subsize[s_size])/100;
+ if(status_get_mode(src) & 0x20)
cardfix=cardfix*(100-tsd->subrace[10])/100; //ボスからの攻撃はダメージ減少
else
cardfix=cardfix*(100-tsd->subrace[11])/100; //ボス以外からの攻撃はダメージ減少
//特定Class用補正処理左手(少女の日記→ボンゴン用?)
for(i=0;i<tsd->add_def_class_count;i++) {
- if(tsd->add_def_classid[i] == sd->status.class) {
+ if(tsd->add_def_classid[i] == sd->status.class_) {
cardfix=cardfix*(100-tsd->add_def_classrate[i])/100;
break;
}
@@ -3756,29 +2641,29 @@ static struct Damage battle_calc_pc_weapon_attack(
if(t_sc_data[SC_DEFENDER].timer != -1 && flag&BF_LONG) //ディフェンダー状態で遠距離攻撃
cardfix=cardfix*(100-t_sc_data[SC_DEFENDER].val2)/100; //ディフェンダーによる減衰
if(t_sc_data[SC_FOGWALL].timer != -1 && flag&BF_LONG)
- cardfix=cardfix*(100-t_sc_data[SC_FOGWALL].val2)/100;
+ cardfix=cardfix*50/100;
if(cardfix != 100) {
damage=damage*cardfix/100; //ディフェンダー補正によるダメージ減少
damage2=damage2*cardfix/100; //ディフェンダー補正による左手ダメージ減少
}
if(t_sc_data[SC_ASSUMPTIO].timer != -1){ //アスムプティオ
if(!map[target->m].flag.pvp){
- damage=damage/3;
- damage2=damage2/3;
- }else{
- damage=damage/2;
- damage2=damage2/2;
+ damage=damage/3;
+ damage2=damage2/3;
+ }else{
+ damage=damage/2;
+ damage2=damage2/2;
+ }
}
}
- }
//対象にステータス異常がある場合のダメージ減算処理ここまで
if(damage < 0) damage = 0;
if(damage2 < 0) damage2 = 0;
// 属 性の適用
- damage=battle_attr_fix(damage,s_ele, battle_get_element(target) );
- damage2=battle_attr_fix(damage2,s_ele_, battle_get_element(target) );
+ damage=battle_attr_fix(damage,s_ele, status_get_element(target) );
+ damage2=battle_attr_fix(damage2,s_ele_, status_get_element(target) );
// 星のかけら、気球の適用
damage += sd->star;
@@ -3797,16 +2682,16 @@ static struct Damage battle_calc_pc_weapon_attack(
// >二刀流の左右ダメージ計算誰かやってくれぇぇぇぇえええ!
// >map_session_data に左手ダメージ(atk,atk2)追加して
- // >pc_calcstatus()でやるべきかな?
+ // >status_calc_pc()でやるべきかな?
// map_session_data に左手武器(atk,atk2,ele,star,atkmods)追加して
- // pc_calcstatus()でデータを入力しています
+ // status_calc_pc()でデータを入力しています
//左手のみ武器装備
if(sd->weapontype1 == 0 && sd->weapontype2 > 0) {
damage = damage2;
damage2 = 0;
}
-
+
// 右手、左手修練の適用
if(sd->status.weapon > 16) {// 二刀流か?
int dmg = damage, dmg2 = damage2;
@@ -3838,14 +2723,14 @@ static struct Damage battle_calc_pc_weapon_attack(
// インベナム修正
if(skill_num==TF_POISON){
- damage = battle_attr_fix(damage + 15*skill_lv, s_ele, battle_get_element(target) );
+ damage = battle_attr_fix(damage + 15*skill_lv, s_ele, status_get_element(target) );
}
if(skill_num==MC_CARTREVOLUTION){
- damage = battle_attr_fix(damage, 0, battle_get_element(target) );
+ damage = battle_attr_fix(damage, 0, status_get_element(target) );
}
// 完全回避の判定
- if(skill_num == 0 && skill_lv >= 0 && tsd!=NULL && div_ < 255 && rand()%1000 < battle_get_flee2(target) ){
+ if(skill_num == 0 && tsd!=NULL && div_ < 255 && rand()%1000 < status_get_flee2(target) ){
damage=damage2=0;
type=0x0b;
dmg_lv = ATK_LUCKY;
@@ -3853,7 +2738,7 @@ static struct Damage battle_calc_pc_weapon_attack(
// 対象が完全回避をする設定がONなら
if(battle_config.enemy_perfect_flee) {
- if(skill_num == 0 && skill_lv >= 0 && tmd!=NULL && div_ < 255 && rand()%1000 < battle_get_flee2(target) ) {
+ if(skill_num == 0 && tmd!=NULL && div_ < 255 && rand()%1000 < status_get_flee2(target) ) {
damage=damage2=0;
type=0x0b;
dmg_lv = ATK_LUCKY;
@@ -3921,21 +2806,14 @@ static struct Damage battle_calc_pc_weapon_attack(
}
}
-
-// -- moonsoul (final combination of phys, mag damage for ASC_BREAKER)
- if(skill_num == ASC_BREAKER) {
- damage += damage3;
- damage2 += damage3;
- }
-
wd.damage=damage;
wd.damage2=damage2;
wd.type=type;
wd.div_=div_;
- wd.amotion=battle_get_amotion(src);
+ wd.amotion=status_get_amotion(src);
if(skill_num == KN_AUTOCOUNTER)
wd.amotion >>= 1;
- wd.dmotion=battle_get_dmotion(target);
+ wd.dmotion=status_get_dmotion(target);
wd.blewcount=blewcount;
wd.flag=flag;
wd.dmg_lv=dmg_lv;
@@ -3972,32 +2850,45 @@ struct Damage battle_calc_weapon_attack(
memset(&wd,0,sizeof(wd));
if(battle_config.equipment_breaking && src->type==BL_PC && (wd.damage > 0 || wd.damage2 > 0)) {
- struct map_session_data *sd=(struct map_session_data *)src;
- int breakrate=1;
- if(sd->status.weapon && sd->status.weapon!=11) {
- if(target->type == BL_PC && sd->sc_data[SC_MELTDOWN].timer!=-1){
- breakrate+=100*sd->sc_data[SC_MELTDOWN].val1;
- if(rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000)
- pc_breakweapon((struct map_session_data *)target);
+ struct map_session_data *sd = (struct map_session_data *)src;
+ // weapon = 0, armor = 1
+ int breakrate = 1; //0.01% default self weapon breaking chance [DracoRPG]
+ int breakrate_[2] = {0,0}; //enemy breaking chance [celest]
+ int breaktime = 5000;
+
+ breakrate_[0] += sd->break_weapon_rate;
+ breakrate_[1] += sd->break_armor_rate;
+
+ if (sd->sc_count) {
+ if (sd->sc_data[SC_MELTDOWN].timer!=-1) {
+ breakrate_[0] += 100*sd->sc_data[SC_MELTDOWN].val1;
+ breakrate_[1] = 70*sd->sc_data[SC_MELTDOWN].val1;
+ breaktime = skill_get_time2(WS_MELTDOWN,1);
}
if(sd->sc_data[SC_OVERTHRUST].timer!=-1)
- breakrate+=20*sd->sc_data[SC_OVERTHRUST].val1;
- if(wd.type==0x0a)
- breakrate*=2;
- if(rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) {
- if(pc_breakweapon(sd)==1)
+ breakrate += 10;
+ }
+
+ if(sd->status.weapon && sd->status.weapon != 11) {
+ if(rand() % 10000 < breakrate * battle_config.equipment_break_rate / 100 || breakrate >= 10000)
+ if (pc_breakweapon(sd) == 1)
wd = battle_calc_pc_weapon_attack(src,target,skill_num,skill_lv,wflag);
- }
}
- }
-
- if (battle_config.equipment_breaking && target->type == BL_PC && (wd.damage > 0 || wd.damage2 > 0)) {
- int breakrate=1;
- if(src->type==BL_PC && ((struct map_session_data *)src)->sc_data[SC_MELTDOWN].timer!=-1) breakrate+=70*((struct map_session_data *)src)->sc_data[SC_MELTDOWN].val1;
- if (wd.type==0x0a)
- breakrate*=2;
- if (rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) {
- pc_breakarmor((struct map_session_data *)target);
+ if(rand() % 10000 < breakrate_[0] * battle_config.equipment_break_rate / 100 || breakrate_[0] >= 10000) {
+ if (target->type == BL_PC) {
+ struct map_session_data *tsd = (struct map_session_data *)target;
+ if(tsd->status.weapon != 11)
+ pc_breakweapon(tsd);
+ } else
+ status_change_start(target,SC_STRIPWEAPON,1,75,0,0,breaktime,0);
+ }
+ if(rand() % 10000 < breakrate_[1] * battle_config.equipment_break_rate/100 || breakrate_[1] >= 10000) {
+ if (target->type == BL_PC) {
+ struct map_session_data *tsd = (struct map_session_data *)target;
+ if(tsd->status.weapon != 11)
+ pc_breakarmor(tsd);
+ } else
+ status_change_start(target,SC_STRIPSHIELD,1,75,0,0,breaktime,0);
}
}
@@ -4011,13 +2902,14 @@ struct Damage battle_calc_weapon_attack(
struct Damage battle_calc_magic_attack(
struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag)
{
- int mdef1=battle_get_mdef(target);
- int mdef2=battle_get_mdef2(target);
+ int mdef1=status_get_mdef(target);
+ int mdef2=status_get_mdef2(target);
int matk1,matk2,damage=0,div_=1,blewcount=skill_get_blewcount(skill_num,skill_lv),rdamage = 0;
struct Damage md;
int aflag;
int normalmagic_flag=1;
- int ele=0,race=7,t_ele=0,t_race=7,t_mode = 0,cardfix,t_class,i;
+ int matk_flag = 1;
+ int ele=0,race=7,size=1,race2=7,t_ele=0,t_race=7,t_mode = 0,cardfix,t_class,i;
struct map_session_data *sd=NULL,*tsd=NULL;
struct mob_data *tmd = NULL;
@@ -4034,13 +2926,15 @@ struct Damage battle_calc_magic_attack(
return md;
}
- matk1=battle_get_matk1(bl);
- matk2=battle_get_matk2(bl);
+ matk1=status_get_matk1(bl);
+ matk2=status_get_matk2(bl);
ele = skill_get_pl(skill_num);
- race = battle_get_race(bl);
- t_ele = battle_get_elem_type(target);
- t_race = battle_get_race(target);
- t_mode = battle_get_mode(target);
+ race = status_get_race(bl);
+ size = status_get_size(bl);
+ race2 = status_get_race2(bl);
+ t_ele = status_get_elem_type(target);
+ t_race = status_get_race(target);
+ t_mode = status_get_mode(target);
#define MATK_FIX( a,b ) { matk1=matk1*(a)/(b); matk2=matk2*(a)/(b); }
@@ -4078,10 +2972,10 @@ struct Damage battle_calc_magic_attack(
case PR_TURNUNDEAD: // 攻撃リザレクションとターンアンデッド
if(target->type != BL_PC && battle_check_undead(t_race,t_ele)){
int hp, mhp, thres;
- hp = battle_get_hp(target);
- mhp = battle_get_max_hp(target);
- thres = (skill_lv * 20) + battle_get_luk(bl)+
- battle_get_int(bl) + battle_get_lv(bl)+
+ hp = status_get_hp(target);
+ mhp = status_get_max_hp(target);
+ thres = (skill_lv * 20) + status_get_luk(bl)+
+ status_get_int(bl) + status_get_lv(bl)+
((200 - hp * 200 / mhp));
if(thres > 700) thres = 700;
// if(battle_config.battle_log)
@@ -4089,7 +2983,7 @@ struct Damage battle_calc_magic_attack(
if(rand()%1000 < thres && !(t_mode&0x20)) // 成功
damage = hp;
else // 失敗
- damage = battle_get_lv(bl) + battle_get_int(bl) + skill_lv * 10;
+ damage = status_get_lv(bl) + status_get_int(bl) + skill_lv * 10;
}
normalmagic_flag=0;
break;
@@ -4157,7 +3051,7 @@ struct Damage battle_calc_magic_attack(
break;
case WZ_STORMGUST: // ストームガスト
MATK_FIX( skill_lv*40+100 ,100 );
- blewcount|=0x10000;
+// blewcount|=0x10000;
break;
case AL_HOLYLIGHT: // ホーリーライト
MATK_FIX( 125,100 );
@@ -4174,15 +3068,30 @@ struct Damage battle_calc_magic_attack(
printf("battle_calc_magic_attack(): napalmvulcan enemy count=0 !\n");
}
break;
+ case PF_SOULBURN: // Celest
+ if (target->type != BL_PC || skill_lv < 5) {
+ memset(&md,0,sizeof(md));
+ return md;
+ } else if (target->type == BL_PC) {
+ damage = ((struct map_session_data *)target)->status.sp * 2;
+ matk_flag = 0; // don't consider matk and matk2
+ }
+ break;
+ case ASC_BREAKER:
+ damage = rand()%500 + 500 + skill_lv * status_get_int(bl) * 5;
+ matk_flag = 0; // don't consider matk and matk2
+ break;
}
}
if(normalmagic_flag){ // 一般魔法ダメージ計算
int imdef_flag=0;
- if(matk1>matk2)
- damage= matk2+rand()%(matk1-matk2+1);
- else
- damage= matk2;
+ if (matk_flag) {
+ if(matk1>matk2)
+ damage= matk2+rand()%(matk1-matk2+1);
+ else
+ damage= matk2;
+ }
if(sd) {
if(sd->ignore_mdef_ele & (1<<t_ele) || sd->ignore_mdef_race & (1<<t_race))
imdef_flag = 1;
@@ -4216,7 +3125,7 @@ struct Damage battle_calc_magic_attack(
cardfix=cardfix*(100+sd->magic_addrace[10])/100;
else
cardfix=cardfix*(100+sd->magic_addrace[11])/100;
- t_class = battle_get_class(target);
+ t_class = status_get_class(target);
for(i=0;i<sd->add_magic_damage_class_count;i++) {
if(sd->add_magic_damage_classid[i] == t_class) {
cardfix=cardfix*(100+sd->add_magic_damage_classrate[i])/100;
@@ -4224,15 +3133,19 @@ struct Damage battle_calc_magic_attack(
}
}
damage=damage*cardfix/100;
+ if (skill_num > 0 && sd->skillatk[0] == skill_num)
+ damage += damage*sd->skillatk[1]/100;
}
if( tsd ){
- int s_class = battle_get_class(bl);
+ int s_class = status_get_class(bl);
cardfix=100;
cardfix=cardfix*(100-tsd->subele[ele])/100; // 属 性によるダメージ耐性
cardfix=cardfix*(100-tsd->subrace[race])/100; // 種族によるダメージ耐性
+ cardfix=cardfix*(100-tsd->subsize[size])/100;
cardfix=cardfix*(100-tsd->magic_subrace[race])/100;
- if(battle_get_mode(bl) & 0x20)
+ cardfix=cardfix*(100-tsd->subrace2[race2])/100; // 種族によるダメージ耐性
+ if(status_get_mode(bl) & 0x20)
cardfix=cardfix*(100-tsd->magic_subrace[10])/100;
else
cardfix=cardfix*(100-tsd->magic_subrace[11])/100;
@@ -4247,13 +3160,13 @@ struct Damage battle_calc_magic_attack(
}
if(damage < 0) damage = 0;
- damage=battle_attr_fix(damage, ele, battle_get_element(target) ); // 属 性修正
+ damage=battle_attr_fix(damage, ele, status_get_element(target) ); // 属 性修正
if(skill_num == CR_GRANDCROSS) { // グランドクロス
struct Damage wd;
wd=battle_calc_weapon_attack(bl,target,skill_num,skill_lv,flag);
damage = (damage + wd.damage) * (100 + 40*skill_lv)/100;
- if(battle_config.gx_dupele) damage=battle_attr_fix(damage, ele, battle_get_element(target) ); //属性2回かかる
+ if(battle_config.gx_dupele) damage=battle_attr_fix(damage, ele, status_get_element(target) ); //属性2回かかる
if(bl==target) damage=damage/2; //反動は半分
}
@@ -4287,8 +3200,8 @@ struct Damage battle_calc_magic_attack(
md.damage=damage;
md.div_=div_;
- md.amotion=battle_get_amotion(bl);
- md.dmotion=battle_get_dmotion(target);
+ md.amotion=status_get_amotion(bl);
+ md.dmotion=status_get_dmotion(target);
md.damage2=0;
md.type=0;
md.blewcount=blewcount;
@@ -4304,16 +3217,16 @@ struct Damage battle_calc_magic_attack(
struct Damage battle_calc_misc_attack(
struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag)
{
- int int_=battle_get_int(bl);
-// int luk=battle_get_luk(bl);
- int dex=battle_get_dex(bl);
- int skill,ele,race,cardfix;
+ int int_=status_get_int(bl);
+// int luk=status_get_luk(bl);
+ int dex=status_get_dex(bl);
+ int skill,ele,race,size,cardfix,race2;
struct map_session_data *sd=NULL,*tsd=NULL;
int damage=0,div_=1,blewcount=skill_get_blewcount(skill_num,skill_lv);
struct Damage md;
int damagefix=1;
- int aflag=BF_MISC|BF_LONG|BF_SKILL;
+ int aflag=BF_MISC|BF_SHORT|BF_SKILL;
//return前の処理があるので情報出力部のみ変更
if( bl == NULL || target == NULL ){
@@ -4355,11 +3268,13 @@ struct Damage battle_calc_misc_attack(
damage=(dex/10+int_/2+skill*3+40)*2;
if(flag > 1)
damage /= flag;
+ aflag |= (flag&~BF_RANGEMASK)|BF_LONG;
break;
case TF_THROWSTONE: // 石投げ
damage=50;
damagefix=0;
+ aflag |= (flag&~BF_RANGEMASK)|BF_LONG;
break;
case BA_DISSONANCE: // 不協和音
@@ -4367,7 +3282,7 @@ struct Damage battle_calc_misc_attack(
break;
case NPC_SELFDESTRUCTION: // 自爆
- damage=battle_get_hp(bl)-(bl==target?1:0);
+ damage=status_get_hp(bl)-(bl==target?1:0);
damagefix=0;
break;
@@ -4378,8 +3293,8 @@ struct Damage battle_calc_misc_attack(
case NPC_DARKBREATH:
{
- struct status_change *sc_data = battle_get_sc_data(target);
- int hitrate=battle_get_hit(bl) - battle_get_flee(target) + 80;
+ struct status_change *sc_data = status_get_sc_data(target);
+ int hitrate=status_get_hit(bl) - status_get_flee(target) + 80;
hitrate = ( (hitrate>95)?95: ((hitrate<5)?5:hitrate) );
if(sc_data && (sc_data[SC_SLEEP].timer!=-1 || sc_data[SC_STAN].timer!=-1 ||
sc_data[SC_FREEZE].timer!=-1 || (sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0) ) )
@@ -4391,13 +3306,25 @@ struct Damage battle_calc_misc_attack(
}
break;
case SN_FALCONASSAULT: /* ファルコンアサルト */
- skill = pc_checkskill(sd,HT_STEELCROW); // Celest
- damage=((150+50*skill_lv)*(dex/10+int_/2+skill*3+40)*2)/100;
+#ifdef TWILIGHT
+ if( sd==NULL || (skill = pc_checkskill(sd,HT_BLITZBEAT)) <= 0)
+ skill=0;
+ damage=(100+50*skill_lv+(dex/10+int_/2+skill*3+40)*2) * 2;
+#else
+ if( sd==NULL || (skill = pc_checkskill(sd,HT_STEELCROW)) <= 0)
+ skill=0;
+ damage=((150+50*skill_lv)*(dex/10+int_/2+skill*3+40)*2)/100; // [Celest]
+#endif
+ if(flag > 1)
+ damage /= flag;
+ aflag |= (flag&~BF_RANGEMASK)|BF_LONG;
break;
}
ele = skill_get_pl(skill_num);
- race = battle_get_race(bl);
+ race = status_get_race(bl);
+ size = status_get_size(bl);
+ race2 = status_get_race(bl);
if(damagefix){
if(damage<1 && skill_num != NPC_DARKBREATH)
@@ -4407,27 +3334,35 @@ struct Damage battle_calc_misc_attack(
cardfix=100;
cardfix=cardfix*(100-tsd->subele[ele])/100; // 属性によるダメージ耐性
cardfix=cardfix*(100-tsd->subrace[race])/100; // 種族によるダメージ耐性
+ cardfix=cardfix*(100-tsd->subsize[size])/100;
cardfix=cardfix*(100-tsd->misc_def_rate)/100;
+ cardfix=cardfix*(100-tsd->subrace2[race2])/100;
damage=damage*cardfix/100;
}
+ if (sd && skill_num > 0 && sd->skillatk[0] == skill_num)
+ damage += damage*sd->skillatk[1]/100;
+
if(damage < 0) damage = 0;
- damage=battle_attr_fix(damage, ele, battle_get_element(target) ); // 属性修正
+ damage=battle_attr_fix(damage, ele, status_get_element(target) ); // 属性修正
}
div_=skill_get_num( skill_num,skill_lv );
if(div_>1)
damage*=div_;
- if(damage > 0 && (damage < div_ || (battle_get_def(target) >= 1000000 && battle_get_mdef(target) >= 1000000) ) ) {
+ if(damage > 0 && (damage < div_ || (status_get_def(target) >= 1000000 && status_get_mdef(target) >= 1000000) ) ) {
damage = div_;
}
+ if(status_get_mode(target)&0x40 && damage>0)
+ damage = 1;
+
damage=battle_calc_damage(bl,target,damage,div_,skill_num,skill_lv,aflag); // 最終修正
md.damage=damage;
md.div_=div_;
- md.amotion=battle_get_amotion(bl);
- md.dmotion=battle_get_dmotion(target);
+ md.amotion=status_get_amotion(bl);
+ md.dmotion=status_get_dmotion(target);
md.damage2=0;
md.type=0;
md.blewcount=blewcount;
@@ -4453,6 +3388,7 @@ struct Damage battle_calc_attack( int attack_type,
default:
if(battle_config.error_log)
printf("battle_calc_attack: unknwon attack type ! %d\n",attack_type);
+ memset(&d,0,sizeof(d));
break;
}
return d;
@@ -4465,7 +3401,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
unsigned int tick,int flag)
{
struct map_session_data *sd=NULL;
- struct status_change *sc_data = battle_get_sc_data(src),*t_sc_data=battle_get_sc_data(target);
+ struct status_change *sc_data = status_get_sc_data(src),*t_sc_data=status_get_sc_data(target);
short *opt1;
int race = 7, ele = 0;
int damage,rdamage = 0;
@@ -4484,7 +3420,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
if(target->type == BL_PC && pc_isdead((struct map_session_data *)target))
return 0;
- opt1=battle_get_opt1(src);
+ opt1=status_get_opt1(src);
if(opt1 && *opt1 > 0) {
battle_stopattack(src);
return 0;
@@ -4495,11 +3431,11 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
}
if(battle_check_target(src,target,BCT_ENEMY) <= 0 &&
- !battle_check_range(src,target,0))
+ !battle_check_range(src,target,0))
return 0; // 攻撃対象外
- race = battle_get_race(target);
- ele = battle_get_elem_type(target);
+ race = status_get_race(target);
+ ele = status_get_elem_type(target);
if(battle_check_target(src,target,BCT_ENEMY) > 0 &&
battle_check_range(src,target,0)){
// 攻撃対象となりうるので攻撃
@@ -4549,17 +3485,17 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
}
}
if(rdamage > 0)
- clif_damage(src,src,tick, wd.amotion,0,rdamage,1,4,0);
+ clif_damage(src,src,tick,wd.amotion,wd.dmotion,rdamage,1,4,0);
}
if (wd.div_ == 255 && sd) { //三段掌
- int delay = 1000 - 4 * battle_get_agi(src) - 2 * battle_get_dex(src);
+ int delay = 1000 - 4 * status_get_agi(src) - 2 * status_get_dex(src);
int skilllv;
- if(wd.damage+wd.damage2 < battle_get_hp(target)) {
+ if(wd.damage+wd.damage2 < status_get_hp(target)) {
if((skilllv = pc_checkskill(sd, MO_CHAINCOMBO)) > 0)
delay += 300 * battle_config.combo_delay_rate /100; //追加ディレイをconfにより調整
- skill_status_change_start(src,SC_COMBO,MO_TRIPLEATTACK,skilllv,0,0,delay,0);
+ status_change_start(src,SC_COMBO,MO_TRIPLEATTACK,skilllv,0,0,delay,0);
}
sd->attackabletime = sd->canmove_tick = tick + delay;
clif_combo_delay(src,delay);
@@ -4576,23 +3512,23 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
if(sd && sd->splash_range > 0 && (wd.damage > 0 || wd.damage2 > 0) )
skill_castend_damage_id(src,target,0,-1,tick,0);
map_freeblock_lock();
- battle_damage(src,target,(wd.damage+wd.damage2),0);
+ battle_delay_damage(tick+wd.amotion,src,target,(wd.damage+wd.damage2),0);
if(target->prev != NULL &&
(target->type != BL_PC || (target->type == BL_PC && !pc_isdead((struct map_session_data *)target) ) ) ) {
if(wd.damage > 0 || wd.damage2 > 0) {
skill_additional_effect(src,target,0,0,BF_WEAPON,tick);
if(sd) {
if(sd->weapon_coma_ele[ele] > 0 && rand()%10000 < sd->weapon_coma_ele[ele])
- battle_damage(src,target,battle_get_max_hp(target),1);
+ battle_damage(src,target,status_get_max_hp(target),1);
if(sd->weapon_coma_race[race] > 0 && rand()%10000 < sd->weapon_coma_race[race])
- battle_damage(src,target,battle_get_max_hp(target),1);
- if(battle_get_mode(target) & 0x20) {
+ battle_damage(src,target,status_get_max_hp(target),1);
+ if(status_get_mode(target) & 0x20) {
if(sd->weapon_coma_race[10] > 0 && rand()%10000 < sd->weapon_coma_race[10])
- battle_damage(src,target,battle_get_max_hp(target),1);
+ battle_damage(src,target,status_get_max_hp(target),1);
}
else {
if(sd->weapon_coma_race[11] > 0 && rand()%10000 < sd->weapon_coma_race[11])
- battle_damage(src,target,battle_get_max_hp(target),1);
+ battle_damage(src,target,status_get_max_hp(target),1);
}
}
}
@@ -4643,69 +3579,96 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
}
}
if(sd) {
- if(sd->autospell_id > 0 && sd->autospell_lv > 0 && rand()%100 < sd->autospell_rate) {
- int skilllv=sd->autospell_lv,i,f=0,sp;
+ if(sd->autospell_id > 0 && rand()%100 < sd->autospell_rate) {
+ int skilllv = sd->autospell_lv, i;
i = rand()%100;
if(i >= 50) skilllv -= 2;
else if(i >= 15) skilllv--;
if(skilllv < 1) skilllv = 1;
- sp = skill_get_sp(sd->autospell_id,skilllv)*2/3;
- if(sd->status.sp >= sp) {
- if((i=skill_get_inf(sd->autospell_id) == 2) || i == 32)
- f = skill_castend_pos2(src,target->x,target->y,sd->autospell_id,skilllv,tick,flag);
- else {
- switch( skill_get_nk(sd->autospell_id) ) {
- case 0: case 2:
- f = skill_castend_damage_id(src,target,sd->autospell_id,skilllv,tick,flag);
- break;
- case 1:/* 支援系 */
- if((sd->autospell_id==AL_HEAL || (sd->autospell_id==ALL_RESURRECTION && target->type != BL_PC)) && battle_check_undead(race,ele))
- f = skill_castend_damage_id(src,target,sd->autospell_id,skilllv,tick,flag);
- else
- f = skill_castend_nodamage_id(src,target,sd->autospell_id,skilllv,tick,flag);
- break;
- }
+
+ if((i=skill_get_inf(sd->autospell_id) == 2) || i == 32)
+ skill_castend_pos2(src,target->x,target->y,sd->autospell_id,skilllv,tick,flag);
+ else {
+ switch( skill_get_nk(sd->autospell_id) ) {
+ case 0: case 2:
+ skill_castend_damage_id(src,target,sd->autospell_id,skilllv,tick,flag);
+ break;
+ case 1:/* 支援系 */
+ if((sd->autospell_id==AL_HEAL || (sd->autospell_id==ALL_RESURRECTION && target->type != BL_PC)) && battle_check_undead(race,ele))
+ skill_castend_damage_id(src,target,sd->autospell_id,skilllv,tick,flag);
+ else
+ skill_castend_nodamage_id(src,target,sd->autospell_id,skilllv,tick,flag);
+ break;
}
- if(!f) pc_heal(sd,0,-sp);
- }
+ }
}
- if(wd.flag&BF_WEAPON && src != target && (wd.damage > 0 || wd.damage2 > 0)) {
+ if (wd.flag&BF_WEAPON && src != target && (wd.damage > 0 || wd.damage2 > 0)) {
int hp = 0,sp = 0;
- if(sd->hp_drain_rate && sd->hp_drain_per > 0 && wd.damage > 0 && rand()%100 < sd->hp_drain_rate) {
- hp += (wd.damage * sd->hp_drain_per)/100;
- if(sd->hp_drain_rate > 0 && hp < 1) hp = 1;
- else if(sd->hp_drain_rate < 0 && hp > -1) hp = -1;
- }
- if(sd->hp_drain_rate_ && sd->hp_drain_per_ > 0 && wd.damage2 > 0 && rand()%100 < sd->hp_drain_rate_) {
- hp += (wd.damage2 * sd->hp_drain_per_)/100;
- if(sd->hp_drain_rate_ > 0 && hp < 1) hp = 1;
- else if(sd->hp_drain_rate_ < 0 && hp > -1) hp = -1;
- }
- if(sd->sp_drain_rate && sd->sp_drain_per > 0 && wd.damage > 0 && rand()%100 < sd->sp_drain_rate) {
- sp += (wd.damage * sd->sp_drain_per)/100;
- if(sd->sp_drain_rate > 0 && sp < 1) sp = 1;
- else if(sd->sp_drain_rate < 0 && sp > -1) sp = -1;
+ if (!battle_config.left_cardfix_to_right) { // 二刀流左手カードの吸収系効果を右手に追加しない場合
+ hp += battle_calc_drain(wd.damage, sd->hp_drain_rate, sd->hp_drain_per, sd->hp_drain_value);
+ hp += battle_calc_drain(wd.damage2, sd->hp_drain_rate_, sd->hp_drain_per_, sd->hp_drain_value_);
+ sp += battle_calc_drain(wd.damage, sd->sp_drain_rate, sd->sp_drain_per, sd->sp_drain_value);
+ sp += battle_calc_drain(wd.damage2, sd->sp_drain_rate_, sd->sp_drain_per_, sd->sp_drain_value_);
+ } else { // 二刀流左手カードの吸収系効果を右手に追加する場合
+ int hp_drain_rate = sd->hp_drain_rate + sd->hp_drain_rate_;
+ int hp_drain_per = sd->hp_drain_per + sd->hp_drain_per_;
+ int hp_drain_value = sd->hp_drain_value + sd->hp_drain_value_;
+ int sp_drain_rate = sd->sp_drain_rate + sd->sp_drain_rate_;
+ int sp_drain_per = sd->sp_drain_per + sd->sp_drain_per_;
+ int sp_drain_value = sd->sp_drain_value + sd->sp_drain_value_;
+ hp += battle_calc_drain(wd.damage, hp_drain_rate, hp_drain_per, hp_drain_value);
+ sp += battle_calc_drain(wd.damage, sp_drain_rate, sp_drain_per, sp_drain_value);
}
- if(sd->sp_drain_rate_ && sd->sp_drain_per_ > 0 && wd.damage2 > 0 && rand()%100 < sd->sp_drain_rate_) {
- sp += (wd.damage2 * sd->sp_drain_per_)/100;
- if(sd->sp_drain_rate_ > 0 && sp < 1) sp = 1;
- else if(sd->sp_drain_rate_ < 0 && sp > -1) sp = -1;
- }
- if(hp || sp) pc_heal(sd,hp,sp);
+
+ if (hp || sp) pc_heal(sd, hp, sp);
+ if (sd->sp_drain_type && target->type == BL_PC)
+ battle_heal(NULL,target,0,-sp,0);
+ }
+ }
+ if (target->type == BL_PC) {
+ struct map_session_data *tsd = (struct map_session_data *)target;
+ if(tsd && ((sd && !sd->state.arrow_atk) || (status_get_range(src)<=2)) &&
+ tsd->autospell2_id > 0 && rand()%100 < tsd->autospell2_rate) {
+ struct block_list *tbl;
+ int skilllv = tsd->autospell_lv, i;
+ i = rand()%100;
+ if(i >= 50) skilllv -= 2;
+ else if(i >= 15) skilllv--;
+ if(skilllv < 1) skilllv = 1;
+
+ if (tsd->autospell2_type == 0) tbl = target;
+ else tbl = src;
+ if((i=skill_get_inf(tsd->autospell2_id) == 2) || i == 32)
+ skill_castend_pos2(target,tbl->x,tbl->y,tsd->autospell2_id,skilllv,tick,flag);
+ else {
+ switch( skill_get_nk(tsd->autospell2_id) ) {
+ case 0: case 2:
+ skill_castend_damage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag);
+ break;
+ case 1:/* 支援系 */
+ if((tsd->autospell2_id==AL_HEAL || (tsd->autospell2_id==ALL_RESURRECTION && tbl->type != BL_PC)) &&
+ battle_check_undead(status_get_race(tbl),status_get_elem_type(tbl)))
+ skill_castend_damage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag);
+ else
+ skill_castend_nodamage_id(target,tbl,tsd->autospell2_id,skilllv,tick,flag);
+ break;
+ }
+ }
}
}
if(rdamage > 0)
- battle_damage(target,src,rdamage,0);
+ battle_delay_damage(tick+wd.amotion,target,src,rdamage,0);
+
if(t_sc_data && t_sc_data[SC_AUTOCOUNTER].timer != -1 && t_sc_data[SC_AUTOCOUNTER].val4 > 0) {
if(t_sc_data[SC_AUTOCOUNTER].val3 == src->id)
battle_weapon_attack(target,src,tick,0x8000|t_sc_data[SC_AUTOCOUNTER].val1);
- skill_status_change_end(target,SC_AUTOCOUNTER,-1);
+ status_change_end(target,SC_AUTOCOUNTER,-1);
}
if(t_sc_data && t_sc_data[SC_POISONREACT].timer != -1 && t_sc_data[SC_POISONREACT].val4 > 0) { // poison react [Celest]
if(t_sc_data[SC_POISONREACT].val3 == src->id) {
struct map_session_data *tsd = (struct map_session_data *)target;
- if ((src->type == BL_MOB && battle_get_elem_type(src)==5) || (src->type == BL_PC && battle_get_attack_element(src)==5)) {
+ if ((src->type == BL_MOB && status_get_elem_type(src)==5) || (src->type == BL_PC && status_get_attack_element(src)==5)) {
t_sc_data[SC_POISONREACT].val2 = 0;
battle_weapon_attack(target,src,tick,flag|AS_POISONREACT);
} else {
@@ -4713,19 +3676,18 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
--t_sc_data[SC_POISONREACT].val2;
}
if (t_sc_data[SC_POISONREACT].val2<=0)
- skill_status_change_end(target,SC_POISONREACT,-1);
- }
- }
- if(t_sc_data && t_sc_data[SC_BLADESTOP_WAIT].timer != -1){
- if (!(src->type == BL_MOB && mob_db[((struct mob_data *)src)->class].mode&0x20)) {
- int lv = t_sc_data[SC_BLADESTOP_WAIT].val1;
- skill_status_change_end(target,SC_BLADESTOP_WAIT,-1);
- skill_status_change_start(src,SC_BLADESTOP,lv,1,(int)src,(int)target,skill_get_time2(MO_BLADESTOP,lv),0);
- skill_status_change_start(target,SC_BLADESTOP,lv,2,(int)target,(int)src,skill_get_time2(MO_BLADESTOP,lv),0);
+ status_change_end(target,SC_POISONREACT,-1);
}
}
+ if (t_sc_data && t_sc_data[SC_BLADESTOP_WAIT].timer != -1 &&
+ !(status_get_mode(src)&0x20)) { // ボスには無効
+ int lv = t_sc_data[SC_BLADESTOP_WAIT].val1;
+ status_change_end(target,SC_BLADESTOP_WAIT,-1);
+ status_change_start(src,SC_BLADESTOP,lv,1,(int)src,(int)target,skill_get_time2(MO_BLADESTOP,lv),0);
+ status_change_start(target,SC_BLADESTOP,lv,2,(int)target,(int)src,skill_get_time2(MO_BLADESTOP,lv),0);
+ }
if(t_sc_data && t_sc_data[SC_SPLASHER].timer!=-1) //殴ったので対象のベナムスプラッシャー状態を解除
- skill_status_change_end(target,SC_SPLASHER,-1);
+ status_change_end(target,SC_SPLASHER,-1);
map_freeblock_unlock();
}
@@ -4789,8 +3751,8 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
return -1;
// Celest
- sc_data = battle_get_sc_data(src);
- tsc_data = battle_get_sc_data(target);
+ sc_data = status_get_sc_data(src);
+ tsc_data = status_get_sc_data(target);
if ((sc_data && sc_data[SC_BASILICA].timer != -1) ||
(tsc_data && tsc_data[SC_BASILICA].timer != -1))
return -1;
@@ -4810,15 +3772,22 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
// スキルユニットの場合、親を求める
if( src->type==BL_SKILL) {
- int inf2 = skill_get_inf2(((struct skill_unit *)src)->group->skill_id);
- if( (ss=map_id2bl( ((struct skill_unit *)src)->group->src_id))==NULL )
+ struct skill_unit *su = (struct skill_unit *)src;
+ int skillid, inf2;
+
+ nullpo_retr (-1, su);
+ nullpo_retr (-1, su->group);
+ skillid = su->group->skill_id;
+ inf2 = skill_get_inf2(skillid);
+ if( (ss=map_id2bl( su->group->src_id))==NULL )
return -1;
if(ss->prev == NULL)
return -1;
- if(inf2&0x80 &&
- (map[src->m].flag.pvp || pc_iskiller((struct map_session_data *)src, (struct map_session_data *)target)) && // [MouseJstr]
- !(target->type == BL_PC && pc_isinvisible((struct map_session_data *)target)))
- return 0;
+ if(inf2&0x80 &&
+ (map[src->m].flag.pvp ||
+ (skillid >= 115 && skillid <= 125 && map[src->m].flag.gvg)) &&
+ !(target->type == BL_PC && pc_isinvisible((struct map_session_data *)target)))
+ return 0;
if(ss == target) {
if(inf2&0x100)
return 0;
@@ -4826,10 +3795,33 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
return -1;
}
}
- // Mobでmaster_idがあってspecial_mob_aiなら、召喚主を求める
+
if( src->type==BL_MOB ){
struct mob_data *md=(struct mob_data *)src;
- if(md && md->master_id>0){
+ nullpo_retr (-1, md);
+
+ if(target->type == BL_PC) {
+ struct map_session_data *sd = (struct map_session_data *)target;
+ nullpo_retr (-1, sd);
+
+ if(md->class_ >= 1285 && md->class_ <= 1287){
+ struct guild_castle *gc = guild_mapname2gc (map[target->m].name);
+ if(gc && agit_flag==0) // Guardians will not attack during non-woe time [Valaris]
+ return 1; // end addition [Valaris]
+ if(gc && sd->status.guild_id > 0) {
+ struct guild *g=guild_search(sd->status.guild_id); // don't attack guild members [Valaris]
+ if(g && g->guild_id == gc->guild_id)
+ return 1;
+ if(g && guild_isallied(g,gc))
+ return 1;
+ }
+ }
+ // option to have monsters ignore GMs [Valaris]
+ if (battle_config.monsters_ignore_gm > 0 && pc_isGM(sd) >= battle_config.monsters_ignore_gm)
+ return 1;
+ }
+ // Mobでmaster_idがあってspecial_mob_aiなら、召喚主を求める
+ if(md->master_id>0){
if(md->master_id==target->id) // 主なら肯定
return 1;
if(md->state.special_mob_ai){
@@ -4869,11 +3861,11 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if(ss->type == BL_PET && target->type==BL_MOB)
return 0;
- s_p=battle_get_party_id(ss);
- s_g=battle_get_guild_id(ss);
+ s_p=status_get_party_id(ss);
+ s_g=status_get_guild_id(ss);
- t_p=battle_get_party_id(target);
- t_g=battle_get_guild_id(target);
+ t_p=status_get_party_id(target);
+ t_g=status_get_guild_id(target);
if(flag&0x10000) {
if(s_p && t_p && s_p == t_p) // 同じパーティなら肯定(味方)
@@ -4896,7 +3888,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if(su && su->group->target_flag==BCT_NOENEMY)
return 1;
else if (battle_config.pk_mode &&
- (((struct map_session_data*)ss)->status.class==0 || ((struct map_session_data*)target)->status.class==0 ||
+ (((struct map_session_data*)ss)->status.class_==0 || ((struct map_session_data*)target)->status.class_==0 ||
((struct map_session_data*)ss)->status.base_level < battle_config.pk_min_level ||
((struct map_session_data*)target)->status.base_level < battle_config.pk_min_level))
return 1; // prevent novice engagement in pk_mode [Valaris]
@@ -4939,7 +3931,6 @@ int battle_check_range(struct block_list *src,struct block_list *bl,int range)
{
int dx,dy;
- struct walkpath_data wpd;
int arange;
nullpo_retr(0, src);
@@ -4962,16 +3953,7 @@ int battle_check_range(struct block_list *src,struct block_list *bl,int range)
// return 1;
// 障害物判定
- wpd.path_len=0;
- wpd.path_pos=0;
- wpd.path_half=0;
- if(path_search(&wpd,src->m,src->x,src->y,bl->x,bl->y,0x10001)!=-1)
- return 1;
-
- dx=(dx>0)?1:((dx<0)?-1:0);
- dy=(dy>0)?1:((dy<0)?-1:0);
- return (path_search(&wpd,src->m,src->x+dx,src->y+dy,
- bl->x-dx,bl->y-dy,0x10001)!=-1)?1:0;
+ return path_search_long(NULL,src->m,src->x,src->y,bl->x,bl->y);
}
/*==========================================
@@ -4989,7 +3971,7 @@ int battle_config_switch(const char *str) {
static const struct {
char str[128];
- int *val;
+ void *val;
} battle_data[] = {
{ "warp_point_debug", &battle_config.warp_point_debug },
{ "enemy_critical", &battle_config.enemy_critical },
@@ -5045,7 +4027,6 @@ static const struct {
{ "player_skillup_limit", &battle_config.skillup_limit },
{ "weapon_produce_rate", &battle_config.wp_rate },
{ "potion_produce_rate", &battle_config.pp_rate },
- { "deadly_potion_produce_rate", &battle_config.cdp_rate },
{ "monster_active_enable", &battle_config.monster_active_enable },
{ "monster_damage_delay_rate", &battle_config.monster_damage_delay_rate},
{ "monster_loot_type", &battle_config.monster_loot_type },
@@ -5082,6 +4063,11 @@ static const struct {
{ "natural_heal_skill_interval", &battle_config.natural_heal_skill_interval},
{ "natural_heal_weight_rate", &battle_config.natural_heal_weight_rate },
{ "item_name_override_grffile", &battle_config.item_name_override_grffile},
+ { "item_equip_override_grffile", &battle_config.item_equip_override_grffile}, // [Celest]
+ { "item_slots_override_grffile", &battle_config.item_slots_override_grffile}, // [Celest]
+ { "indoors_override_grffile", &battle_config.indoors_override_grffile}, // [Celest]
+ { "skill_sp_override_grffile", &battle_config.skill_sp_override_grffile}, // [Celest]
+ { "cardillust_read_grffile", &battle_config.cardillust_read_grffile}, // [Celest]
{ "arrow_decrement", &battle_config.arrow_decrement },
{ "max_aspd", &battle_config.max_aspd },
{ "max_hp", &battle_config.max_hp },
@@ -5099,14 +4085,14 @@ static const struct {
{ "undead_detect_type", &battle_config.undead_detect_type },
{ "player_auto_counter_type", &battle_config.pc_auto_counter_type },
{ "monster_auto_counter_type", &battle_config.monster_auto_counter_type},
- { "agi_penaly_type", &battle_config.agi_penaly_type },
- { "agi_penaly_count", &battle_config.agi_penaly_count },
- { "agi_penaly_num", &battle_config.agi_penaly_num },
- { "agi_penaly_count_lv", &battle_config.agi_penaly_count_lv },
- { "vit_penaly_type", &battle_config.vit_penaly_type },
- { "vit_penaly_count", &battle_config.vit_penaly_count },
- { "vit_penaly_num", &battle_config.vit_penaly_num },
- { "vit_penaly_count_lv", &battle_config.vit_penaly_count_lv },
+ { "agi_penalty_type", &battle_config.agi_penalty_type },
+ { "agi_penalty_count", &battle_config.agi_penalty_count },
+ { "agi_penalty_num", &battle_config.agi_penalty_num },
+ { "agi_penalty_count_lv", &battle_config.agi_penalty_count_lv },
+ { "vit_penalty_type", &battle_config.vit_penalty_type },
+ { "vit_penalty_count", &battle_config.vit_penalty_count },
+ { "vit_penalty_num", &battle_config.vit_penalty_num },
+ { "vit_penalty_count_lv", &battle_config.vit_penalty_count_lv },
{ "player_defense_type", &battle_config.player_defense_type },
{ "monster_defense_type", &battle_config.monster_defense_type },
{ "pet_defense_type", &battle_config.pet_defense_type },
@@ -5127,7 +4113,7 @@ static const struct {
{ "monster_attack_direction_change", &battle_config.monster_attack_direction_change },
{ "player_land_skill_limit", &battle_config.pc_land_skill_limit },
{ "monster_land_skill_limit", &battle_config.monster_land_skill_limit},
- { "party_skill_penaly", &battle_config.party_skill_penaly },
+ { "party_skill_penalty", &battle_config.party_skill_penalty },
{ "monster_class_change_full_recover", &battle_config.monster_class_change_full_recover },
{ "produce_item_name_input", &battle_config.produce_item_name_input },
{ "produce_potion_name_input", &battle_config.produce_potion_name_input},
@@ -5140,7 +4126,6 @@ static const struct {
{ "dead_branch_active", &battle_config.dead_branch_active },
{ "vending_max_value", &battle_config.vending_max_value },
{ "show_steal_in_same_party", &battle_config.show_steal_in_same_party },
- { "enable_upper_class", &battle_config.enable_upper_class },
{ "pet_attack_attr_none", &battle_config.pet_attack_attr_none },
{ "mob_attack_attr_none", &battle_config.mob_attack_attr_none },
{ "mob_ghostring_fix", &battle_config.mob_ghostring_fix },
@@ -5156,8 +4141,15 @@ static const struct {
{ "invite_request_check", &battle_config.invite_request_check },
{ "skill_removetrap_type", &battle_config.skill_removetrap_type },
{ "disp_experience", &battle_config.disp_experience },
- { "castle_defense_rate", &battle_config.castle_defense_rate },
- { "riding_weight", &battle_config.riding_weight },
+ { "castle_defense_rate", &battle_config.castle_defense_rate },
+ { "hp_rate", &battle_config.hp_rate },
+ { "sp_rate", &battle_config.sp_rate },
+ { "gm_can_drop_lv", &battle_config.gm_can_drop_lv },
+ { "disp_hpmeter", &battle_config.disp_hpmeter },
+ { "bone_drop", &battle_config.bone_drop },
+ { "monster_damage_delay", &battle_config.monster_damage_delay },
+
+// eAthena additions
{ "item_rate_common", &battle_config.item_rate_common }, // Added by RoVeRT
{ "item_rate_equip", &battle_config.item_rate_equip },
{ "item_rate_card", &battle_config.item_rate_card }, // End Addition
@@ -5198,16 +4190,23 @@ static const struct {
{ "max_cloth_color", &battle_config.max_cloth_color }, // added by [MouseJstr]
{ "castrate_dex_scale", &battle_config.castrate_dex_scale }, // added by [MouseJstr]
{ "area_size", &battle_config.area_size }, // added by [MouseJstr]
- { "muting_players", &battle_config.muting_players}, // added by [Apple]
+ { "muting_players", &battle_config.muting_players}, // added by [Apple]
{ "zeny_from_mobs", &battle_config.zeny_from_mobs}, // [Valaris]
{ "mobs_level_up", &battle_config.mobs_level_up}, // [Valaris]
{ "pk_min_level", &battle_config.pk_min_level}, // [celest]
{ "skill_steal_type", &battle_config.skill_steal_type}, // [celest]
{ "skill_steal_rate", &battle_config.skill_steal_rate}, // [celest]
{ "night_darkness_level", &battle_config.night_darkness_level}, // [celest]
+ { "motd_type", &battle_config.motd_type}, // [celest]
+ { "allow_atcommand_when_mute", &battle_config.allow_atcommand_when_mute}, // [celest]
+ { "finding_ore_rate", &battle_config.finding_ore_rate}, // [celest]
+ { "exp_calc_type", &battle_config.exp_calc_type}, // [celest]
+ { "min_skill_delay_limit", &battle_config.min_skill_delay_limit}, // [celest]
+ { "require_glory_guild", &battle_config.require_glory_guild}, // [celest]
+ { "idle_no_share", &battle_config.idle_no_share}, // [celest], for a feature by [MouseJstr]
//SQL-only options start
-#ifndef TXT_ONLY
+#ifndef TXT_ONLY
{ "mail_system", &battle_config.mail_system }, // added by [Valaris]
//SQL-only options end
#endif
@@ -5217,7 +4216,7 @@ int battle_set_value(char *w1, char *w2) {
int i;
for(i = 0; i < sizeof(battle_data) / (sizeof(battle_data[0])); i++)
if (strcmpi(w1, battle_data[i].str) == 0) {
- *battle_data[i].val = battle_config_switch(w2);
+ *((unsigned int *) battle_data[i].val) = battle_config_switch(w2);
return 1;
}
return 0;
@@ -5276,7 +4275,6 @@ void battle_set_defaults() {
battle_config.skillup_limit = 0;
battle_config.wp_rate=100;
battle_config.pp_rate=100;
- battle_config.cdp_rate=100;
battle_config.monster_active_enable=1;
battle_config.monster_damage_delay_rate=100;
battle_config.monster_loot_type=0;
@@ -5313,6 +4311,11 @@ void battle_set_defaults() {
battle_config.natural_heal_skill_interval=10000;
battle_config.natural_heal_weight_rate=50;
battle_config.item_name_override_grffile=1;
+ battle_config.item_equip_override_grffile=0; // [Celest]
+ battle_config.item_slots_override_grffile=0; // [Celest]
+ battle_config.indoors_override_grffile=0; // [Celest]
+ battle_config.skill_sp_override_grffile=0; // [Celest]
+ battle_config.cardillust_read_grffile=0; // [Celest]
battle_config.arrow_decrement=1;
battle_config.max_aspd = 199;
battle_config.max_hp = 32500;
@@ -5330,14 +4333,14 @@ void battle_set_defaults() {
battle_config.undead_detect_type = 0;
battle_config.pc_auto_counter_type = 1;
battle_config.monster_auto_counter_type = 1;
- battle_config.agi_penaly_type = 0;
- battle_config.agi_penaly_count = 3;
- battle_config.agi_penaly_num = 0;
- battle_config.agi_penaly_count_lv = ATK_FLEE;
- battle_config.vit_penaly_type = 0;
- battle_config.vit_penaly_count = 3;
- battle_config.vit_penaly_num = 0;
- battle_config.vit_penaly_count_lv = ATK_DEF;
+ battle_config.agi_penalty_type = 0;
+ battle_config.agi_penalty_count = 3;
+ battle_config.agi_penalty_num = 0;
+ battle_config.agi_penalty_count_lv = ATK_FLEE;
+ battle_config.vit_penalty_type = 0;
+ battle_config.vit_penalty_count = 3;
+ battle_config.vit_penalty_num = 0;
+ battle_config.vit_penalty_count_lv = ATK_DEF;
battle_config.player_defense_type = 0;
battle_config.monster_defense_type = 0;
battle_config.pet_defense_type = 0;
@@ -5349,17 +4352,16 @@ void battle_set_defaults() {
battle_config.pc_cloak_check_type = 0;
battle_config.monster_cloak_check_type = 0;
battle_config.gvg_short_damage_rate = 100;
- battle_config.gvg_long_damage_rate = 100;
- battle_config.gvg_magic_damage_rate = 100;
- battle_config.gvg_misc_damage_rate = 100;
+ battle_config.gvg_long_damage_rate = 60;
+ battle_config.gvg_magic_damage_rate = 50;
+ battle_config.gvg_misc_damage_rate = 60;
battle_config.gvg_eliminate_time = 7000;
battle_config.mob_changetarget_byskill = 0;
battle_config.pc_attack_direction_change = 1;
battle_config.monster_attack_direction_change = 1;
- battle_config.pc_undead_nofreeze = 0;
battle_config.pc_land_skill_limit = 1;
battle_config.monster_land_skill_limit = 1;
- battle_config.party_skill_penaly = 1;
+ battle_config.party_skill_penalty = 1;
battle_config.monster_class_change_full_recover = 0;
battle_config.produce_item_name_input = 1;
battle_config.produce_potion_name_input = 1;
@@ -5372,7 +4374,6 @@ void battle_set_defaults() {
battle_config.dead_branch_active = 0;
battle_config.vending_max_value = 10000000;
battle_config.show_steal_in_same_party = 0;
- battle_config.enable_upper_class = 0;
battle_config.pet_attack_attr_none = 0;
battle_config.pc_attack_attr_none = 0;
battle_config.mob_attack_attr_none = 1;
@@ -5388,6 +4389,15 @@ void battle_set_defaults() {
battle_config.invite_request_check = 1;
battle_config.skill_removetrap_type = 0;
battle_config.disp_experience = 0;
+ battle_config.castle_defense_rate = 100;
+ battle_config.hp_rate = 100;
+ battle_config.sp_rate = 100;
+ battle_config.gm_can_drop_lv = 0;
+ battle_config.disp_hpmeter = 0;
+ battle_config.bone_drop = 0;
+ battle_config.monster_damage_delay = 1;
+
+// eAthena additions
battle_config.item_rate_common = 100;
battle_config.item_rate_equip = 100;
battle_config.item_rate_card = 100;
@@ -5421,7 +4431,7 @@ void battle_set_defaults() {
battle_config.ban_spoof_namer = 5; // added by [Yor] (default: 5 minutes)
battle_config.hack_info_GM_level = 60; // added by [Yor] (default: 60, GM level)
battle_config.any_warp_GM_min_level = 20; // added by [Yor]
- battle_config.packet_ver_flag = 511; // added by [Yor]
+ battle_config.packet_ver_flag = 255; // added by [Yor]
battle_config.min_hair_style = 0;
battle_config.max_hair_style = 20;
battle_config.min_hair_color = 0;
@@ -5434,13 +4444,18 @@ void battle_set_defaults() {
battle_config.skill_steal_type = 1;
battle_config.skill_steal_rate = 100;
battle_config.night_darkness_level = 9;
-
+ battle_config.motd_type = 0;
+ battle_config.allow_atcommand_when_mute = 0;
+ battle_config.finding_ore_rate = 100;
battle_config.castrate_dex_scale = 150;
-
battle_config.area_size = 14;
+ battle_config.exp_calc_type = 1;
+ battle_config.min_skill_delay_limit = 100;
+ battle_config.require_glory_guild = 0;
+ battle_config.idle_no_share = 0;
//SQL-only options start
-#ifndef TXT_ONLY
+#ifndef TXT_ONLY
battle_config.mail_system = 0;
//SQL-only options end
#endif
@@ -5477,6 +4492,10 @@ void battle_validate_conf() {
battle_config.max_aspd = 10;
if(battle_config.max_aspd > 1000)
battle_config.max_aspd = 1000;
+ if(battle_config.hp_rate < 0)
+ battle_config.hp_rate = 1;
+ if(battle_config.sp_rate < 0)
+ battle_config.sp_rate = 1;
if(battle_config.max_hp > 1000000)
battle_config.max_hp = 1000000;
if(battle_config.max_hp < 100)
@@ -5495,10 +4514,10 @@ void battle_validate_conf() {
battle_config.max_cart_weight = 100;
battle_config.max_cart_weight *= 10;
- if(battle_config.agi_penaly_count < 2)
- battle_config.agi_penaly_count = 2;
- if(battle_config.vit_penaly_count < 2)
- battle_config.vit_penaly_count = 2;
+ if(battle_config.agi_penalty_count < 2)
+ battle_config.agi_penalty_count = 2;
+ if(battle_config.vit_penalty_count < 2)
+ battle_config.vit_penalty_count = 2;
if(battle_config.guild_exp_limit > 99)
battle_config.guild_exp_limit = 99;
@@ -5530,11 +4549,11 @@ void battle_validate_conf() {
battle_config.night_at_start = 0;
else if (battle_config.night_at_start > 1) // added by [Yor]
battle_config.night_at_start = 1;
- if (battle_config.day_duration < 0) // added by [Yor]
- battle_config.day_duration = 0;
- if (battle_config.night_duration < 0) // added by [Yor]
- battle_config.night_duration = 0;
-
+ if (battle_config.day_duration != 0 && battle_config.day_duration < 60000) // added by [Yor]
+ battle_config.day_duration = 60000;
+ if (battle_config.night_duration != 0 && battle_config.night_duration < 60000) // added by [Yor]
+ battle_config.night_duration = 60000;
+
if (battle_config.ban_spoof_namer < 0) // added by [Yor]
battle_config.ban_spoof_namer = 0;
else if (battle_config.ban_spoof_namer > 32767)
@@ -5551,33 +4570,43 @@ void battle_validate_conf() {
battle_config.any_warp_GM_min_level = 100;
// at least 1 client must be accepted
- if ((battle_config.packet_ver_flag & 511) == 0) // added by [Yor]
- battle_config.packet_ver_flag = 511; // accept all clients
-
+ if ((battle_config.packet_ver_flag & 255) == 0) // added by [Yor]
+ battle_config.packet_ver_flag = 255; // accept all clients
+
if (battle_config.night_darkness_level > 10) // Celest
battle_config.night_darkness_level = 10;
+ if (battle_config.motd_type < 0)
+ battle_config.motd_type = 0;
+ else if (battle_config.motd_type > 1)
+ battle_config.motd_type = 1;
+
+ if (battle_config.finding_ore_rate < 0)
+ battle_config.finding_ore_rate = 0;
+
if (battle_config.vending_max_value > 10000000 || battle_config.vending_max_value<=0) // Lupus & Kobra_k88
battle_config.vending_max_value = 10000000;
+ if (battle_config.min_skill_delay_limit < 10)
+ battle_config.min_skill_delay_limit = 10; // minimum delay of 10ms
}
/*==========================================
* 設定ファイルを読み込む
*------------------------------------------
*/
-int battle_config_read(const char *cfgName)
+int battle_config_read(const char *cfgName)
{
char line[1024], w1[1024], w2[1024];
FILE *fp;
static int count = 0;
- if ((count++) == 0)
+ if ((count++) == 0)
battle_set_defaults();
fp = fopen(cfgName,"r");
if (fp == NULL) {
- printf("file not found: %s\n", cfgName);
+ printf("File not found: %s\n", cfgName);
return 1;
}
while(fgets(line,1020,fp)){