summaryrefslogtreecommitdiff
path: root/src/map/battle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/battle.cpp')
-rw-r--r--src/map/battle.cpp5401
1 files changed, 957 insertions, 4444 deletions
diff --git a/src/map/battle.cpp b/src/map/battle.cpp
index a636af4..97edeb3 100644
--- a/src/map/battle.cpp
+++ b/src/map/battle.cpp
@@ -1,60 +1,39 @@
-// $Id: battle.c,v 1.10 2004/09/29 21:08:17 Akitasha Exp $
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
#include "battle.hpp"
-#include "../common/timer.hpp"
+#include <cstring>
+
+#include <fstream>
+
+#include "../common/cxxstdio.hpp"
+#include "../common/random.hpp"
#include "../common/nullpo.hpp"
#include "clif.hpp"
-#include "guild.hpp"
#include "itemdb.hpp"
#include "map.hpp"
#include "mob.hpp"
#include "pc.hpp"
#include "skill.hpp"
-#include "../common/socket.hpp"
-#include "../common/mt_rand.hpp"
-#ifdef MEMWATCH
-#include "memwatch.hpp"
-#endif
-
-int attr_fix_table[4][10][10];
+#include "../poison.hpp"
struct Battle_Config battle_config;
/*==========================================
- * 二点間の距離を返す
- * 戻りは整数で0以上
- *------------------------------------------
- */
-static int distance (int x0, int y0, int x1, int y1)
-{
- int dx, dy;
-
- dx = abs (x0 - x1);
- dy = abs (y0 - y1);
- return dx > dy ? dx : dy;
-}
-
-/*==========================================
* 自分をロックしている対象の数を返す(汎用)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_counttargeted (struct block_list *bl, struct block_list *src,
- int target_lv)
+static
+int battle_counttargeted(struct block_list *bl, struct block_list *src,
+ ATK target_lv)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_PC)
- return pc_counttargeted ((struct map_session_data *) bl, src,
+ nullpo_ret(bl);
+ if (bl->type == BL::PC)
+ return pc_counttargeted((struct map_session_data *) bl, src,
target_lv);
- else if (bl->type == BL_MOB)
- return mob_counttargeted ((struct mob_data *) bl, src, target_lv);
+ else if (bl->type == BL::MOB)
+ return mob_counttargeted((struct mob_data *) bl, src, target_lv);
return 0;
}
@@ -63,13 +42,13 @@ int battle_counttargeted (struct block_list *bl, struct block_list *src,
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_class (struct block_list *bl)
+int battle_get_class(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
return ((struct mob_data *) bl)->mob_class;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
- return ((struct map_session_data *) bl)->status.pc_class;
+ else if (bl->type == BL::PC)
+ return 0;
else
return 0;
}
@@ -79,15 +58,15 @@ int battle_get_class (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_dir (struct block_list *bl)
+DIR battle_get_dir(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_retr(DIR::S, bl);
+ if (bl->type == BL::MOB)
return ((struct mob_data *) bl)->dir;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
+ else if (bl->type == BL::PC)
return ((struct map_session_data *) bl)->dir;
else
- return 0;
+ return DIR::S;
}
/*==========================================
@@ -95,12 +74,12 @@ int battle_get_dir (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_lv (struct block_list *bl)
+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)->stats[MOB_LV];
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
+ return ((struct mob_data *) bl)->stats[mob_stat::LV];
+ else if (bl->type == BL::PC)
return ((struct map_session_data *) bl)->status.base_level;
else
return 0;
@@ -111,12 +90,12 @@ int battle_get_lv (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_range (struct block_list *bl)
+int battle_get_range(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
return mob_db[((struct mob_data *) bl)->mob_class].range;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
+ else if (bl->type == BL::PC)
return ((struct map_session_data *) bl)->attackrange;
else
return 0;
@@ -127,12 +106,12 @@ int battle_get_range (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_hp (struct block_list *bl)
+int battle_get_hp(struct block_list *bl)
{
- nullpo_retr (1, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_retr(1, bl);
+ if (bl->type == BL::MOB)
return ((struct mob_data *) bl)->hp;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
+ else if (bl->type == BL::PC)
return ((struct map_session_data *) bl)->status.hp;
else
return 1;
@@ -143,42 +122,26 @@ int battle_get_hp (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_max_hp (struct block_list *bl)
+int battle_get_max_hp(struct block_list *bl)
{
- nullpo_retr (1, bl);
- if (bl->type == BL_PC && ((struct map_session_data *) 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))
+ int max_hp = 1;
+ if (bl->type == BL::MOB && ((struct mob_data *) bl))
{
- max_hp = ((struct mob_data *) bl)->stats[MOB_MAX_HP];
- if (mob_db[((struct mob_data *) bl)->mob_class].mexp > 0)
- {
- if (battle_config.mvp_hp_rate != 100)
- max_hp = (max_hp * battle_config.mvp_hp_rate) / 100;
- }
- else
+ max_hp = ((struct mob_data *) bl)->stats[mob_stat::MAX_HP];
{
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;
}
/*==========================================
@@ -186,35 +149,18 @@ int battle_get_max_hp (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_str (struct block_list *bl)
+int battle_get_str(struct block_list *bl)
{
- int str = 0;
- struct status_change *sc_data;
+ int str = 0;
+ eptr<struct status_change, StatusChange> sc_data;
- nullpo_retr (0, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_MOB && ((struct mob_data *) bl))
- str = ((struct mob_data *) bl)->stats[MOB_STR];
- else if (bl->type == BL_PC && ((struct map_session_data *) bl))
- return ((struct map_session_data *) bl)->paramc[0];
+ nullpo_ret(bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::MOB && ((struct mob_data *) bl))
+ str = ((struct mob_data *) bl)->stats[mob_stat::STR];
+ else if (bl->type == BL::PC && ((struct map_session_data *) bl))
+ return ((struct map_session_data *) bl)->paramc[ATTR::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;
@@ -226,35 +172,18 @@ int battle_get_str (struct block_list *bl)
*------------------------------------------
*/
-int battle_get_agi (struct block_list *bl)
+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 = ((struct mob_data *) bl)->stats[MOB_AGI];
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
- agi = ((struct map_session_data *) bl)->paramc[1];
-
- 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;
+ int agi = 0;
+ eptr<struct status_change, StatusChange> sc_data;
- if (sc_data[SC_DECREASEAGI].timer != -1) // 速度減少
- agi -= 2 + sc_data[SC_DECREASEAGI].val1;
+ nullpo_ret(bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::MOB)
+ agi = ((struct mob_data *) bl)->stats[mob_stat::AGI];
+ else if (bl->type == BL::PC)
+ agi = ((struct map_session_data *) bl)->paramc[ATTR::AGI];
- if (sc_data[SC_QUAGMIRE].timer != -1) // クァグマイア
- agi >>= 1;
- if (sc_data[SC_TRUESIGHT].timer != -1 && bl->type != BL_PC) // トゥルーサイト
- agi += 5;
- }
if (agi < 0)
agi = 0;
return agi;
@@ -265,24 +194,17 @@ int battle_get_agi (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_vit (struct block_list *bl)
+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 = ((struct mob_data *) bl)->stats[MOB_VIT];
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
- vit = ((struct map_session_data *) bl)->paramc[2];
- 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;
- }
+ int vit = 0;
+ eptr<struct status_change, StatusChange> sc_data;
+
+ nullpo_ret(bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::MOB)
+ vit = ((struct mob_data *) bl)->stats[mob_stat::VIT];
+ else if (bl->type == BL::PC)
+ vit = ((struct map_session_data *) bl)->paramc[ATTR::VIT];
if (vit < 0)
vit = 0;
@@ -294,34 +216,18 @@ int battle_get_vit (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_int (struct block_list *bl)
+int battle_get_int(struct block_list *bl)
{
- int int_ = 0;
- struct status_change *sc_data;
+ int int_ = 0;
+ eptr<struct status_change, StatusChange> sc_data;
- nullpo_retr (0, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
- int_ = ((struct mob_data *) bl)->stats[MOB_INT];
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
- int_ = ((struct map_session_data *) bl)->paramc[3];
+ nullpo_ret(bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::MOB)
+ int_ = ((struct mob_data *) bl)->stats[mob_stat::INT];
+ else if (bl->type == BL::PC)
+ int_ = ((struct map_session_data *) bl)->paramc[ATTR::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_;
@@ -332,39 +238,18 @@ int battle_get_int (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_dex (struct block_list *bl)
+int battle_get_dex(struct block_list *bl)
{
- int dex = 0;
- struct status_change *sc_data;
+ int dex = 0;
+ eptr<struct status_change, StatusChange> sc_data;
- nullpo_retr (0, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
- dex = ((struct mob_data *) bl)->stats[MOB_DEX];
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
- dex = ((struct map_session_data *) bl)->paramc[4];
+ nullpo_ret(bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::MOB)
+ dex = ((struct mob_data *) bl)->stats[mob_stat::DEX];
+ else if (bl->type == BL::PC)
+ dex = ((struct map_session_data *) bl)->paramc[ATTR::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;
- if (sc_data[SC_TRUESIGHT].timer != -1 && bl->type != BL_PC) // トゥルーサイト
- dex += 5;
- }
if (dex < 0)
dex = 0;
return dex;
@@ -375,27 +260,18 @@ int battle_get_dex (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_luk (struct block_list *bl)
+int battle_get_luk(struct block_list *bl)
{
- int luk = 0;
- struct status_change *sc_data;
+ int luk = 0;
+ eptr<struct status_change, StatusChange> sc_data;
- nullpo_retr (0, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
- luk = ((struct mob_data *) bl)->stats[MOB_LUK];
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
- luk = ((struct map_session_data *) bl)->paramc[5];
+ nullpo_ret(bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::MOB)
+ luk = ((struct mob_data *) bl)->stats[mob_stat::LUK];
+ else if (bl->type == BL::PC)
+ luk = ((struct map_session_data *) bl)->paramc[ATTR::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;
@@ -406,34 +282,24 @@ int battle_get_luk (struct block_list *bl)
* 戻りは整数で1以上
*------------------------------------------
*/
-int battle_get_flee (struct block_list *bl)
+static
+int battle_get_flee(struct block_list *bl)
{
- int flee = 1;
- struct status_change *sc_data;
+ int flee = 1;
+ eptr<struct status_change, StatusChange> sc_data;
- nullpo_retr (1, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_PC && (struct map_session_data *) bl)
+ nullpo_retr(1, bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::PC)
flee = ((struct map_session_data *) bl)->flee;
else
- flee = battle_get_agi (bl) + battle_get_lv (bl);
+ 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 (battle_is_unarmed (bl))
- flee += (skill_power_bl (bl, TMW_BRAWLING) >> 3); // +25 for 200
- flee += skill_power_bl (bl, TMW_SPEED) >> 3;
+ if (battle_is_unarmed(bl))
+ flee += (skill_power_bl(bl, SkillID::TMW_BRAWLING) >> 3); // +25 for 200
+ flee += skill_power_bl(bl, SkillID::TMW_SPEED) >> 3;
}
if (flee < 1)
flee = 1;
@@ -445,34 +311,23 @@ int battle_get_flee (struct block_list *bl)
* 戻りは整数で1以上
*------------------------------------------
*/
-int battle_get_hit (struct block_list *bl)
+static
+int battle_get_hit(struct block_list *bl)
{
- int hit = 1;
- struct status_change *sc_data;
+ int hit = 1;
+ eptr<struct status_change, StatusChange> sc_data;
- nullpo_retr (1, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_PC && (struct map_session_data *) bl)
+ nullpo_retr(1, bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::PC)
hit = ((struct map_session_data *) bl)->hit;
else
- hit = battle_get_dex (bl) + battle_get_lv (bl);
+ 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 (battle_is_unarmed (bl))
- hit += (skill_power_bl (bl, TMW_BRAWLING) >> 4); // +12 for 200
+ if (battle_is_unarmed(bl))
+ hit += (skill_power_bl(bl, SkillID::TMW_BRAWLING) >> 4); // +12 for 200
}
if (hit < 1)
hit = 1;
@@ -484,32 +339,28 @@ int battle_get_hit (struct block_list *bl)
* 戻りは整数で1以上
*------------------------------------------
*/
-int battle_get_flee2 (struct block_list *bl)
+static
+int battle_get_flee2(struct block_list *bl)
{
- int flee2 = 1;
- struct status_change *sc_data;
+ int flee2 = 1;
+ eptr<struct status_change, StatusChange> sc_data;
- nullpo_retr (1, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_PC && (struct map_session_data *) bl)
+ nullpo_retr(1, bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::PC)
{
- flee2 = battle_get_luk (bl) + 10;
+ flee2 = battle_get_luk(bl) + 10;
flee2 +=
((struct map_session_data *) bl)->flee2 -
- (((struct map_session_data *) bl)->paramc[5] + 10);
+ (((struct map_session_data *) bl)->paramc[ATTR::LUK] + 10);
}
else
- flee2 = battle_get_luk (bl) + 1;
+ 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 (battle_is_unarmed (bl))
- flee2 += (skill_power_bl (bl, TMW_BRAWLING) >> 3); // +25 for 200
- flee2 += skill_power_bl (bl, TMW_SPEED) >> 3;
+ if (battle_is_unarmed(bl))
+ flee2 += (skill_power_bl(bl, SkillID::TMW_BRAWLING) >> 3); // +25 for 200
+ flee2 += skill_power_bl(bl, SkillID::TMW_SPEED) >> 3;
}
if (flee2 < 1)
flee2 = 1;
@@ -522,34 +373,23 @@ int battle_get_flee2 (struct block_list *bl)
*------------------------------------------
*/
static
-int battle_get_critical (struct block_list *bl)
+int battle_get_critical(struct block_list *bl)
{
- int critical = 1;
- struct status_change *sc_data;
+ int critical = 1;
+ eptr<struct status_change, StatusChange> sc_data;
- nullpo_retr (1, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_PC && (struct map_session_data *) bl)
+ nullpo_retr(1, bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::PC)
{
- critical = battle_get_luk (bl) * 2 + 10;
+ critical = battle_get_luk(bl) * 2 + 10;
critical +=
((struct map_session_data *) bl)->critical -
- ((((struct map_session_data *) bl)->paramc[5] * 3) + 10);
+ ((((struct map_session_data *) bl)->paramc[ATTR::LUK] * 3) + 10);
}
else
- critical = battle_get_luk (bl) * 3 + 1;
+ 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;
@@ -560,31 +400,23 @@ int battle_get_critical (struct block_list *bl)
* 戻りは整数で1以上
*------------------------------------------
*/
-int battle_get_baseatk (struct block_list *bl)
+static
+int battle_get_baseatk(struct block_list *bl)
{
- struct status_change *sc_data;
- int batk = 1;
+ eptr<struct status_change, StatusChange> 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)
+ nullpo_retr(1, bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::PC)
batk = ((struct map_session_data *) bl)->base_atk; //設定されているbase_atk
else
{ //それ以外なら
- int str, dstr;
- str = battle_get_str (bl); //STR
+ 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 (batk < 1)
batk = 1; //base_atkは最低でも1
return batk;
@@ -595,27 +427,19 @@ int battle_get_baseatk (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_atk (struct block_list *bl)
+static
+int battle_get_atk(struct block_list *bl)
{
- struct status_change *sc_data;
- int atk = 0;
+ eptr<struct status_change, StatusChange> 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)
+ nullpo_ret(bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::PC)
atk = ((struct map_session_data *) bl)->watk;
- else if (bl->type == BL_MOB && (struct mob_data *) bl)
- atk = ((struct mob_data *) bl)->stats[MOB_ATK1];
+ else if (bl->type == BL::MOB)
+ atk = ((struct mob_data *) bl)->stats[mob_stat::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;
@@ -627,17 +451,11 @@ int battle_get_atk (struct block_list *bl)
*------------------------------------------
*/
static
-int battle_get_atk_ (struct block_list *bl)
+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;
- }
+ nullpo_ret(bl);
+ if (bl->type == BL::PC)
+ return ((struct map_session_data *) bl)->watk_;
else
return 0;
}
@@ -647,41 +465,22 @@ int battle_get_atk_ (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_atk2 (struct block_list *bl)
+static
+int battle_get_atk2(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_PC && (struct map_session_data *) bl)
+ nullpo_ret(bl);
+ if (bl->type == BL::PC)
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 = ((struct mob_data *) bl)->stats[MOB_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;
- }
+ int atk2 = 0;
+ if (bl->type == BL::MOB)
+ atk2 = ((struct mob_data *) bl)->stats[mob_stat::ATK2];
if (atk2 < 0)
atk2 = 0;
return atk2;
}
- return 0;
}
/*==========================================
@@ -690,10 +489,10 @@ int battle_get_atk2 (struct block_list *bl)
*------------------------------------------
*/
static
-int battle_get_atk_2 (struct block_list *bl)
+int battle_get_atk_2(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_PC)
+ nullpo_ret(bl);
+ if (bl->type == BL::PC)
return ((struct map_session_data *) bl)->watk_2;
else
return 0;
@@ -705,22 +504,19 @@ int battle_get_atk_2 (struct block_list *bl)
*------------------------------------------
*/
static
-int battle_get_matk1 (struct block_list *bl)
+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)
+ eptr<struct status_change, StatusChange> sc_data;
+ nullpo_ret(bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::MOB)
{
- int matk, int_ = battle_get_int (bl);
+ 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)
+ else if (bl->type == BL::PC)
return ((struct map_session_data *) bl)->matk1;
else
return 0;
@@ -732,21 +528,17 @@ int battle_get_matk1 (struct block_list *bl)
*------------------------------------------
*/
static
-int battle_get_matk2 (struct block_list *bl)
+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)
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
{
- int matk, int_ = battle_get_int (bl);
+ 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)
+ else if (bl->type == BL::PC)
return ((struct map_session_data *) bl)->matk2;
else
return 0;
@@ -757,67 +549,30 @@ int battle_get_matk2 (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_def (struct block_list *bl)
+int battle_get_def(struct block_list *bl)
{
- struct status_change *sc_data;
- int def = 0, skilltimer = -1, skillid = 0;
+ eptr<struct status_change, StatusChange> sc_data;
+ int def = 0;
- nullpo_retr (0, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_PC && (struct map_session_data *) bl)
+ nullpo_ret(bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::PC)
{
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)
+ else if (bl->type == BL::MOB)
{
- def = ((struct mob_data *) bl)->stats[MOB_DEF];
- skilltimer = ((struct mob_data *) bl)->skilltimer;
- skillid = ((struct mob_data *) bl)->skillid;
+ def = ((struct mob_data *) bl)->stats[mob_stat::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)
+ if (sc_data[StatusChange::SC_POISON].timer
+ && 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)
@@ -830,38 +585,29 @@ int battle_get_def (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_mdef (struct block_list *bl)
+int battle_get_mdef(struct block_list *bl)
{
- struct status_change *sc_data;
- int mdef = 0;
+ eptr<struct status_change, StatusChange> 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)
+ nullpo_ret(bl);
+ sc_data = battle_get_sc_data(bl);
+ if (bl->type == BL::PC)
mdef = ((struct map_session_data *) bl)->mdef;
- else if (bl->type == BL_MOB && (struct mob_data *) bl)
- mdef = ((struct mob_data *) bl)->stats[MOB_MDEF];
+ else if (bl->type == BL::MOB)
+ mdef = ((struct mob_data *) bl)->stats[mob_stat::MDEF];
if (mdef < 1000000)
{
if (sc_data)
{
//バリアー状態時はMDEF100
- if (mdef < 90 && sc_data[SC_MBARRIER].timer != -1)
+ if (mdef < 90 && sc_data[StatusChange::SC_MBARRIER].timer)
{
- mdef += sc_data[SC_MBARRIER].val1;
+ mdef += sc_data[StatusChange::SC_MBARRIER].val1;
if (mdef > 90)
mdef = 90;
}
- 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)
@@ -874,29 +620,23 @@ int battle_get_mdef (struct block_list *bl)
* 戻りは整数で1以上
*------------------------------------------
*/
-int battle_get_def2 (struct block_list *bl)
+int battle_get_def2(struct block_list *bl)
{
- struct status_change *sc_data;
- int def2 = 1;
+ eptr<struct status_change, StatusChange> sc_data;
+ int def2 = 1;
- nullpo_retr (1, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_PC)
+ 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 = ((struct mob_data *) bl)->stats[MOB_VIT];
+ else if (bl->type == BL::MOB)
+ def2 = ((struct mob_data *) bl)->stats[mob_stat::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)
+ if (sc_data[StatusChange::SC_POISON].timer
+ && 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;
@@ -908,25 +648,20 @@ int battle_get_def2 (struct block_list *bl)
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_mdef2 (struct block_list *bl)
+int battle_get_mdef2(struct block_list *bl)
{
- int mdef2 = 0;
- struct status_change *sc_data = battle_get_sc_data (bl);
+ int mdef2 = 0;
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB)
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
mdef2 =
- ((struct mob_data *) bl)->stats[MOB_INT] +
- (((struct mob_data *) bl)->stats[MOB_VIT] >> 1);
- else if (bl->type == BL_PC)
+ ((struct mob_data *) bl)->stats[mob_stat::INT] +
+ (((struct mob_data *) bl)->stats[mob_stat::VIT] >> 1);
+ else if (bl->type == BL::PC)
mdef2 =
((struct map_session_data *) bl)->mdef2 +
- (((struct map_session_data *) bl)->paramc[2] >> 1);
- if (sc_data)
- {
- if (sc_data[SC_MINDBREAKER].timer != -1 && bl->type != BL_PC)
- mdef2 -= (mdef2 * 6 * sc_data[SC_MINDBREAKER].val1) / 100;
- }
+ (((struct map_session_data *) bl)->paramc[ATTR::VIT] >> 1);
+
if (mdef2 < 0)
mdef2 = 0;
return mdef2;
@@ -938,58 +673,19 @@ int battle_get_mdef2 (struct block_list *bl)
* Speedは小さいほうが移動速度が速い
*------------------------------------------
*/
-int battle_get_speed (struct block_list *bl)
+interval_t battle_get_speed(struct block_list *bl)
{
- nullpo_retr (1000, bl);
- if (bl->type == BL_PC && (struct map_session_data *) bl)
+ nullpo_retr(std::chrono::seconds(1), bl);
+ if (bl->type == BL::PC)
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)->stats[MOB_SPEED];
+ interval_t speed = std::chrono::seconds(1);
+ if (bl->type == BL::MOB)
+ speed = static_cast<interval_t>(((struct mob_data *) bl)->stats[mob_stat::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 (speed < 1)
- speed = 1;
- return speed;
+ return std::max(speed, std::chrono::milliseconds(1));
}
-
- return 1000;
}
/*==========================================
@@ -997,423 +693,213 @@ int battle_get_speed (struct block_list *bl)
* aDelayは小さいほうが攻撃速度が速い
*------------------------------------------
*/
-int battle_get_adelay (struct block_list *bl)
+// TODO figure out what all the doubling is about
+interval_t 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);
+ nullpo_retr(std::chrono::seconds(4), bl);
+ if (bl->type == BL::PC)
+ return ((struct map_session_data *) bl)->aspd * 2;
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 = ((struct mob_data *) bl)->stats[MOB_ADELAY];
+ eptr<struct status_change, StatusChange> sc_data = battle_get_sc_data(bl);
+ interval_t adelay = std::chrono::seconds(4);
+ int aspd_rate = 100;
+ if (bl->type == BL::MOB)
+ adelay = static_cast<interval_t>(((struct mob_data *) bl)->stats[mob_stat::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].val1;
+ if (sc_data[StatusChange::SC_SPEEDPOTION0].timer)
+ aspd_rate -= sc_data[StatusChange::SC_SPEEDPOTION0].val1;
// Fate's `haste' spell works the same as the above
- if (sc_data[SC_HASTE].timer != -1)
- aspd_rate -= sc_data[SC_HASTE].val1;
- //ディフェンダー時は加算
- if (sc_data[SC_DEFENDER].timer != -1)
- adelay += (1100 - sc_data[SC_DEFENDER].val1 * 100);
+ if (sc_data[StatusChange::SC_HASTE].timer)
+ aspd_rate -= sc_data[StatusChange::SC_HASTE].val1;
}
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 std::max(adelay, static_cast<interval_t>(battle_config.monster_max_aspd) * 2);
}
- return 4000;
}
-int battle_get_amotion (struct block_list *bl)
+interval_t battle_get_amotion(struct block_list *bl)
{
- nullpo_retr (2000, bl);
- if (bl->type == BL_PC && (struct map_session_data *) bl)
+ nullpo_retr(std::chrono::seconds(2), bl);
+ if (bl->type == BL::PC)
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)->mob_class].amotion;
+ eptr<struct status_change, StatusChange> sc_data = battle_get_sc_data(bl);
+ interval_t amotion = std::chrono::seconds(2);
+ int aspd_rate = 100;
+ if (bl->type == BL::MOB)
+ amotion = static_cast<interval_t>(mob_db[((struct mob_data *) bl)->mob_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].val1;
- if (sc_data[SC_HASTE].timer != -1)
- aspd_rate -= sc_data[SC_HASTE].val1;
- if (sc_data[SC_DEFENDER].timer != -1)
- amotion += (550 - sc_data[SC_DEFENDER].val1 * 50);
+ if (sc_data[StatusChange::SC_SPEEDPOTION0].timer)
+ aspd_rate -= sc_data[StatusChange::SC_SPEEDPOTION0].val1;
+ if (sc_data[StatusChange::SC_HASTE].timer)
+ aspd_rate -= sc_data[StatusChange::SC_HASTE].val1;
}
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 std::max(amotion, static_cast<interval_t>(battle_config.monster_max_aspd));
}
- return 2000;
}
-int battle_get_dmotion (struct block_list *bl)
+interval_t 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)
+ nullpo_retr(interval_t::zero(), bl);
+ if (bl->type == BL::MOB)
{
- ret = mob_db[((struct mob_data *) bl)->mob_class].dmotion;
- if (battle_config.monster_damage_delay_rate != 100)
- ret = ret * battle_config.monster_damage_delay_rate / 400;
+ return static_cast<interval_t>(mob_db[((struct mob_data *) bl)->mob_class].dmotion);
}
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
+ else if (bl->type == BL::PC)
{
- ret = ((struct map_session_data *) bl)->dmotion;
- if (battle_config.pc_damage_delay_rate != 100)
- ret = ret * battle_config.pc_damage_delay_rate / 400;
+ return ((struct map_session_data *) bl)->dmotion;
}
else
- return 2000;
-
- if ((sc_data && sc_data[SC_ENDURE].timer != -1) ||
- (bl->type == BL_PC
- && ((struct map_session_data *) bl)->special_state.infinite_endure))
- ret = 0;
-
- return ret;
+ return std::chrono::seconds(2);
}
-int battle_get_element (struct block_list *bl)
+LevelElement battle_get_element(struct block_list *bl)
{
- int ret = 20;
- struct status_change *sc_data;
+ LevelElement ret = {2, Element::neutral};
- nullpo_retr (ret, bl);
- sc_data = battle_get_sc_data (bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl) // 10の位=Lv*2、1の位=属性
+ nullpo_retr(ret, bl);
+ if (bl->type == BL::MOB) // 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
-
- 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;
-
- 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)
+int battle_get_party_id(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_PC && (struct map_session_data *) bl)
+ nullpo_ret(bl);
+ if (bl->type == BL::PC)
return ((struct map_session_data *) bl)->status.party_id;
- else if (bl->type == BL_MOB && (struct mob_data *) bl)
+ else if (bl->type == BL::MOB)
{
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)->mob_class;
- else if (bl->type == BL_SKILL && (struct skill_unit *) bl)
- return ((struct skill_unit *) bl)->group->guild_id;
- else
- return 0;
+ return 0;
}
-int battle_get_race (struct block_list *bl)
+Race battle_get_race(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_retr(Race::formless, bl);
+ if (bl->type == BL::MOB)
return mob_db[((struct mob_data *) bl)->mob_class].race;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
- return 7;
- 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)->mob_class].size;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
- return 1;
+ else if (bl->type == BL::PC)
+ return Race::demihuman;
else
- return 1;
+ return Race::formless;
}
-int battle_get_mode (struct block_list *bl)
+MobMode battle_get_mode(struct block_list *bl)
{
- nullpo_retr (0x01, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_retr(MobMode::CAN_MOVE, bl);
+ if (bl->type == BL::MOB)
return mob_db[((struct mob_data *) bl)->mob_class].mode;
- else
- return 0x01; // とりあえず動くということで1
+ // とりあえず動くということで1
+ return MobMode::CAN_MOVE;
}
-int battle_get_mexp (struct block_list *bl)
-{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
- {
- const struct mob_data *mob = (struct mob_data *) bl;
- const int retval =
- (mob_db[mob->mob_class].mexp *
- (int) (mob->stats[MOB_XP_BONUS])) >> MOB_XP_BONUS_SHIFT;
- fprintf (stderr, "Modifier of %x: -> %d\n", mob->stats[MOB_XP_BONUS],
- retval);
- return retval;
- }
- else
- return 0;
-}
-
-int battle_get_stat (int stat_id /* SP_VIT or similar */ ,
- struct block_list *bl)
+int battle_get_stat(SP stat_id, struct block_list *bl)
{
switch (stat_id)
{
- case SP_STR:
- return battle_get_str (bl);
- case SP_AGI:
- return battle_get_agi (bl);
- case SP_DEX:
- return battle_get_dex (bl);
- case SP_VIT:
- return battle_get_vit (bl);
- case SP_INT:
- return battle_get_int (bl);
- case SP_LUK:
- return battle_get_luk (bl);
+ case SP::STR:
+ return battle_get_str(bl);
+ case SP::AGI:
+ return battle_get_agi(bl);
+ case SP::DEX:
+ return battle_get_dex(bl);
+ case SP::VIT:
+ return battle_get_vit(bl);
+ case SP::INT:
+ return battle_get_int(bl);
+ case SP::LUK:
+ return battle_get_luk(bl);
default:
return 0;
}
}
// StatusChange系の所得
-struct status_change *battle_get_sc_data (struct block_list *bl)
+eptr<struct status_change, StatusChange> 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;
+ nullpo_retr(nullptr, bl);
+
+ switch (bl->type)
+ {
+ case BL::MOB:
+ return ((struct mob_data *)(bl))->sc_data;
+ case BL::PC:
+ return ((struct map_session_data *)(bl))->sc_data;
+ }
+ return nullptr;
}
-short *battle_get_sc_count (struct block_list *bl)
+short *battle_get_sc_count(struct block_list *bl)
{
- nullpo_retr (NULL, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_retr(NULL, bl);
+ if (bl->type == BL::MOB)
return &((struct mob_data *) bl)->sc_count;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
+ else if (bl->type == BL::PC)
return &((struct map_session_data *) bl)->sc_count;
return NULL;
}
-short *battle_get_opt1 (struct block_list *bl)
+Opt1 *battle_get_opt1(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
return &((struct mob_data *) bl)->opt1;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
+ else if (bl->type == BL::PC)
return &((struct map_session_data *) bl)->opt1;
- else if (bl->type == BL_NPC && (struct npc_data *) bl)
+ 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)
+Opt2 *battle_get_opt2(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
return &((struct mob_data *) bl)->opt2;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
+ else if (bl->type == BL::PC)
return &((struct map_session_data *) bl)->opt2;
- else if (bl->type == BL_NPC && (struct npc_data *) bl)
+ 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)
+Opt3 *battle_get_opt3(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
return &((struct mob_data *) bl)->opt3;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
+ else if (bl->type == BL::PC)
return &((struct map_session_data *) bl)->opt3;
- else if (bl->type == BL_NPC && (struct npc_data *) bl)
+ 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)
+Option *battle_get_option(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB && (struct mob_data *) bl)
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
return &((struct mob_data *) bl)->option;
- else if (bl->type == BL_PC && (struct map_session_data *) bl)
+ else if (bl->type == BL::PC)
return &((struct map_session_data *) bl)->status.option;
- else if (bl->type == BL_NPC && (struct npc_data *) bl)
+ else if (bl->type == BL::NPC && (struct npc_data *) bl)
return &((struct npc_data *) bl)->option;
return 0;
}
@@ -1424,45 +910,15 @@ short *battle_get_option (struct block_list *bl)
struct battle_delay_damage_
{
struct block_list *src, *target;
- int damage;
- int flag;
+ int damage;
+ int flag;
};
-static
-void battle_delay_damage_sub (timer_id tid, tick_t tick, custom_id_t id, custom_data_t 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);
-}
-
-int battle_delay_damage (unsigned int tick, struct block_list *src,
- struct block_list *target, int damage, int flag)
-{
- struct battle_delay_damage_ *dat;
- CREATE (dat, struct battle_delay_damage_, 1);
-
- nullpo_retr (0, src);
- nullpo_retr (0, target);
-
- dat->src = src;
- dat->target = target;
- dat->damage = damage;
- dat->flag = flag;
- add_timer (tick, battle_delay_damage_sub, src->id, (int) dat);
- return 0;
-}
// 実際にHPを操作
-int battle_damage (struct block_list *bl, struct block_list *target,
+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);
- short *sc_count;
- int i;
-
- nullpo_retr (0, target); //blはNULLで呼ばれることがあるので他でチェック
+ nullpo_ret(target); //blはNULLで呼ばれることがあるので他でチェック
if (damage == 0)
return 0;
@@ -1474,371 +930,90 @@ int battle_damage (struct block_list *bl, struct block_list *target,
{
if (bl->prev == NULL)
return 0;
-
- if (bl->type == BL_PC)
- sd = (struct map_session_data *) bl;
}
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 (sc_data[SC_FREEZE].timer != -1)
- skill_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);
- if (sc_data[SC_SLEEP].timer != -1)
- skill_status_change_end (target, SC_SLEEP, -1);
- }
+ return battle_heal(bl, target, -damage, 0, flag);
- if (target->type == BL_MOB)
+ if (target->type == BL::MOB)
{ // MOB
struct mob_data *md = (struct mob_data *) target;
- if (md && md->skilltimer != -1 && md->state.skillcastcancel) // 詠唱妨害
- skill_castcancel (target, 0);
- return mob_damage (bl, md, damage, 0);
+ if (md && md->skilltimer && md->state.skillcastcancel) // 詠唱妨害
+ skill_castcancel(target, 0);
+ return mob_damage(bl, md, damage, 0);
}
- else if (target->type == BL_PC)
+ else if (target->type == BL::PC)
{ // PC
struct map_session_data *tsd = (struct map_session_data *) target;
- if (tsd && tsd->sc_data && tsd->sc_data[SC_DEVOTION].val1)
- { // ディボーションをかけられている
- struct map_session_data *md =
- map_id2sd (tsd->sc_data[SC_DEVOTION].val1);
- if (md && skill_devotion3 (&md->bl, target->id))
- {
- skill_devotion (md, target->id);
- }
- else if (md && bl)
- for (i = 0; i < 5; i++)
- if (md->dev.val1[i] == target->id)
- {
- clif_damage (bl, &md->bl, gettick (), 0, 0,
- damage, 0, 0, 0);
- pc_damage (&md->bl, md, damage);
-
- return 0;
- }
- }
-
- if (tsd && tsd->skilltimer != -1)
- { // 詠唱妨害
- // フェンカードや妨害されないスキルかの検査
- if ((!tsd->special_state.no_castcancel || map[bl->m].flag.gvg)
- && tsd->state.skillcastcancel
- && !tsd->special_state.no_castcancel2)
- skill_castcancel (target, 0);
- }
-
- return pc_damage (bl, tsd, damage);
+ return pc_damage(bl, tsd, damage);
}
- else if (target->type == BL_SKILL)
- return skill_unit_ondamaged ((struct skill_unit *) target, bl, damage,
- gettick ());
return 0;
}
-int battle_heal (struct block_list *bl, struct block_list *target, int hp,
+int battle_heal(struct block_list *bl, struct block_list *target, int hp,
int sp, int flag)
{
- nullpo_retr (0, target); //blはNULLで呼ばれることがあるので他でチェック
+ nullpo_ret(target); //blはNULLで呼ばれることがあるので他でチェック
- if (target->type == BL_PC
- && pc_isdead ((struct map_session_data *) target))
+ if (target->type == BL::PC
+ && pc_isdead((struct map_session_data *) target))
return 0;
if (hp == 0 && sp == 0)
return 0;
if (hp < 0)
- return battle_damage (bl, target, -hp, flag);
+ return battle_damage(bl, target, -hp, flag);
- if (target->type == BL_MOB)
- return mob_heal ((struct mob_data *) target, hp);
- else if (target->type == BL_PC)
- return pc_heal ((struct map_session_data *) target, hp, sp);
+ if (target->type == BL::MOB)
+ return mob_heal((struct mob_data *) target, hp);
+ else if (target->type == BL::PC)
+ return pc_heal((struct map_session_data *) target, hp, sp);
return 0;
}
// 攻撃停止
-int battle_stopattack (struct block_list *bl)
+int battle_stopattack(struct block_list *bl)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB)
- return mob_stopattack ((struct mob_data *) bl);
- else if (bl->type == BL_PC)
- return pc_stopattack ((struct map_session_data *) bl);
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
+ return mob_stopattack((struct mob_data *) bl);
+ else if (bl->type == BL::PC)
+ return pc_stopattack((struct map_session_data *) bl);
return 0;
}
// 移動停止
-int battle_stopwalking (struct block_list *bl, int type)
+int battle_stopwalking(struct block_list *bl, int type)
{
- nullpo_retr (0, bl);
- if (bl->type == BL_MOB)
- return mob_stop_walking ((struct mob_data *) bl, type);
- else if (bl->type == BL_PC)
- return pc_stop_walking ((struct map_session_data *) bl, type);
+ nullpo_ret(bl);
+ if (bl->type == BL::MOB)
+ return mob_stop_walking((struct mob_data *) bl, type);
+ else if (bl->type == BL::PC)
+ return pc_stop_walking((struct map_session_data *) bl, type);
return 0;
}
/*==========================================
- * ダメージの属性修正
- *------------------------------------------
- */
-int battle_attr_fix (int damage, int atk_elem, int def_elem)
-{
- int def_type = def_elem % 10, def_lv = def_elem / 10 / 2;
-
- if (atk_elem < 0 || atk_elem > 9 || def_type < 0 || def_type > 9 ||
- def_lv < 1 || def_lv > 4)
- { // 属 性値がおかしいのでとりあえずそのまま返す
- if (battle_config.error_log)
- printf
- ("battle_attr_fix: unknown attr type: atk=%d def_type=%d def_lv=%d\n",
- atk_elem, def_type, def_lv);
- return damage;
- }
-
- return damage * attr_fix_table[def_lv - 1][atk_elem][def_type] / 100;
-}
-
-/*==========================================
* ダメージ最終計算
*------------------------------------------
*/
-int battle_calc_damage (struct block_list *src, struct block_list *bl,
- int damage, int div_, int skill_num, int skill_lv,
- int flag)
+static
+int battle_calc_damage(struct block_list *, struct block_list *bl,
+ int damage, int div_,
+ SkillID, int, BF flag)
{
- struct map_session_data *sd = NULL;
struct mob_data *md = NULL;
- struct status_change *sc_data, *sc;
- short *sc_count;
- int class_;
- nullpo_retr (0, bl);
+ nullpo_ret(bl);
- class_ = battle_get_class (bl);
- if (bl->type == BL_MOB)
+ 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);
-
- 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)
- {
- // セーフティウォール
- 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;
- }
- if (sc_data[SC_PNEUMA].timer != -1 && damage > 0 && flag & BF_WEAPON
- && flag & BF_LONG && skill_num != NPC_GUIDEDATTACK)
- {
- // ニューマ
- damage = 0;
- }
-
- if (sc_data[SC_ROKISWEIL].timer != -1 && damage > 0 &&
- flag & BF_MAGIC)
- {
- // ニューマ
- damage = 0;
- }
-
- if (sc_data[SC_AETERNA].timer != -1 && damage > 0)
- { // レックスエーテルナ
- damage <<= 1;
- skill_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;
- }
-
- 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;
- }
-
- 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;
- }
-
- if (sc_data[SC_ENERGYCOAT].timer != -1 && damage > 0
- && flag & BF_WEAPON)
- { // エナジーコート
- if (sd)
- {
- if (sd->status.sp > 0)
- {
- int per = sd->status.sp * 5 / (sd->status.max_sp + 1);
- sd->status.sp -= sd->status.sp * (per * 5 + 10) / 1000;
- if (sd->status.sp < 0)
- sd->status.sp = 0;
- damage -= damage * ((per + 1) * 6) / 100;
- clif_updatestatus (sd, SP_SP);
- }
- if (sd->status.sp <= 0)
- skill_status_change_end (bl, SC_ENERGYCOAT, -1);
- }
- else
- damage -= damage * (sc_data[SC_ENERGYCOAT].val1 * 6) / 100;
- }
-
- if (sc_data[SC_KYRIE].timer != -1 && damage > 0)
- { // キリエエレイソン
- sc = &sc_data[SC_KYRIE];
- sc->val2 -= damage;
- if (flag & BF_WEAPON)
- {
- if (sc->val2 >= 0)
- damage = 0;
- else
- damage = -sc->val2;
- }
- if ((--sc->val3) <= 0 || (sc->val2 <= 0)
- || skill_num == AL_HOLYLIGHT)
- skill_status_change_end (bl, SC_KYRIE, -1);
- }
-
- if (sc_data[SC_BASILICA].timer != -1 && damage > 0)
- {
- // ニューマ
- damage = 0;
- }
- if (sc_data[SC_LANDPROTECTOR].timer != -1 && damage > 0
- && flag & BF_MAGIC)
- {
- // ニューマ
- damage = 0;
- }
-
- if (sc_data[SC_AUTOGUARD].timer != -1 && damage > 0
- && flag & BF_WEAPON)
- {
- if (MRAND (100) < sc_data[SC_AUTOGUARD].val2)
- {
- damage = 0;
- clif_skill_nodamage (bl, bl, CR_AUTOGUARD,
- sc_data[SC_AUTOGUARD].val1, 1);
- if (sd)
- sd->canmove_tick = gettick () + 300;
- else if (md)
- md->canmove_tick = gettick () + 300;
- }
- }
-// -- moonsoul (chance to block attacks with new Lord Knight skill parrying)
-//
- if (sc_data[SC_PARRYING].timer != -1 && damage > 0
- && flag & BF_WEAPON)
- {
- if (MRAND (100) < sc_data[SC_PARRYING].val2)
- {
- damage = 0;
- clif_skill_nodamage (bl, bl, LK_PARRYING,
- sc_data[SC_PARRYING].val1, 1);
- }
- }
- // リジェクトソード
- 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))
- {
- if (MRAND (100) < (10 + 5 * sc_data[SC_REJECTSWORD].val1))
- { //反射確率は10+5*Lv
- damage = damage * 50 / 100;
- 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);
- }
- }
- }
-
- if (class_ == 1288 || class_ == 1287 || class_ == 1286 || class_ == 1285)
- {
-// if(class == 1288) {
- if (class_ == 1288 && flag & BF_SKILL)
- 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]
- damage = 0; // end woe check [Valaris]
- if (g == NULL)
- damage = 0; //ギルド未加入ならダメージ無し
- else if ((gc != NULL) && guild_isallied (g, gc))
- damage = 0; //自占領ギルドのエンペならダメージ無し
- 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]
- }
- else
- damage = 0;
- }
-
- if (map[bl->m].flag.gvg && damage > 0)
- { //GvG
- if (flag & BF_WEAPON)
- {
- if (flag & BF_SHORT)
- damage = damage * battle_config.gvg_short_damage_rate / 100;
- if (flag & BF_LONG)
- damage = damage * battle_config.gvg_long_damage_rate / 100;
- }
- if (flag & BF_MAGIC)
- damage = damage * battle_config.gvg_magic_damage_rate / 100;
- if (flag & BF_MISC)
- damage = damage * battle_config.gvg_misc_damage_rate / 100;
- if (damage < 1)
- damage = 1;
- }
-
- if (battle_config.skill_min_damage || flag & BF_MISC)
+ if (battle_config.skill_min_damage
+ || bool(flag & BF::MISC))
{
if (div_ < 255)
{
@@ -1850,258 +1025,56 @@ int battle_calc_damage (struct block_list *src, struct block_list *bl,
}
if (md != NULL && md->hp > 0 && damage > 0) // 反撃などのMOBスキル判定
- mobskill_event (md, flag);
+ mobskill_event(md, flag);
return damage;
}
-/*==========================================
- * 修練ダメージ
- *------------------------------------------
- */
static
-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 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))
- damage += (skill * 3);
-
- // ビーストベイン(+4 〜 +40) vs 動物 or 昆虫
- if ((skill = pc_checkskill (sd, HT_BEASTBANE)) > 0
- && (race == 2 || race == 4))
- damage += (skill * 4);
-
- if (type == 0)
- weapon = sd->weapontype1;
- else
- weapon = sd->weapontype2;
- switch (weapon)
- {
- case 0x01: // 短剣 (Updated By AppleGirl)
- case 0x02: // 1HS
- {
- // 剣修練(+4 〜 +40) 片手剣 短剣含む
- if ((skill = pc_checkskill (sd, SM_SWORD)) > 0)
- {
- damage += (skill * 4);
- }
- break;
- }
- case 0x03: // 2HS
- {
- // 両手剣修練(+4 〜 +40) 両手剣
- if ((skill = pc_checkskill (sd, SM_TWOHAND)) > 0)
- {
- damage += (skill * 4);
- }
- 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) 槍
- if ((skill = pc_checkskill (sd, KN_SPEARMASTERY)) > 0)
- {
- if (!pc_isriding (sd))
- damage += (skill * 4); // ペコに乗ってない
- else
- damage += (skill * 5); // ペコに乗ってる
- }
- break;
- }
- case 0x06: // 片手斧
- {
- if ((skill = pc_checkskill (sd, AM_AXEMASTERY)) > 0)
- {
- damage += (skill * 3);
- }
- break;
- }
- case 0x07: // Axe by Tato
- {
- if ((skill = pc_checkskill (sd, AM_AXEMASTERY)) > 0)
- {
- damage += (skill * 3);
- }
- break;
- }
- case 0x08: // メイス
- {
- // メイス修練(+3 〜 +30) メイス
- if ((skill = pc_checkskill (sd, PR_MACEMASTERY)) > 0)
- {
- damage += (skill * 3);
- }
- break;
- }
- case 0x09: // なし?
- break;
- case 0x0a: // 杖
- break;
- case 0x0b: // 弓
- break;
- case 0x00: // 素手
- case 0x0c: // Knuckles
- {
- // 鉄拳(+3 〜 +30) 素手,ナックル
- if ((skill = pc_checkskill (sd, MO_IRONHAND)) > 0)
- {
- damage += (skill * 3);
- }
- break;
- }
- case 0x0d: // Musical Instrument
- {
- // 楽器の練習(+3 〜 +30) 楽器
- if ((skill = pc_checkskill (sd, BA_MUSICALLESSON)) > 0)
- {
- damage += (skill * 3);
- }
- break;
- }
- case 0x0e: // Dance Mastery
- {
- // Dance Lesson Skill Effect(+3 damage for every lvl = +30) 鞭
- if ((skill = pc_checkskill (sd, DC_DANCINGLESSON)) > 0)
- {
- damage += (skill * 3);
- }
- break;
- }
- case 0x0f: // Book
- {
- // Advance Book Skill Effect(+3 damage for every lvl = +30) {
- if ((skill = pc_checkskill (sd, SA_ADVANCEDBOOK)) > 0)
- {
- damage += (skill * 3);
- }
- break;
- }
- case 0x10: // Katars
- {
- // カタール修練(+3 〜 +30) カタール
- if ((skill = pc_checkskill (sd, AS_KATAR)) > 0)
- {
- //ソニックブロー時は別処理(1撃に付き1/8適応)
- damage += (skill * 3);
- }
- break;
- }
- }
- damage = dmg + damage;
- return (damage);
-}
-
-static struct Damage battle_calc_mob_weapon_attack (struct block_list *src,
+struct Damage battle_calc_mob_weapon_attack(struct block_list *src,
struct block_list *target,
- int skill_num,
- int skill_lv, int wflag)
+ SkillID skill_num,
+ int skill_lv, int)
{
struct map_session_data *tsd = NULL;
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);
- 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;
- struct status_change *sc_data, *t_sc_data;
- short *sc_count;
- short *option, *opt1, *opt2;
-
- //return前の処理があるので情報出力部のみ変更
- if (src == NULL || target == NULL || md == NULL)
- {
- nullpo_info (NLP_MARK);
- memset (&wd, 0, sizeof (wd));
- 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);
+ int hitrate, flee, cri = 0, atkmin, atkmax;
+ int target_count = 1;
+ int def1 = battle_get_def(target);
+ int def2 = battle_get_def2(target);
+ int t_vit = battle_get_vit(target);
+ struct Damage wd {};
+ int damage, damage2 = 0;
+ DamageType type;
+ int div_;
+ BF flag;
+ int ac_flag = 0;
+ ATK dmg_lv = ATK::ZERO;
+ eptr<struct status_change, StatusChange> sc_data, t_sc_data;
+
+ nullpo_retr(wd, src);
+ nullpo_retr(wd, target);
+ nullpo_retr(wd, md);
+
+ sc_data = battle_get_sc_data(src);
// ターゲット
- if (target->type == BL_PC)
+ if (target->type == BL::PC)
tsd = (struct map_session_data *) target;
- else if (target->type == BL_MOB)
+ 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 (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 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);
- 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;
- }
- return wd;
- }
- else
- ac_flag = 1;
- }
- }
- flag = BF_SHORT | BF_WEAPON | BF_NORMAL; // 攻撃の種類の設定
+ MobMode t_mode = battle_get_mode(target);
+ t_sc_data = battle_get_sc_data(target);
+
+ flag = BF::SHORT | BF::WEAPON | BF::NORMAL; // 攻撃の種類の設定
// 回避率計算、回避判定は後で
- flee = battle_get_flee (target);
+ 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);
+ battle_counttargeted(target, src,
+ ATK(battle_config.agi_penaly_count_lv)); // FIXME
if (battle_config.agi_penaly_type > 0)
{
if (target_count >= battle_config.agi_penaly_count)
@@ -2122,325 +1095,72 @@ static struct Damage battle_calc_mob_weapon_attack (struct block_list *src,
flee = 1;
}
}
- hitrate = battle_get_hit (src) - flee + 80;
+ hitrate = battle_get_hit(src) - flee + 80;
- type = 0; // normal
+ type = DamageType::NORMAL;
div_ = 1; // single attack
- luk = battle_get_luk (src);
-
if (battle_config.enemy_str)
- damage = battle_get_baseatk (src);
+ damage = battle_get_baseatk(src);
else
damage = 0;
- if (skill_num == HW_MAGICCRASHER)
- { /* マジッククラッシャーはMATKで殴る */
- atkmin = battle_get_matk1 (src);
- atkmax = battle_get_matk2 (src);
- }
- else
{
- atkmin = battle_get_atk (src);
- atkmax = battle_get_atk2 (src);
+ atkmin = battle_get_atk(src);
+ atkmax = battle_get_atk2(src);
}
if (mob_db[md->mob_class].range > 3)
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
+ flag = (flag & ~BF::RANGEMASK) | BF::LONG;
if (atkmin > atkmax)
atkmin = atkmax;
- if (sc_data != NULL && sc_data[SC_MAXIMIZEPOWER].timer != -1)
- { // マキシマイズパワー
- atkmin = atkmax;
- }
-
- cri = battle_get_critical (src);
- cri -= battle_get_luk (target) * 3;
+ cri = battle_get_critical(src);
+ cri -= battle_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 (ac_flag)
cri = 1000;
- if (skill_num == KN_AUTOCOUNTER)
- {
- if (!(battle_config.monster_auto_counter_type & 1))
- cri = 1000;
- else
- cri <<= 1;
- }
-
if (tsd && tsd->critical_def)
cri = cri * (100 - tsd->critical_def) / 100;
- if ((skill_num == 0 || skill_num == KN_AUTOCOUNTER) && skill_lv >= 0 && battle_config.enemy_critical && (MRAND (1000)) < cri) // 判定(スキルの場合は無視)
+ if ((skill_num == SkillID::ZERO)
+ && skill_lv >= 0 && battle_config.enemy_critical
+ && random_::chance({cri, 1000}))
+ // 判定(スキルの場合は無視)
// 敵の判定
{
damage += atkmax;
- type = 0x0a;
+ type = DamageType::CRITICAL;
}
else
{
- int vitbonusmax;
+ int vitbonusmax;
if (atkmax > atkmin)
- damage += atkmin + MRAND ((atkmax - atkmin + 1));
+ damage += random_::in(atkmin, atkmax);
else
damage += atkmin;
- // スキル修正1(攻撃力倍化系)
- // オーバートラスト(+5% 〜 +25%),他攻撃系スキルの場合ここで補正
- // バッシュ,マグナムブレイク,
- // ボーリングバッシュ,スピアブーメラン,ブランディッシュスピア,スピアスタッブ,
- // メマーナイト,カートレボリューション
- // ダブルストレイフィング,アローシャワー,チャージアロー,
- // ソニックブロー
- if (sc_data)
- { //状態異常中のダメージ追加
- if (sc_data[SC_OVERTHRUST].timer != -1) // オーバートラスト
- 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;
- if (sc_data[SC_BERSERK].timer != -1) // バーサーク
- damage += damage * 50 / 100;
- }
- if (skill_num > 0)
+ if (skill_num != SkillID::ZERO && skill_num != SkillID::NEGATIVE)
{
- int i;
- if ((i = skill_get_pl (skill_num)) > 0)
- s_ele = i;
-
- flag = (flag & ~BF_SKILLMASK) | BF_SKILL;
- switch (skill_num)
- {
- case SM_BASH: // バッシュ
- damage = damage * (100 + 30 * skill_lv) / 100;
- hitrate = (hitrate * (100 + 5 * skill_lv)) / 100;
- break;
- case SM_MAGNUM: // マグナムブレイク
- damage =
- damage * (5 * skill_lv + (wflag) ? 65 : 115) / 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: // アローシャワー
- damage = damage * (75 + 5 * skill_lv) / 100;
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
- break;
- case AC_CHARGEARROW: // チャージアロー
- damage = damage * 150 / 100;
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
- break;
- case KN_PIERCE: // ピアース
- damage = damage * (100 + 10 * skill_lv) / 100;
- hitrate = hitrate * (100 + 5 * skill_lv) / 100;
- div_ = t_size + 1;
- damage *= div_;
- break;
- case KN_SPEARSTAB: // スピアスタブ
- damage = damage * (100 + 15 * skill_lv) / 100;
- break;
- case KN_SPEARBOOMERANG: // スピアブーメラン
- damage = damage * (100 + 50 * skill_lv) / 100;
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
- break;
- case KN_BRANDISHSPEAR: // ブランディッシュスピア
- damage = damage * (100 + 20 * skill_lv) / 100;
- if (skill_lv > 3 && wflag == 1)
- damage2 += damage / 2;
- if (skill_lv > 6 && wflag == 1)
- damage2 += damage / 4;
- if (skill_lv > 9 && wflag == 1)
- damage2 += damage / 8;
- if (skill_lv > 6 && wflag == 2)
- damage2 += damage / 2;
- 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 KN_AUTOCOUNTER:
- if (battle_config.monster_auto_counter_type & 1)
- hitrate += 20;
- else
- hitrate = 1000000;
- flag = (flag & ~BF_SKILLMASK) | BF_NORMAL;
- break;
- case AS_SONICBLOW: // ソニックブロウ
- damage = damage * (300 + 50 * skill_lv) / 100;
- div_ = 8;
- break;
- case TF_SPRINKLESAND: // 砂まき
- damage = damage * 125 / 100;
- break;
- case MC_CARTREVOLUTION: // カートレボリューション
- damage = (damage * 150) / 100;
- break;
- // 以下MOB
- case NPC_COMBOATTACK: // 多段攻撃
- div_ = skill_get_num (skill_num, skill_lv);
- damage *= div_;
- break;
- case NPC_RANDOMATTACK: // ランダムATK攻撃
- damage = damage * (MPRAND (50, 150)) / 100;
- break;
- // 属性攻撃(適当)
- case NPC_WATERATTACK:
- case NPC_GROUNDATTACK:
- case NPC_FIREATTACK:
- case NPC_WINDATTACK:
- case NPC_POISONATTACK:
- case NPC_HOLYATTACK:
- case NPC_DARKNESSATTACK:
- case NPC_TELEKINESISATTACK:
- damage = damage * (100 + 25 * (skill_lv - 1)) / 100;
- break;
- case NPC_GUIDEDATTACK:
- hitrate = 1000000;
- break;
- case NPC_RANGEATTACK:
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
- break;
- case NPC_PIERCINGATT:
- flag = (flag & ~BF_RANGEMASK) | BF_SHORT;
- break;
- case RG_BACKSTAP: // バックスタブ
- damage = damage * (300 + 40 * skill_lv) / 100;
- hitrate = 1000000;
- break;
- case RG_RAID: // サプライズアタック
- damage = damage * (100 + 40 * skill_lv) / 100;
- break;
- case RG_INTIMIDATE: // インティミデイト
- damage = damage * (100 + 30 * skill_lv) / 100;
- break;
- case CR_SHIELDCHARGE: // シールドチャージ
- damage = damage * (100 + 20 * skill_lv) / 100;
- flag = (flag & ~BF_RANGEMASK) | BF_SHORT;
- s_ele = 0;
- break;
- case CR_SHIELDBOOMERANG: // シールドブーメラン
- damage = damage * (100 + 30 * skill_lv) / 100;
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
- s_ele = 0;
- break;
- case CR_HOLYCROSS: // ホーリークロス
- damage = damage * (100 + 35 * skill_lv) / 100;
- div_ = 2;
- break;
- case CR_GRANDCROSS:
- hitrate = 1000000;
- break;
- case AM_DEMONSTRATION: // デモンストレーション
- damage = damage * (100 + 20 * skill_lv) / 100;
- damage2 = damage2 * (100 + 20 * skill_lv) / 100;
- break;
- case AM_ACIDTERROR: // アシッドテラー
- damage = damage * (100 + 40 * skill_lv) / 100;
- damage2 = damage2 * (100 + 40 * skill_lv) / 100;
- break;
- case MO_FINGEROFFENSIVE: //指弾
- damage = damage * (100 + 50 * skill_lv) / 100;
- div_ = 1;
- break;
- case MO_INVESTIGATE: // 発 勁
- if (def1 < 1000000)
- damage =
- damage * (100 + 75 * skill_lv) / 100 * (def1 +
- def2) /
- 100;
- hitrate = 1000000;
- s_ele = 0;
- break;
- case MO_EXTREMITYFIST: // 阿修羅覇鳳拳
- damage = damage * 8 + 250 + (skill_lv * 150);
- hitrate = 1000000;
- s_ele = 0;
- break;
- case MO_CHAINCOMBO: // 連打掌
- damage = damage * (150 + 50 * skill_lv) / 100;
- div_ = 4;
- break;
- case BA_MUSICALSTRIKE: // ミュージカルストライク
- damage = damage * (100 + 50 * skill_lv) / 100;
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
- break;
- case DC_THROWARROW: // 矢撃ち
- damage = damage * (100 + 50 * 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;
- break;
- case CH_CHAINCRUSH: // 連柱崩撃
- damage = damage * (100 + 20 * skill_lv) / 100;
- div_ = skill_get_num (skill_num, skill_lv);
- break;
- case CH_PALMSTRIKE: // 猛虎硬派山
- damage = damage * (50 + 100 * skill_lv) / 100;
- break;
- case LK_SPIRALPIERCE: /* スパイラルピアース */
- damage = damage * (100 + 50 * skill_lv) / 100; //増加量が分からないので適当に
- div_ = 5;
- if (tsd)
- tsd->canmove_tick = gettick () + 1000;
- else if (tmd)
- tmd->canmove_tick = gettick () + 1000;
- break;
- case LK_HEADCRUSH: /* ヘッドクラッシュ */
- damage = damage * (100 + 20 * skill_lv) / 100;
- break;
- case LK_JOINTBEAT: /* ジョイントビート */
- damage = damage * (50 + 10 * skill_lv) / 100;
- break;
- case ASC_METEORASSAULT: /* メテオアサルト */
- damage = damage * (40 + 40 * skill_lv) / 100;
- break;
- case SN_SHARPSHOOTING: /* シャープシューティング */
- damage += damage * (30 * skill_lv) / 100;
- break;
- case CG_ARROWVULCAN: /* アローバルカン */
- damage = damage * (160 + 40 * skill_lv) / 100;
- div_ = 9;
- break;
- case AS_SPLASHER: /* ベナムスプラッシャー */
- damage = damage * (200 + 20 * skill_lv) / 100;
- break;
- }
+ flag = (flag & ~BF::SKILLMASK) | BF::SKILL;
}
- if (skill_num != NPC_CRITICALSLASH)
{
// 対 象の防御力によるダメージの減少
// ディバインプロテクション(ここでいいのかな?)
- if (skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST
- && skill_num != KN_AUTOCOUNTER && def1 < 1000000)
+ if (def1 < 1000000)
{ //DEF, VIT無視
- int t_def;
+ int t_def;
target_count =
- 1 + battle_counttargeted (target, src,
- battle_config.vit_penaly_count_lv);
+ 1 + battle_counttargeted(target, src,
+ ATK(battle_config.vit_penaly_count_lv)); // FIXME
if (battle_config.vit_penaly_type > 0)
{
if (target_count >= battle_config.vit_penaly_count)
@@ -2493,24 +1213,13 @@ static struct Damage battle_calc_mob_weapon_attack (struct block_list *src,
}
}
t_def = def2 * 8 / 10;
- if (battle_check_undead (s_race, battle_get_elem_type (src))
- || s_race == 6)
- if (tsd && (skill = pc_checkskill (tsd, AL_DP)) > 0)
- t_def += skill * 3;
vitbonusmax = (t_vit / 20) * (t_vit / 20) - 1;
- if (battle_config.monster_defense_type)
- {
- damage =
- damage - (def1 * battle_config.monster_defense_type) -
- t_def -
- ((vitbonusmax < 1) ? 0 : MRAND ((vitbonusmax + 1)));
- }
- else
{
- damage =
- damage * (100 - def1) / 100 - t_def -
- ((vitbonusmax < 1) ? 0 : MRAND ((vitbonusmax + 1)));
+ damage = damage * (100 - def1) / 100;
+ damage -= t_def;
+ if (vitbonusmax > 0)
+ damage -= random_::in(0, vitbonusmax);
}
}
}
@@ -2523,143 +1232,68 @@ static struct Damage battle_calc_mob_weapon_attack (struct block_list *src,
// 回避修正
if (hitrate < 1000000)
hitrate = ((hitrate > 95) ? 95 : ((hitrate < 5) ? 5 : hitrate));
- if (hitrate < 1000000 && // 必中攻撃
- (t_sc_data != NULL && (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_STONE].timer != -1 && t_sc_data[SC_STONE].val2 == 0)))) // 凍結は必中
- hitrate = 1000000;
- if (type == 0 && MRAND (100) >= hitrate)
+
+ if (type == DamageType::NORMAL && !random_::chance({hitrate, 100}))
{
damage = damage2 = 0;
- dmg_lv = ATK_FLEE;
+ dmg_lv = ATK::FLEE;
}
else
{
- dmg_lv = ATK_DEF;
- }
-
- if (tsd)
- {
- int cardfix = 100, i;
- cardfix = cardfix * (100 - tsd->subele[s_ele]) / 100; // 属 性によるダメージ耐性
- cardfix = cardfix * (100 - tsd->subrace[s_race]) / 100; // 種族によるダメージ耐性
- if (mob_db[md->mob_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->mob_class)
- {
- cardfix = cardfix * (100 - tsd->add_def_classrate[i]) / 100;
- break;
- }
- }
- if (flag & BF_LONG)
- cardfix = cardfix * (100 - tsd->long_attack_def_rate) / 100;
- if (flag & BF_SHORT)
- cardfix = cardfix * (100 - tsd->near_attack_def_rate) / 100;
- damage = damage * cardfix / 100;
- }
- 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 (cardfix != 100)
- damage = damage * cardfix / 100;
- }
- if (t_sc_data && t_sc_data[SC_ASSUMPTIO].timer != -1)
- { //アシャンプティオ
- if (!map[target->m].flag.pvp)
- damage = damage / 3;
- else
- damage = damage / 2;
+ dmg_lv = ATK::DEF;
}
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 (sc_data && sc_data[SC_AURABLADE].timer != -1) /* オーラブレード 必中 */
- damage += sc_data[SC_AURABLADE].val1 * 10;
- if (skill_num == PA_PRESSURE) /* プレッシャー 必中? */
- damage = 700 + 100 * skill_lv;
-
- // インベナム修正
- if (skill_num == TF_POISON)
- {
- damage =
- battle_attr_fix (damage + 15 * skill_lv, s_ele,
- battle_get_element (target));
- }
- if (skill_num == MC_CARTREVOLUTION)
- {
- damage = battle_attr_fix (damage, 0, battle_get_element (target));
- }
-
// 完全回避の判定
- if (skill_num == 0 && skill_lv >= 0 && tsd != NULL
- && MRAND (1000) < battle_get_flee2 (target))
+ if (skill_num == SkillID::ZERO && skill_lv >= 0 && tsd != NULL
+ && random_::chance({battle_get_flee2(target), 1000}))
{
damage = 0;
- type = 0x0b;
- dmg_lv = ATK_LUCKY;
+ type = DamageType::FLEE2;
+ dmg_lv = ATK::LUCKY;
}
if (battle_config.enemy_perfect_flee)
{
- if (skill_num == 0 && skill_lv >= 0 && tmd != NULL
- && MRAND (1000) < battle_get_flee2 (target))
+ if (skill_num == SkillID::ZERO && skill_lv >= 0 && tmd != NULL
+ && random_::chance({battle_get_flee2(target), 1000}))
{
damage = 0;
- type = 0x0b;
- dmg_lv = ATK_LUCKY;
+ type = DamageType::FLEE2;
+ dmg_lv = ATK::LUCKY;
}
}
// if(def1 >= 1000000 && damage > 0)
- if (t_mode & 0x40 && damage > 0)
+ if (bool(t_mode & MobMode::PLANT) && damage > 0)
damage = 1;
- if (tsd && tsd->special_state.no_weapon_damage)
- damage = 0;
-
- if (skill_num != CR_GRANDCROSS)
- damage =
- battle_calc_damage (src, target, damage, div_, skill_num,
- skill_lv, flag);
+ damage = battle_calc_damage(src, target, damage, div_,
+ skill_num, skill_lv, flag);
wd.damage = damage;
wd.damage2 = 0;
wd.type = type;
wd.div_ = div_;
- wd.amotion = battle_get_amotion (src);
- if (skill_num == KN_AUTOCOUNTER)
- wd.amotion >>= 1;
- wd.dmotion = battle_get_dmotion (target);
- wd.blewcount = blewcount;
+ wd.amotion = battle_get_amotion(src);
+ wd.dmotion = battle_get_dmotion(target);
wd.flag = flag;
wd.dmg_lv = dmg_lv;
return wd;
}
-int battle_is_unarmed (struct block_list *bl)
+int battle_is_unarmed(struct block_list *bl)
{
if (!bl)
return 0;
- if (bl->type == BL_PC)
+ if (bl->type == BL::PC)
{
struct map_session_data *sd = (struct map_session_data *) bl;
- return (sd->equip_index[EQUIP_SHIELD] == -1
- && sd->equip_index[EQUIP_WEAPON] == -1);
+ return (sd->equip_index[EQUIP::SHIELD] == -1
+ && sd->equip_index[EQUIP::WEAPON] == -1);
}
else
return 0;
@@ -2670,104 +1304,57 @@ int battle_is_unarmed (struct block_list *bl)
* PCの武器による攻撃
*-------------------------------------------------------------------------
*/
-static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
+static
+struct Damage battle_calc_pc_weapon_attack(struct block_list *src,
struct block_list *target,
- int skill_num,
- int skill_lv, int wflag)
+ SkillID skill_num,
+ int skill_lv, int)
{
struct map_session_data *sd = (struct map_session_data *) src, *tsd =
NULL;
struct mob_data *tmd = NULL;
- int hitrate, flee, cri = 0, atkmin, atkmax;
- int dex, luk, target_count = 1;
- int def1 = battle_get_def (target);
- int def2 = battle_get_def2 (target);
- int t_vit = battle_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;
- struct status_change *sc_data, *t_sc_data;
- short *sc_count;
- short *option, *opt1, *opt2;
- int atkmax_ = 0, atkmin_ = 0, s_ele_; //二刀流用
- int watk, watk_, cardfix, t_ele;
- int da = 0, i, t_class, ac_flag = 0;
- int idef_flag = 0, idef_flag_ = 0;
- int target_distance;
-
- //return前の処理があるので情報出力部のみ変更
- if (src == NULL || target == NULL || sd == NULL)
- {
- nullpo_info (NLP_MARK);
- memset (&wd, 0, sizeof (wd));
- return wd;
- }
+ int hitrate, flee, cri = 0, atkmin, atkmax;
+ int dex, target_count = 1;
+ int def1 = battle_get_def(target);
+ int def2 = battle_get_def2(target);
+ int t_vit = battle_get_vit(target);
+ struct Damage wd {};
+ int damage, damage2;
+ DamageType type;
+ int div_;
+ BF flag;
+ ATK dmg_lv = ATK::ZERO;
+ eptr<struct status_change, StatusChange> sc_data, t_sc_data;
+ int atkmax_ = 0, atkmin_ = 0; //二刀流用
+ int watk, watk_;
+ bool da = false;
+ int ac_flag = 0;
+ int target_distance;
+
+ nullpo_retr(wd, src);
+ nullpo_retr(wd, target);
+ nullpo_retr(wd, sd);
// アタッカー
- 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); //毒、呪い、沈黙、暗闇?
-
- if (skill_num != CR_GRANDCROSS) //グランドクロスでないなら
- sd->state.attack_type = BF_WEAPON; //攻撃タイプは武器攻撃
+ sc_data = battle_get_sc_data(src); //ステータス異常
+
+ sd->state.attack_type = BF::WEAPON; //攻撃タイプは武器攻撃
// ターゲット
- if (target->type == BL_PC) //対象がPCなら
+ if (target->type == BL::PC) //対象がPCなら
tsd = (struct map_session_data *) target; //tsdに代入(tmdはNULL)
- else if (target->type == BL_MOB) //対象がMobなら
+ 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); //対象のステータス異常
-
-//オートカウンター処理ここから
- 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 != 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 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);
- 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;
- }
- return wd; //ダメージ構造体を返して終了
- }
- else
- ac_flag = 1;
- }
- }
-//オートカウンター処理ここまで
+ MobMode t_mode = battle_get_mode(target); //対象のMode
+ t_sc_data = battle_get_sc_data(target); //対象のステータス異常
- flag = BF_SHORT | BF_WEAPON | BF_NORMAL; // 攻撃の種類の設定
+ flag = BF::SHORT | BF::WEAPON | BF::NORMAL; // 攻撃の種類の設定
// 回避率計算、回避判定は後で
- flee = battle_get_flee (target);
+ 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); //対象の数を算出
+ target_count += battle_counttargeted(target, src,
+ ATK(battle_config.agi_penaly_count_lv)); //対象の数を算出
if (battle_config.agi_penaly_type > 0)
{
if (target_count >= battle_config.agi_penaly_count)
@@ -2788,34 +1375,28 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
flee = 1; //回避率は最低でも1
}
}
- hitrate = battle_get_hit (src) - flee + 80; //命中率計算
+ hitrate = battle_get_hit(src) - flee + 80; //命中率計算
{ // [fate] Reduce hit chance by distance
- int dx = abs (src->x - target->x);
- int dy = abs (src->y - target->y);
- int malus_dist;
+ int dx = abs(src->x - target->x);
+ int dy = abs(src->y - target->y);
+ int malus_dist;
- target_distance = MAX (dx, dy);
+ target_distance = max(dx, dy);
malus_dist =
- MAX (0, target_distance - (skill_power (sd, AC_OWL) / 75));
+ max(0, target_distance - (skill_power(sd, SkillID::AC_OWL) / 75));
hitrate -= (malus_dist * (malus_dist + 1));
}
- 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 = battle_get_dex(src); //DEX
+ watk = battle_get_atk(src); //ATK
+ watk_ = battle_get_atk_(src); //ATK左手
- type = 0; // normal
+ type = DamageType::NORMAL;
div_ = 1; // single attack
- if (skill_num == HW_MAGICCRASHER)
- { /* マジッククラッシャーはMATKで殴る */
- damage = damage2 = battle_get_matk1 (src); //damega,damega2初登場、base_atkの取得
- }
- else
{
- damage = damage2 = battle_get_baseatk (&sd->bl); //damega,damega2初登場、base_atkの取得
+ damage = damage2 = battle_get_baseatk(&sd->bl); //damega,damega2初登場、base_atkの取得
}
if (sd->attackrange > 2)
{ // [fate] ranged weapon?
@@ -2832,45 +1413,23 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
atkmin = atkmin_ = dex; //最低ATKはDEXで初期化?
sd->state.arrow_atk = 0; //arrow_atk初期化
- if (sd->equip_index[9] >= 0 && sd->inventory_data[sd->equip_index[9]])
+ if (sd->equip_index[EQUIP::WEAPON] >= 0 && sd->inventory_data[sd->equip_index[EQUIP::WEAPON]])
atkmin =
atkmin * (80 +
- sd->inventory_data[sd->equip_index[9]]->wlv * 20) / 100;
- if (sd->equip_index[8] >= 0 && sd->inventory_data[sd->equip_index[8]])
+ sd->inventory_data[sd->equip_index[EQUIP::WEAPON]]->wlv * 20) / 100;
+ if (sd->equip_index[EQUIP::SHIELD] >= 0 && sd->inventory_data[sd->equip_index[EQUIP::SHIELD]])
atkmin_ =
atkmin_ * (80 +
- sd->inventory_data[sd->equip_index[8]]->wlv * 20) /
+ sd->inventory_data[sd->equip_index[EQUIP::SHIELD]]->wlv * 20) /
100;
- if (sd->status.weapon == 11)
+ if (sd->status.weapon == ItemLook::BOW)
{ //武器が弓矢の場合
atkmin = watk * ((atkmin < watk) ? atkmin : watk) / 100; //弓用最低ATK計算
- flag = (flag & ~BF_RANGEMASK) | BF_LONG; //遠距離攻撃フラグを有効
- if (sd->arrow_ele > 0) //属性矢なら属性を矢の属性に変更
- s_ele = sd->arrow_ele;
+ flag = (flag & ~BF::RANGEMASK) | BF::LONG; //遠距離攻撃フラグを有効
sd->state.arrow_atk = 1; //arrow_atk有効化
}
- // サイズ修正
- // ペコ騎乗していて、槍で攻撃した場合は中型のサイズ修正を100にする
- // ウェポンパーフェクション,ドレイクC
- if (((sd->special_state.no_sizefix)
- || (pc_isriding (sd)
- && (sd->status.weapon == 4 || sd->status.weapon == 5)
- && t_size == 1) || skill_num == MO_EXTREMITYFIST))
- { //ペコ騎乗していて、槍で中型を攻撃
- atkmax = watk;
- atkmax_ = watk_;
- }
- else
{
- atkmax = (watk * sd->atkmods[t_size]) / 100;
- atkmin = (atkmin * sd->atkmods[t_size]) / 100;
- atkmax_ = (watk_ * sd->atkmods_[t_size]) / 100;
- atkmin_ = (atkmin_ * sd->atkmods[t_size]) / 100;
- }
- if ((sc_data != NULL && sc_data[SC_WEAPONPERFECTION].timer != -1)
- || (sd->special_state.no_sizefix))
- { // ウェポンパーフェクション || ドレイクカード
atkmax = watk;
atkmax_ = watk_;
}
@@ -2880,70 +1439,37 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
if (atkmin_ > atkmax_)
atkmin_ = atkmax_;
- if (sc_data != NULL && sc_data[SC_MAXIMIZEPOWER].timer != -1)
- { // マキシマイズパワー
- atkmin = atkmax;
- atkmin_ = atkmax_;
- }
-
- //ダブルアタック判定
- if (sd->weapontype1 == 0x01)
- {
- if (skill_num == 0 && skill_lv >= 0
- && (skill = pc_checkskill (sd, TF_DOUBLE)) > 0)
- da = (MRAND (100) < (skill * 5)) ? 1 : 0;
- }
-
- //三段掌
- if (skill_num == 0 && skill_lv >= 0
- && (skill = pc_checkskill (sd, MO_TRIPLEATTACK)) > 0
- && sd->status.weapon <= 16 && !sd->state.arrow_atk)
- {
- da = (MRAND (100) < (30 - skill)) ? 2 : 0;
- }
-
- if (sd->double_rate > 0 && da == 0 && skill_num == 0 && skill_lv >= 0)
- da = (MRAND (100) < sd->double_rate) ? 1 : 0;
+ if (sd->double_rate > 0 && skill_num == SkillID::ZERO && skill_lv >= 0)
+ da = random_::chance({sd->double_rate, 100});
// 過剰精錬ボーナス
if (sd->overrefine > 0)
- damage += MPRAND (1, sd->overrefine);
+ damage += random_::in(1, sd->overrefine);
if (sd->overrefine_ > 0)
- damage2 += MPRAND (1, sd->overrefine_);
+ damage2 += random_::in(1, sd->overrefine_);
- if (da == 0)
+ if (!da)
{ //ダブルアタックが発動していない
// クリティカル計算
- cri = battle_get_critical (src);
+ cri = battle_get_critical(src);
if (sd->state.arrow_atk)
cri += sd->arrow_cri;
- if (sd->status.weapon == 16)
+ if (sd->status.weapon == ItemLook::_16)
// カタールの場合、クリティカルを倍に
cri <<= 1;
- cri -= battle_get_luk (target) * 3;
- if (t_sc_data != NULL && t_sc_data[SC_SLEEP].timer != -1) // 睡眠中はクリティカルが倍に
- cri <<= 1;
+ cri -= battle_get_luk(target) * 3;
if (ac_flag)
cri = 1000;
-
- if (skill_num == KN_AUTOCOUNTER)
- {
- if (!(battle_config.pc_auto_counter_type & 1))
- cri = 1000;
- else
- cri <<= 1;
- }
-
- if (skill_num == SN_SHARPSHOOTING && MRAND (100) < 50)
- cri = 1000;
}
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 && //ダブルアタックが発動していない
- (MRAND (1000)) < cri) // 判定(スキルの場合は無視)
+ //ダブルアタックが発動していない
+ // 判定(スキルの場合は無視)
+ if (!da && skill_num == SkillID::ZERO && skill_lv >= 0
+ && random_::chance({cri, 1000}))
{
damage += atkmax;
damage2 += atkmax_;
@@ -2954,49 +1480,18 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
}
if (sd->state.arrow_atk)
damage += sd->arrow_atk;
- type = 0x0a;
-
-/* if(def1 < 1000000) {
- if(sd->def_ratio_atk_ele & (1<<t_ele) || sd->def_ratio_atk_race & (1<<t_race)) {
- damage = (damage * (def1 + def2))/100;
- idef_flag = 1;
- }
- if(sd->def_ratio_atk_ele_ & (1<<t_ele) || sd->def_ratio_atk_race_ & (1<<t_race)) {
- damage2 = (damage2 * (def1 + def2))/100;
- idef_flag_ = 1;
- }
- if(t_mode & 0x20) {
- if(!idef_flag && sd->def_ratio_atk_race & (1<<10)) {
- damage = (damage * (def1 + def2))/100;
- idef_flag = 1;
- }
- if(!idef_flag_ && sd->def_ratio_atk_race_ & (1<<10)) {
- damage2 = (damage2 * (def1 + def2))/100;
- idef_flag_ = 1;
- }
- }
- else {
- if(!idef_flag && sd->def_ratio_atk_race & (1<<11)) {
- damage = (damage * (def1 + def2))/100;
- idef_flag = 1;
- }
- if(!idef_flag_ && sd->def_ratio_atk_race_ & (1<<11)) {
- damage2 = (damage2 * (def1 + def2))/100;
- idef_flag_ = 1;
- }
- }
- }*/
+ type = DamageType::CRITICAL;
}
else
{
- int vitbonusmax;
+ int vitbonusmax;
if (atkmax > atkmin)
- damage += atkmin + MRAND ((atkmax - atkmin + 1));
+ damage += random_::in(atkmin, atkmax);
else
damage += atkmin;
if (atkmax_ > atkmin_)
- damage2 += atkmin_ + MRAND ((atkmax_ - atkmin_ + 1));
+ damage2 += random_::in(atkmin_, atkmax_);
else
damage2 += atkmin_;
if (sd->atk_rate != 100)
@@ -3008,562 +1503,24 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
if (sd->state.arrow_atk)
{
if (sd->arrow_atk > 0)
- damage += MRAND ((sd->arrow_atk + 1));
+ damage += random_::in(0, sd->arrow_atk);
hitrate += sd->arrow_hit;
}
- if (skill_num != MO_INVESTIGATE && def1 < 1000000)
- {
- if (sd->def_ratio_atk_ele & (1 << t_ele)
- || sd->def_ratio_atk_race & (1 << t_race))
- {
- damage = (damage * (def1 + def2)) / 100;
- idef_flag = 1;
- }
- if (sd->def_ratio_atk_ele_ & (1 << t_ele)
- || sd->def_ratio_atk_race_ & (1 << t_race))
- {
- damage2 = (damage2 * (def1 + def2)) / 100;
- idef_flag_ = 1;
- }
- if (t_mode & 0x20)
- {
- if (!idef_flag && sd->def_ratio_atk_race & (1 << 10))
- {
- damage = (damage * (def1 + def2)) / 100;
- idef_flag = 1;
- }
- if (!idef_flag_ && sd->def_ratio_atk_race_ & (1 << 10))
- {
- damage2 = (damage2 * (def1 + def2)) / 100;
- idef_flag_ = 1;
- }
- }
- else
- {
- if (!idef_flag && sd->def_ratio_atk_race & (1 << 11))
- {
- damage = (damage * (def1 + def2)) / 100;
- idef_flag = 1;
- }
- if (!idef_flag_ && sd->def_ratio_atk_race_ & (1 << 11))
- {
- damage2 = (damage2 * (def1 + def2)) / 100;
- idef_flag_ = 1;
- }
- }
- }
-
- // スキル修正1(攻撃力倍化系)
- // オーバートラスト(+5% 〜 +25%),他攻撃系スキルの場合ここで補正
- // バッシュ,マグナムブレイク,
- // ボーリングバッシュ,スピアブーメラン,ブランディッシュスピア,スピアスタッブ,
- // メマーナイト,カートレボリューション
- // ダブルストレイフィング,アローシャワー,チャージアロー,
- // ソニックブロー
- if (sc_data)
- { //状態異常中のダメージ追加
- if (sc_data[SC_OVERTHRUST].timer != -1)
- { // オーバートラスト
- damage += damage * (5 * sc_data[SC_OVERTHRUST].val1) / 100;
- damage2 += damage2 * (5 * sc_data[SC_OVERTHRUST].val1) / 100;
- }
- if (sc_data[SC_TRUESIGHT].timer != -1)
- { // トゥルーサイト
- damage += damage * (2 * sc_data[SC_TRUESIGHT].val1) / 100;
- damage2 += damage2 * (2 * sc_data[SC_TRUESIGHT].val1) / 100;
- }
- if (sc_data[SC_BERSERK].timer != -1)
- { // バーサーク
- damage += damage * 50 / 100;
- damage2 += damage2 * 50 / 100;
- }
- }
-
- if (skill_num > 0)
+ if (skill_num != SkillID::ZERO && skill_num != SkillID::NEGATIVE)
{
- int i;
- if ((i = skill_get_pl (skill_num)) > 0)
- s_ele = s_ele_ = i;
-
- flag = (flag & ~BF_SKILLMASK) | BF_SKILL;
- switch (skill_num)
- {
- case SM_BASH: // バッシュ
- damage = damage * (100 + 30 * skill_lv) / 100;
- damage2 = damage2 * (100 + 30 * skill_lv) / 100;
- 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;
- break;
- case MC_MAMMONITE: // メマーナイト
- damage = damage * (100 + 50 * skill_lv) / 100;
- damage2 = damage2 * (100 + 50 * skill_lv) / 100;
- break;
- case AC_DOUBLE: // ダブルストレイフィング
- if (!sd->state.arrow_atk && sd->arrow_atk > 0)
- {
- int arr = MRAND ((sd->arrow_atk + 1));
- damage += arr;
- damage2 += arr;
- }
- 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;
- }
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
- sd->state.arrow_atk = 1;
- break;
- case AC_SHOWER: // アローシャワー
- if (!sd->state.arrow_atk && sd->arrow_atk > 0)
- {
- int arr = MRAND ((sd->arrow_atk + 1));
- damage += arr;
- damage2 += arr;
- }
- damage = damage * (75 + 5 * skill_lv) / 100;
- damage2 = damage2 * (75 + 5 * 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 AC_CHARGEARROW: // チャージアロー
- if (!sd->state.arrow_atk && sd->arrow_atk > 0)
- {
- int arr = MRAND ((sd->arrow_atk + 1));
- damage += arr;
- damage2 += arr;
- }
- damage = damage * 150 / 100;
- damage2 = damage2 * 150 / 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 KN_PIERCE: // ピアース
- damage = damage * (100 + 10 * skill_lv) / 100;
- damage2 = damage2 * (100 + 10 * skill_lv) / 100;
- hitrate = hitrate * (100 + 5 * skill_lv) / 100;
- div_ = t_size + 1;
- damage *= div_;
- damage2 *= div_;
- break;
- case KN_SPEARSTAB: // スピアスタブ
- damage = damage * (100 + 15 * skill_lv) / 100;
- damage2 = damage2 * (100 + 15 * skill_lv) / 100;
- break;
- case KN_SPEARBOOMERANG: // スピアブーメラン
- damage = damage * (100 + 50 * skill_lv) / 100;
- damage2 = damage2 * (100 + 50 * skill_lv) / 100;
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
- break;
- case KN_BRANDISHSPEAR: // ブランディッシュスピア
- damage = damage * (100 + 20 * skill_lv) / 100;
- damage2 = damage2 * (100 + 20 * skill_lv) / 100;
- if (skill_lv > 3 && wflag == 1)
- damage3 += damage / 2;
- if (skill_lv > 6 && wflag == 1)
- damage3 += damage / 4;
- if (skill_lv > 9 && wflag == 1)
- damage3 += damage / 8;
- if (skill_lv > 6 && wflag == 2)
- damage3 += damage / 2;
- if (skill_lv > 9 && wflag == 2)
- damage3 += damage / 4;
- if (skill_lv > 9 && wflag == 3)
- damage3 += damage / 2;
- damage += damage3;
- if (skill_lv > 3 && wflag == 1)
- damage4 += damage2 / 2;
- if (skill_lv > 6 && wflag == 1)
- damage4 += damage2 / 4;
- if (skill_lv > 9 && wflag == 1)
- damage4 += damage2 / 8;
- if (skill_lv > 6 && wflag == 2)
- damage4 += damage2 / 2;
- 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;
- damage2 = damage2 * (100 + 50 * skill_lv) / 100;
- blewcount = 0;
- break;
- case KN_AUTOCOUNTER:
- if (battle_config.pc_auto_counter_type & 1)
- hitrate += 20;
- else
- hitrate = 1000000;
- flag = (flag & ~BF_SKILLMASK) | BF_NORMAL;
- break;
- case AS_SONICBLOW: // ソニックブロウ
- 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;
- damage2 = damage2 * 125 / 100;
- 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;
- }
- else
- {
- damage = (damage * 150) / 100;
- damage2 = (damage2 * 150) / 100;
- }
- break;
- // 以下MOB
- case NPC_COMBOATTACK: // 多段攻撃
- div_ = skill_get_num (skill_num, skill_lv);
- damage *= div_;
- damage2 *= div_;
- break;
- case NPC_RANDOMATTACK: // ランダムATK攻撃
- damage = damage * (MPRAND (50, 150)) / 100;
- damage2 = damage2 * (MPRAND (50, 150)) / 100;
- break;
- // 属性攻撃(適当)
- case NPC_WATERATTACK:
- case NPC_GROUNDATTACK:
- case NPC_FIREATTACK:
- case NPC_WINDATTACK:
- case NPC_POISONATTACK:
- case NPC_HOLYATTACK:
- case NPC_DARKNESSATTACK:
- case NPC_TELEKINESISATTACK:
- damage = damage * (100 + 25 * skill_lv) / 100;
- damage2 = damage2 * (100 + 25 * skill_lv) / 100;
- break;
- case NPC_GUIDEDATTACK:
- hitrate = 1000000;
- break;
- case NPC_RANGEATTACK:
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
- break;
- case NPC_PIERCINGATT:
- flag = (flag & ~BF_RANGEMASK) | BF_SHORT;
- break;
- case RG_BACKSTAP: // バックスタブ
- if (battle_config.backstab_bow_penalty == 1
- && sd->status.weapon == 11)
- {
- damage = (damage * (300 + 40 * skill_lv) / 100) / 2;
- damage2 = (damage2 * (300 + 40 * skill_lv) / 100) / 2;
- }
- else
- {
- damage = damage * (300 + 40 * skill_lv) / 100;
- damage2 = damage2 * (300 + 40 * skill_lv) / 100;
- }
- hitrate = 1000000;
- break;
- case RG_RAID: // サプライズアタック
- damage = damage * (100 + 40 * skill_lv) / 100;
- damage2 = damage2 * (100 + 40 * skill_lv) / 100;
- break;
- case RG_INTIMIDATE: // インティミデイト
- damage = damage * (100 + 30 * skill_lv) / 100;
- damage2 = damage2 * (100 + 30 * skill_lv) / 100;
- break;
- case CR_SHIELDCHARGE: // シールドチャージ
- damage = damage * (100 + 20 * skill_lv) / 100;
- damage2 = damage2 * (100 + 20 * skill_lv) / 100;
- flag = (flag & ~BF_RANGEMASK) | BF_SHORT;
- s_ele = 0;
- break;
- case CR_SHIELDBOOMERANG: // シールドブーメラン
- damage = damage * (100 + 30 * skill_lv) / 100;
- damage2 = damage2 * (100 + 30 * skill_lv) / 100;
- flag = (flag & ~BF_RANGEMASK) | BF_LONG;
- s_ele = 0;
- break;
- 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;
- break;
- case AM_DEMONSTRATION: // デモンストレーション
- damage = damage * (100 + 20 * skill_lv) / 100;
- damage2 = damage2 * (100 + 20 * skill_lv) / 100;
- break;
- case AM_ACIDTERROR: // アシッドテラー
- damage = damage * (100 + 40 * skill_lv) / 100;
- damage2 = damage2 * (100 + 40 * skill_lv) / 100;
- break;
- case MO_FINGEROFFENSIVE: //指弾
- if (battle_config.finger_offensive_type == 0)
- {
- damage =
- damage * (100 +
- 50 * skill_lv) / 100 *
- sd->spiritball_old;
- damage2 =
- damage2 * (100 +
- 50 * skill_lv) / 100 *
- sd->spiritball_old;
- div_ = sd->spiritball_old;
- }
- else
- {
- damage = damage * (100 + 50 * skill_lv) / 100;
- damage2 = damage2 * (100 + 50 * skill_lv) / 100;
- div_ = 1;
- }
- 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;
- }
- hitrate = 1000000;
- s_ele = 0;
- s_ele_ = 0;
- break;
- case MO_EXTREMITYFIST: // 阿修羅覇鳳拳
- damage =
- damage * (8 + ((sd->status.sp) / 10)) + 250 +
- (skill_lv * 150);
- damage2 =
- damage2 * (8 + ((sd->status.sp) / 10)) + 250 +
- (skill_lv * 150);
- sd->status.sp = 0;
- clif_updatestatus (sd, SP_SP);
- hitrate = 1000000;
- s_ele = 0;
- s_ele_ = 0;
- break;
- 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 = MRAND ((sd->arrow_atk + 1));
- damage += arr;
- damage2 += arr;
- }
- damage = damage * (100 + 50 * skill_lv) / 100;
- damage2 = damage2 * (100 + 50 * 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)
- {
- int arr = MRAND ((sd->arrow_atk + 1));
- damage += arr;
- damage2 += arr;
- }
- damage = damage * (100 + 50 * skill_lv) / 100;
- damage2 = damage2 * (100 + 50 * 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 CH_TIGERFIST: // 伏虎拳
- damage = damage * (100 + 20 * skill_lv) / 100;
- damage2 = damage2 * (100 + 20 * skill_lv) / 100;
- break;
- case CH_CHAINCRUSH: // 連柱崩撃
- damage = damage * (100 + 20 * skill_lv) / 100;
- damage2 = damage2 * (100 + 20 * skill_lv) / 100;
- div_ = skill_get_num (skill_num, skill_lv);
- break;
- case CH_PALMSTRIKE: // 猛虎硬派山
- damage = damage * (50 + 100 * skill_lv) / 100;
- damage2 = damage2 * (50 + 100 * skill_lv) / 100;
- break;
- case LK_SPIRALPIERCE: /* スパイラルピアース */
- damage = damage * (100 + 50 * skill_lv) / 100; //増加量が分からないので適当に
- damage2 = damage2 * (100 + 50 * skill_lv) / 100; //増加量が分からないので適当に
- div_ = 5;
- if (tsd)
- tsd->canmove_tick = gettick () + 1000;
- else if (tmd)
- tmd->canmove_tick = gettick () + 1000;
- break;
- case LK_HEADCRUSH: /* ヘッドクラッシュ */
- damage = damage * (100 + 20 * skill_lv) / 100;
- damage2 = damage2 * (100 + 20 * skill_lv) / 100;
- break;
- case LK_JOINTBEAT: /* ジョイントビート */
- damage = damage * (50 + 10 * skill_lv) / 100;
- damage2 = damage2 * (50 + 10 * skill_lv) / 100;
- break;
- case ASC_METEORASSAULT: /* メテオアサルト */
- damage = damage * (40 + 40 * skill_lv) / 100;
- damage2 = damage2 * (40 + 40 * skill_lv) / 100;
- break;
- case SN_SHARPSHOOTING: /* シャープシューティング */
- damage += damage * (30 * skill_lv) / 100;
- damage2 += damage2 * (30 * skill_lv) / 100;
- break;
- case CG_ARROWVULCAN: /* アローバルカン */
- damage = damage * (160 + 40 * skill_lv) / 100;
- damage2 = damage2 * (160 + 40 * skill_lv) / 100;
- div_ = 9;
- 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 * ((skill_lv / 2) + (50 / 100)) / 100;
- damage =
- (((skill_lv * 15) + 90) / 100) * damage3 / 100;
- damage2 =
- (((skill_lv * 15) + 90) / 100) * damage3 / 100;
- }
- 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) +
- MRAND (500) + 500) / 2;
- damage2 =
- ((damage2 * 5) +
- (skill_lv * battle_get_int (src) * 5) +
- MRAND (500) + 500) / 2;
- damage3 = damage;
- hitrate = 1000000;
-
- 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))
- imdef_flag = 1;
- }
- else
- {
- if (sd->ignore_mdef_race & (1 << 11))
- imdef_flag = 1;
- }
- if (!imdef_flag)
- {
- if (battle_config.magic_defense_type)
- {
- damage3 =
- damage3 -
- (mdef1 *
- battle_config.magic_defense_type) -
- mdef2;
- }
- else
- {
- damage3 =
- (damage3 * (100 - mdef1)) / 100 - mdef2;
- }
- }
-
- if (damage3 < 1)
- damage3 = 1;
-
- damage3 =
- battle_attr_fix (damage2, s_ele_,
- battle_get_element (target));
- }
- break;
- }
- }
- if (da == 2)
- { //三段掌が発動しているか
- type = 0x08;
- div_ = 255; //三段掌用に…
- damage =
- damage * (100 +
- 20 * pc_checkskill (sd, MO_TRIPLEATTACK)) / 100;
+ flag = (flag & ~BF::SKILLMASK) | BF::SKILL;
}
- if (skill_num != NPC_CRITICALSLASH)
{
// 対 象の防御力によるダメージの減少
// ディバインプロテクション(ここでいいのかな?)
- if (skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST
- && skill_num != KN_AUTOCOUNTER && def1 < 1000000)
+ if (def1 < 1000000)
{ //DEF, VIT無視
- int t_def;
+ int t_def;
target_count =
- 1 + battle_counttargeted (target, src,
- battle_config.vit_penaly_count_lv);
+ 1 + battle_counttargeted(target, src,
+ ATK(battle_config.vit_penaly_count_lv)); // FIXME
if (battle_config.vit_penaly_type > 0)
{
if (target_count >= battle_config.vit_penaly_count)
@@ -3617,105 +1574,30 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
}
t_def = def2 * 8 / 10;
vitbonusmax = (t_vit / 20) * (t_vit / 20) - 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))
- idef_flag_ = 1;
- if (t_mode & 0x20)
- {
- if (sd->ignore_def_race & (1 << 10))
- idef_flag = 1;
- if (sd->ignore_def_race_ & (1 << 10))
- idef_flag_ = 1;
- }
- else
- {
- if (sd->ignore_def_race & (1 << 11))
- idef_flag = 1;
- if (sd->ignore_def_race_ & (1 << 11))
- idef_flag_ = 1;
- }
- if (!idef_flag)
{
- if (battle_config.player_defense_type)
- {
- damage =
- damage -
- (def1 * battle_config.player_defense_type) -
- t_def -
- ((vitbonusmax <
- 1) ? 0 : MRAND ((vitbonusmax + 1)));
- }
- else
{
- damage =
- damage * (100 - def1) / 100 - t_def -
- ((vitbonusmax <
- 1) ? 0 : MRAND ((vitbonusmax + 1)));
+ damage = damage * (100 - def1) / 100;
+ damage -= t_def;
+ if (vitbonusmax > 0)
+ damage -= random_::in(0, vitbonusmax);
}
}
- if (!idef_flag_)
{
- if (battle_config.player_defense_type)
{
- damage2 =
- damage2 -
- (def1 * battle_config.player_defense_type) -
- t_def -
- ((vitbonusmax <
- 1) ? 0 : MRAND ((vitbonusmax + 1)));
- }
- else
- {
- damage2 =
- damage2 * (100 - def1) / 100 - t_def -
- ((vitbonusmax <
- 1) ? 0 : MRAND ((vitbonusmax + 1)));
+ damage2 = damage2 * (100 - def1) / 100;
+ damage2 -= t_def;
+ if (vitbonusmax > 0)
+ damage2 -= random_::in(0, vitbonusmax);
}
}
}
}
}
// 精錬ダメージの追加
- if (skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST)
{ //DEF, VIT無視
- damage += battle_get_atk2 (src);
- damage2 += battle_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);
- }
- }
- }
- if (skill_num == LK_SPIRALPIERCE)
- { /* スパイラルピアース */
- if (sd->equip_index[9] >= 0)
- { //重量で追加ダメージらしいのでシールドブーメランを参考に追加
- 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 += battle_get_atk2(src);
+ damage2 += battle_get_atk_2(src);
}
// 0未満だった場合1に補正
@@ -3726,222 +1608,35 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
// スキル修正2(修練系)
// 修練ダメージ(右手のみ) ソニックブロー時は別処理(1撃に付き1/8適応)
- if (skill_num != MO_INVESTIGATE && skill_num != MO_EXTREMITYFIST
- && skill_num != CR_GRANDCROSS)
{ //修練ダメージ無視
- damage = battle_addmastery (sd, target, damage, 0);
- damage2 = battle_addmastery (sd, target, damage2, 1);
}
if (sd->perfect_hit > 0)
{
- if (MRAND (100) < sd->perfect_hit)
+ if (random_::chance({sd->perfect_hit, 100}))
hitrate = 1000000;
}
// 回避修正
hitrate = (hitrate < 5) ? 5 : hitrate;
- if (hitrate < 1000000 && // 必中攻撃
- (t_sc_data != NULL && (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_STONE].timer != -1 && t_sc_data[SC_STONE].val2 == 0)))) // 凍結は必中
- hitrate = 1000000;
- if (type == 0 && MRAND (100) >= hitrate)
+ if (type == DamageType::NORMAL && !random_::chance({hitrate, 100}))
{
damage = damage2 = 0;
- dmg_lv = ATK_FLEE;
- }
- else
- {
- dmg_lv = ATK_DEF;
- }
- // スキル修正3(武器研究)
- if ((skill = pc_checkskill (sd, BS_WEAPONRESEARCH)) > 0)
- {
- damage += skill * 2;
- damage2 += skill * 2;
- }
- //Advanced Katar Research by zanetheinsane
- if (sd->weapontype1 == 0x10 || sd->weapontype2 == 0x10)
- {
- if ((skill = pc_checkskill (sd, ASC_KATAR)) > 0)
- {
- damage += (damage * ((skill * 2) + 10)) / 100;
- }
- }
-
-//スキルによるダメージ補正ここまで
-
-//カードによるダメージ追加処理ここから
- cardfix = 100;
- if (!sd->state.arrow_atk)
- { //弓矢以外
- if (!battle_config.left_cardfix_to_right)
- { //左手カード補正設定無し
- cardfix = cardfix * (100 + sd->addrace[t_race]) / 100; // 種族によるダメージ修正
- cardfix = cardfix * (100 + sd->addele[t_ele]) / 100; // 属性によるダメージ修正
- cardfix = cardfix * (100 + sd->addsize[t_size]) / 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; // サイズによるダメージ修正(左手による追加あり)
- }
+ dmg_lv = ATK::FLEE;
}
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; // サイズによるダメージ修正(弓矢による追加あり)
- }
- if (t_mode & 0x20)
- { //ボス
- if (!sd->state.arrow_atk)
- { //弓矢攻撃以外なら
- if (!battle_config.left_cardfix_to_right) //左手カード補正設定無し
- cardfix = cardfix * (100 + sd->addrace[10]) / 100; //ボスモンスターに追加ダメージ
- else //左手カード補正設定あり
- cardfix = cardfix * (100 + sd->addrace[10] + sd->addrace_[10]) / 100; //ボスモンスターに追加ダメージ(左手による追加あり)
- }
- else //弓矢攻撃
- cardfix = cardfix * (100 + sd->addrace[10] + sd->arrow_addrace[10]) / 100; //ボスモンスターに追加ダメージ(弓矢による追加あり)
- }
- else
- { //ボスじゃない
- if (!sd->state.arrow_atk)
- { //弓矢攻撃以外
- if (!battle_config.left_cardfix_to_right) //左手カード補正設定無し
- cardfix = cardfix * (100 + sd->addrace[11]) / 100; //ボス以外モンスターに追加ダメージ
- else //左手カード補正設定あり
- cardfix = cardfix * (100 + sd->addrace[11] + sd->addrace_[11]) / 100; //ボス以外モンスターに追加ダメージ(左手による追加あり)
- }
- else
- cardfix = cardfix * (100 + sd->addrace[11] + sd->arrow_addrace[11]) / 100; //ボス以外モンスターに追加ダメージ(弓矢による追加あり)
- }
- //特定Class用補正処理(少女の日記→ボンゴン用?)
- t_class = battle_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;
- break;
- }
+ dmg_lv = ATK::DEF;
}
- if (skill_num != CR_GRANDCROSS || !battle_config.gx_cardfix)
- damage = damage * cardfix / 100; //カード補正によるダメージ増加
-//カードによるダメージ増加処理ここまで
-
-//カードによるダメージ追加処理(左手)ここから
- cardfix = 100;
- if (!battle_config.left_cardfix_to_right)
- { //左手カード補正設定無し
- cardfix = cardfix * (100 + sd->addrace_[t_race]) / 100; // 種族によるダメージ修正左手
- cardfix = cardfix * (100 + sd->addele_[t_ele]) / 100; // 属 性によるダメージ修正左手
- cardfix = cardfix * (100 + sd->addsize_[t_size]) / 100; // サイズによるダメージ修正左手
- if (t_mode & 0x20) //ボス
- cardfix = cardfix * (100 + sd->addrace_[10]) / 100; //ボスモンスターに追加ダメージ左手
- else
- cardfix = cardfix * (100 + sd->addrace_[11]) / 100; //ボス以外モンスターに追加ダメージ左手
- }
- //特定Class用補正処理左手(少女の日記→ボンゴン用?)
- 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;
- break;
- }
- }
- if (skill_num != CR_GRANDCROSS)
- 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->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.pc_class)
- {
- cardfix = cardfix * (100 - tsd->add_def_classrate[i]) / 100;
- break;
- }
- }
- if (flag & BF_LONG)
- cardfix = cardfix * (100 - tsd->long_attack_def_rate) / 100; //遠距離攻撃はダメージ減少(ホルンCとか)
- if (flag & BF_SHORT)
- cardfix = cardfix * (100 - tsd->near_attack_def_rate) / 100; //近距離攻撃はダメージ減少(該当無し?)
- damage = damage * cardfix / 100; //カード補正によるダメージ減少
- damage2 = damage2 * cardfix / 100; //カード補正による左手ダメージ減少
- }
-//カードによるダメージ減衰処理ここまで
-
-//対象にステータス異常がある場合のダメージ減算処理ここから
- if (t_sc_data)
- {
- cardfix = 100;
- if (t_sc_data[SC_DEFENDER].timer != -1 && flag & BF_LONG) //ディフェンダー状態で遠距離攻撃
- cardfix = cardfix * (100 - t_sc_data[SC_DEFENDER].val2) / 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;
- }
- }
- }
-//対象にステータス異常がある場合のダメージ減算処理ここまで
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 += sd->star;
damage2 += sd->star_;
- damage += sd->spiritball * 3;
- damage2 += sd->spiritball * 3;
-
- if (sc_data && sc_data[SC_AURABLADE].timer != -1)
- { /* オーラブレード 必中 */
- damage += sc_data[SC_AURABLADE].val1 * 10;
- damage2 += sc_data[SC_AURABLADE].val1 * 10;
- }
- if (skill_num == PA_PRESSURE)
- { /* プレッシャー 必中? */
- damage = 700 + 100 * skill_lv;
- damage2 = 700 + 100 * skill_lv;
- }
// >二刀流の左右ダメージ計算誰かやってくれぇぇぇぇえええ!
// >map_session_data に左手ダメージ(atk,atk2)追加して
@@ -3950,23 +1645,22 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
// pc_calcstatus()でデータを入力しています
//左手のみ武器装備
- if (sd->weapontype1 == 0 && sd->weapontype2 > 0)
+ if (sd->weapontype1 == ItemLook::NONE
+ && sd->weapontype2 != ItemLook::NONE)
{
damage = damage2;
damage2 = 0;
}
// 右手、左手修練の適用
- if (sd->status.weapon > 16)
+ if (sd->status.weapon >= ItemLook::SINGLE_HANDED_COUNT)
{ // 二刀流か?
- int dmg = damage, dmg2 = damage2;
+ int dmg = damage, dmg2 = damage2;
// 右手修練(60% 〜 100%) 右手全般
- skill = pc_checkskill (sd, AS_RIGHT);
- damage = damage * (50 + (skill * 10)) / 100;
+ damage = damage * 50 / 100;
if (dmg > 0 && damage < 1)
damage = 1;
// 左手修練(40% 〜 80%) 左手全般
- skill = pc_checkskill (sd, AS_LEFT);
- damage2 = damage2 * (30 + (skill * 10)) / 100;
+ damage2 = damage2 * 30 / 100;
if (dmg2 > 0 && damage2 < 1)
damage2 = 1;
}
@@ -3974,57 +1668,44 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
damage2 = 0;
// 右手,短剣のみ
- if (da == 1)
+ if (da)
{ //ダブルアタックが発動しているか
div_ = 2;
damage += damage;
- type = 0x08;
+ type = DamageType::DOUBLED;
}
- if (sd->status.weapon == 16)
+ if (sd->status.weapon == ItemLook::_16)
{
// カタール追撃ダメージ
- skill = pc_checkskill (sd, TF_DOUBLE);
- damage2 = damage * (1 + (skill * 2)) / 100;
+ damage2 = damage * 1 / 100;
if (damage > 0 && damage2 < 1)
damage2 = 1;
}
- // インベナム修正
- if (skill_num == TF_POISON)
- {
- damage =
- battle_attr_fix (damage + 15 * skill_lv, s_ele,
- battle_get_element (target));
- }
- if (skill_num == MC_CARTREVOLUTION)
- {
- damage = battle_attr_fix (damage, 0, battle_get_element (target));
- }
-
// 完全回避の判定
- if (skill_num == 0 && skill_lv >= 0 && tsd != NULL && div_ < 255
- && MRAND (1000) < battle_get_flee2 (target))
+ if (skill_num == SkillID::ZERO && skill_lv >= 0 && tsd != NULL && div_ < 255
+ && random_::chance({battle_get_flee2(target), 1000}))
{
damage = damage2 = 0;
- type = 0x0b;
- dmg_lv = ATK_LUCKY;
+ type = DamageType::FLEE2;
+ dmg_lv = ATK::LUCKY;
}
// 対象が完全回避をする設定がONなら
if (battle_config.enemy_perfect_flee)
{
- if (skill_num == 0 && skill_lv >= 0 && tmd != NULL && div_ < 255
- && MRAND (1000) < battle_get_flee2 (target))
+ if (skill_num == SkillID::ZERO && skill_lv >= 0 && tmd != NULL && div_ < 255
+ && random_::chance({battle_get_flee2(target), 1000}))
{
damage = damage2 = 0;
- type = 0x0b;
- dmg_lv = ATK_LUCKY;
+ type = DamageType::FLEE2;
+ dmg_lv = ATK::LUCKY;
}
}
//MobのModeに頑強フラグが立っているときの処理
- if (t_mode & 0x40)
+ if (bool(t_mode & MobMode::PLANT))
{
if (damage > 0)
damage = 1;
@@ -4032,26 +1713,21 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
damage2 = 1;
}
- //bNoWeaponDamage(設定アイテム無し?)でグランドクロスじゃない場合はダメージが0
- if (tsd && tsd->special_state.no_weapon_damage
- && skill_num != CR_GRANDCROSS)
- damage = damage2 = 0;
-
- if (skill_num != CR_GRANDCROSS && (damage > 0 || damage2 > 0))
+ if (damage > 0 || damage2 > 0)
{
if (damage2 < 1) // ダメージ最終修正
damage =
- battle_calc_damage (src, target, damage, div_, skill_num,
+ battle_calc_damage(src, target, damage, div_, skill_num,
skill_lv, flag);
else if (damage < 1) // 右手がミス?
damage2 =
- battle_calc_damage (src, target, damage2, div_, skill_num,
+ battle_calc_damage(src, target, damage2, div_, skill_num,
skill_lv, flag);
else
{ // 両 手/カタールの場合はちょっと計算ややこしい
- int d1 = damage + damage2, d2 = damage2;
+ int d1 = damage + damage2, d2 = damage2;
damage =
- battle_calc_damage (src, target, damage + damage2, div_,
+ battle_calc_damage(src, target, damage + damage2, div_,
skill_num, skill_lv, flag);
damage2 = (d2 * 100 / d1) * damage / 100;
if (damage > 1 && damage2 < 1)
@@ -4060,36 +1736,12 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
}
}
- /* For executioner card [Valaris] */
- if (src->type == BL_PC && sd->random_attack_increase_add > 0
- && sd->random_attack_increase_per > 0 && skill_num == 0)
- {
- if (MRAND (100) < sd->random_attack_increase_per)
- {
- if (damage > 0)
- damage *= sd->random_attack_increase_add / 100;
- if (damage2 > 0)
- damage2 *= sd->random_attack_increase_add / 100;
- }
- }
- /* End addition */
-
-// -- 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);
- if (skill_num == KN_AUTOCOUNTER)
- wd.amotion >>= 1;
- wd.dmotion = battle_get_dmotion (target);
- wd.blewcount = blewcount;
+ wd.amotion = battle_get_amotion(src);
+ wd.dmotion = battle_get_dmotion(target);
wd.flag = flag;
wd.dmg_lv = dmg_lv;
@@ -4100,77 +1752,21 @@ static struct Damage battle_calc_pc_weapon_attack (struct block_list *src,
* 武器ダメージ計算
*------------------------------------------
*/
-struct Damage battle_calc_weapon_attack (struct block_list *src,
+static
+struct Damage battle_calc_weapon_attack(struct block_list *src,
struct block_list *target,
- int skill_num, int skill_lv,
+ SkillID skill_num, int skill_lv,
int wflag)
{
- struct Damage wd;
+ struct Damage wd {};
- //return前の処理があるので情報出力部のみ変更
- if (src == NULL || target == NULL)
- {
- nullpo_info (NLP_MARK);
- memset (&wd, 0, sizeof (wd));
- return wd;
- }
+ nullpo_retr(wd, src);
+ nullpo_retr(wd, target);
- else if (src->type == BL_PC)
- wd = battle_calc_pc_weapon_attack (src, target, skill_num, skill_lv, wflag); // weapon breaking [Valaris]
- else if (src->type == BL_MOB)
- wd = battle_calc_mob_weapon_attack (src, target, skill_num, skill_lv,
- wflag);
- else
- 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;
- if (sd->status.weapon && sd->status.weapon != 11)
- {
- int breakrate = 1;
- if (target->type == BL_PC && sd->sc_data[SC_MELTDOWN].timer != -1)
- {
- breakrate += 100 * sd->sc_data[SC_MELTDOWN].val1;
- if (MRAND (10000) <
- breakrate * battle_config.equipment_break_rate / 100
- || breakrate >= 10000)
- pc_breakweapon ((struct map_session_data *) target);
- }
- if (sd->sc_data[SC_OVERTHRUST].timer != -1)
- breakrate += 20 * sd->sc_data[SC_OVERTHRUST].val1;
- if (wd.type == 0x0a)
- breakrate *= 2;
- if (MRAND (10000) <
- breakrate * battle_config.equipment_break_rate / 100
- || breakrate >= 10000)
- {
- pc_breakweapon (sd);
- memset (&wd, 0, sizeof (wd));
- }
- }
- }
-
- 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 (MRAND (10000) <
- breakrate * battle_config.equipment_break_rate / 100
- || breakrate >= 10000)
- {
- pc_breakarmor ((struct map_session_data *) target);
- }
- }
+ if (src->type == BL::PC)
+ wd = battle_calc_pc_weapon_attack(src, target, skill_num, skill_lv, wflag); // weapon breaking [Valaris]
+ else if (src->type == BL::MOB)
+ wd = battle_calc_mob_weapon_attack(src, target, skill_num, skill_lv, wflag);
return wd;
}
@@ -4179,223 +1775,50 @@ struct Damage battle_calc_weapon_attack (struct block_list *src,
* 魔法ダメージ計算
*------------------------------------------
*/
-struct Damage battle_calc_magic_attack (struct block_list *bl,
+static
+struct Damage battle_calc_magic_attack(struct block_list *bl,
struct block_list *target,
- int skill_num, int skill_lv, int flag)
+ SkillID skill_num, int skill_lv, int)
{
- int mdef1 = battle_get_mdef (target);
- int mdef2 = battle_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;
- struct map_session_data *sd = NULL, *tsd = NULL;
- struct mob_data *tmd = NULL;
-
- //return前の処理があるので情報出力部のみ変更
- if (bl == NULL || target == NULL)
- {
- nullpo_info (NLP_MARK);
- memset (&md, 0, sizeof (md));
- return md;
- }
+ int mdef1 = battle_get_mdef(target);
+ int mdef2 = battle_get_mdef2(target);
+ int matk1, matk2, damage = 0, div_ = 1;
+ struct Damage md {};
+ int normalmagic_flag = 1;
+ struct map_session_data *sd = NULL;
- matk1 = battle_get_matk1 (bl);
- matk2 = battle_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);
+ nullpo_retr(md, bl);
+ nullpo_retr(md, target);
-#define MATK_FIX( a,b ) { matk1=matk1*(a)/(b); matk2=matk2*(a)/(b); }
+ matk1 = battle_get_matk1(bl);
+ matk2 = battle_get_matk2(bl);
+ MobMode t_mode = battle_get_mode(target);
- if (bl->type == BL_PC && (sd = (struct map_session_data *) bl))
+ if (bl->type == BL::PC && (sd = (struct map_session_data *) bl))
{
- sd->state.attack_type = BF_MAGIC;
+ sd->state.attack_type = BF::MAGIC;
if (sd->matk_rate != 100)
- MATK_FIX (sd->matk_rate, 100);
+ {
+ matk1 = matk1 * sd->matk_rate / 100;
+ matk2 = matk2 * sd->matk_rate / 100;
+ }
sd->state.arrow_atk = 0;
}
- if (target->type == BL_PC)
- tsd = (struct map_session_data *) target;
- else if (target->type == BL_MOB)
- tmd = (struct mob_data *) target;
-
- aflag = BF_MAGIC | BF_LONG | BF_SKILL;
-
- if (skill_num > 0)
- {
- switch (skill_num)
- { // 基本ダメージ計算(スキルごとに処理)
- // ヒールor聖体
- case AL_HEAL:
- case PR_BENEDICTIO:
- damage = skill_calc_heal (bl, skill_lv) / 2;
- normalmagic_flag = 0;
- break;
- case PR_ASPERSIO: /* アスペルシオ */
- damage = 40; //固定ダメージ
- normalmagic_flag = 0;
- break;
- case PR_SANCTUARY: // サンクチュアリ
- damage = (skill_lv > 6) ? 388 : skill_lv * 50;
- normalmagic_flag = 0;
- blewcount |= 0x10000;
- break;
- case ALL_RESURRECTION:
- 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) +
- ((200 - hp * 200 / mhp));
- if (thres > 700)
- thres = 700;
-// if(battle_config.battle_log)
-// printf("ターンアンデッド! 確率%d ‰(千分率)\n", thres);
- if (MRAND (1000) < thres && !(t_mode & 0x20)) // 成功
- damage = hp;
- else // 失敗
- damage =
- battle_get_lv (bl) + battle_get_int (bl) +
- skill_lv * 10;
- }
- normalmagic_flag = 0;
- break;
- case MG_NAPALMBEAT: // ナパームビート(分散計算込み)
- MATK_FIX (70 + skill_lv * 10, 100);
- if (flag > 0)
- {
- MATK_FIX (1, flag);
- }
- else
- {
- if (battle_config.error_log)
- printf
- ("battle_calc_magic_attack(): napam enemy count=0 !\n");
- }
- break;
- case MG_FIREBALL: // ファイヤーボール
- {
- const int drate[] = { 100, 90, 70 };
- if (flag > 2)
- matk1 = matk2 = 0;
- else
- MATK_FIX ((95 + skill_lv * 5) * drate[flag], 10000);
- }
- break;
- case MG_FIREWALL: // ファイヤーウォール
-/*
- if( (t_ele!=3 && !battle_check_undead(t_race,t_ele)) || target->type==BL_PC ) //PCは火属性でも飛ぶ?そもそもダメージ受ける?
- blewcount |= 0x10000;
- else
- blewcount = 0;
-*/
- if ((t_ele == 3 || battle_check_undead (t_race, t_ele))
- && target->type != BL_PC)
- blewcount = 0;
- else
- blewcount |= 0x10000;
- MATK_FIX (1, 2);
- break;
- case MG_THUNDERSTORM: // サンダーストーム
- MATK_FIX (80, 100);
- break;
- case MG_FROSTDIVER: // フロストダイバ
- MATK_FIX (100 + skill_lv * 10, 100);
- break;
- case WZ_FROSTNOVA: // フロストダイバ
- MATK_FIX (((100 + skill_lv * 10) * (2 / 3)), 100);
- break;
- case WZ_FIREPILLAR: // ファイヤーピラー
- if (mdef1 < 1000000)
- mdef1 = mdef2 = 0; // MDEF無視
- MATK_FIX (1, 5);
- matk1 += 50;
- matk2 += 50;
- break;
- case WZ_SIGHTRASHER:
- MATK_FIX (100 + skill_lv * 20, 100);
- break;
- case WZ_METEOR:
- case WZ_JUPITEL: // ユピテルサンダー
- break;
- case WZ_VERMILION: // ロードオブバーミリオン
- MATK_FIX (skill_lv * 20 + 80, 100);
- break;
- case WZ_WATERBALL: // ウォーターボール
- matk1 += skill_lv * 30;
- matk2 += skill_lv * 30;
- break;
- case WZ_STORMGUST: // ストームガスト
- MATK_FIX (skill_lv * 40 + 100, 100);
- blewcount |= 0x10000;
- break;
- case AL_HOLYLIGHT: // ホーリーライト
- MATK_FIX (125, 100);
- break;
- case AL_RUWACH:
- MATK_FIX (145, 100);
- break;
- case HW_NAPALMVULCAN: // ナパームビート(分散計算込み)
- MATK_FIX (70 + skill_lv * 10, 100);
- if (flag > 0)
- {
- MATK_FIX (1, flag);
- }
- else
- {
- if (battle_config.error_log)
- printf
- ("battle_calc_magic_attack(): napalmvulcan enemy count=0 !\n");
- }
- break;
- }
- }
+ BF aflag = BF::MAGIC | BF::LONG | BF::SKILL;
if (normalmagic_flag)
- { // 一般魔法ダメージ計算
- int imdef_flag = 0;
+ {
+ // 一般魔法ダメージ計算
if (matk1 > matk2)
- damage = matk2 + MRAND ((matk1 - matk2 + 1));
+ damage = random_::in(matk2, matk1);
else
damage = matk2;
- if (sd)
- {
- 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))
- imdef_flag = 1;
- }
- else
- {
- if (sd->ignore_mdef_race & (1 << 11))
- imdef_flag = 1;
- }
- }
- if (!imdef_flag)
+
{
- if (battle_config.magic_defense_type)
- {
- damage =
- damage - (mdef1 * battle_config.magic_defense_type) -
- mdef2;
- }
- else
{
- damage = (damage * (100 - mdef1)) / 100 - mdef2;
+ damage = (damage * (100 - mdef1)) / 100;
+ damage -= mdef2;
}
}
@@ -4403,108 +1826,26 @@ struct Damage battle_calc_magic_attack (struct block_list *bl,
damage = 1;
}
- if (sd)
- {
- cardfix = 100;
- cardfix = cardfix * (100 + sd->magic_addrace[t_race]) / 100;
- cardfix = cardfix * (100 + sd->magic_addele[t_ele]) / 100;
- if (t_mode & 0x20)
- cardfix = cardfix * (100 + sd->magic_addrace[10]) / 100;
- else
- cardfix = cardfix * (100 + sd->magic_addrace[11]) / 100;
- t_class = battle_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;
- break;
- }
- }
- damage = damage * cardfix / 100;
- }
-
- if (tsd)
- {
- int s_class = battle_get_class (bl);
- cardfix = 100;
- cardfix = cardfix * (100 - tsd->subele[ele]) / 100; // 属 性によるダメージ耐性
- cardfix = cardfix * (100 - tsd->subrace[race]) / 100; // 種族によるダメージ耐性
- cardfix = cardfix * (100 - tsd->magic_subrace[race]) / 100;
- if (battle_get_mode (bl) & 0x20)
- cardfix = cardfix * (100 - tsd->magic_subrace[10]) / 100;
- else
- cardfix = cardfix * (100 - tsd->magic_subrace[11]) / 100;
- for (i = 0; i < tsd->add_mdef_class_count; i++)
- {
- if (tsd->add_mdef_classid[i] == s_class)
- {
- cardfix = cardfix * (100 - tsd->add_mdef_classrate[i]) / 100;
- break;
- }
- }
- cardfix = cardfix * (100 - tsd->magic_def_rate) / 100;
- damage = damage * cardfix / 100;
- }
if (damage < 0)
damage = 0;
- damage = battle_attr_fix (damage, ele, battle_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 (bl == target)
- damage = damage / 2; //反動は半分
- }
-
- div_ = skill_get_num (skill_num, skill_lv);
+ div_ = skill_get_num(skill_num, skill_lv);
- if (div_ > 1 && skill_num != WZ_VERMILION)
+ if (div_ > 1)
damage *= div_;
// if(mdef1 >= 1000000 && damage > 0)
- if (t_mode & 0x40 && damage > 0)
+ if (bool(t_mode & MobMode::PLANT) && damage > 0)
damage = 1;
- if (tsd && tsd->special_state.no_magic_damage)
- {
- if (battle_config.gtb_pvp_only != 0)
- { // [MouseJstr]
- if ((map[target->m].flag.pvp || map[target->m].flag.gvg)
- && target->type == BL_PC)
- damage = (damage * (100 - battle_config.gtb_pvp_only)) / 100;
- }
- else
- damage = 0; // 黄 金蟲カード(魔法ダメージ0)
- }
-
- damage = battle_calc_damage (bl, target, damage, div_, skill_num, skill_lv, aflag); // 最終修正
-
- /* magic_damage_return by [AppleGirl] and [Valaris] */
- if (target->type == BL_PC && tsd && tsd->magic_damage_return > 0)
- {
- rdamage += damage * tsd->magic_damage_return / 100;
- if (rdamage < 1)
- rdamage = 1;
- clif_damage (target, bl, gettick (), 0, 0, rdamage, 0, 0, 0);
- battle_damage (target, bl, rdamage, 0);
- }
- /* end magic_damage_return */
+ 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 = battle_get_amotion(bl);
+ md.dmotion = battle_get_dmotion(target);
md.damage2 = 0;
- md.type = 0;
- md.blewcount = blewcount;
+ md.type = DamageType::NORMAL;
md.flag = aflag;
return md;
@@ -4514,153 +1855,61 @@ struct Damage battle_calc_magic_attack (struct block_list *bl,
* その他ダメージ計算
*------------------------------------------
*/
-struct Damage battle_calc_misc_attack (struct block_list *bl,
+static
+struct Damage battle_calc_misc_attack(struct block_list *bl,
struct block_list *target,
- int skill_num, int skill_lv, int flag)
+ SkillID skill_num, int skill_lv, int)
{
- int int_ = battle_get_int (bl);
-// int luk=battle_get_luk(bl);
- int dex = battle_get_dex (bl);
- int skill, ele, race, cardfix;
- 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;
-
- //return前の処理があるので情報出力部のみ変更
- if (bl == NULL || target == NULL)
- {
- nullpo_info (NLP_MARK);
- memset (&md, 0, sizeof (md));
- return md;
- }
+ struct map_session_data *sd = NULL;
+ int damage = 0, div_ = 1;
+ struct Damage md {};
+ int damagefix = 1;
+
+ BF aflag = BF::MISC | BF::LONG | BF::SKILL;
+
+ nullpo_retr(md, bl);
+ nullpo_retr(md, target);
- if (bl->type == BL_PC && (sd = (struct map_session_data *) bl))
+ if (bl->type == BL::PC && (sd = (struct map_session_data *) bl))
{
- sd->state.attack_type = BF_MISC;
+ sd->state.attack_type = BF::MISC;
sd->state.arrow_atk = 0;
}
- if (target->type == BL_PC)
- tsd = (struct map_session_data *) target;
-
switch (skill_num)
{
-
- case HT_LANDMINE: // ランドマイン
- damage = skill_lv * (dex + 75) * (100 + int_) / 100;
- break;
-
- case HT_BLASTMINE: // ブラストマイン
- damage = skill_lv * (dex / 2 + 50) * (100 + int_) / 100;
- break;
-
- case HT_CLAYMORETRAP: // クレイモアートラップ
- damage = skill_lv * (dex / 2 + 75) * (100 + int_) / 100;
- break;
-
- case HT_BLITZBEAT: // ブリッツビート
- if (sd == NULL || (skill = pc_checkskill (sd, HT_STEELCROW)) <= 0)
- skill = 0;
- damage = (dex / 10 + int_ / 2 + skill * 3 + 40) * 2;
- if (flag > 1)
- damage /= flag;
- break;
-
- case TF_THROWSTONE: // 石投げ
- damage = 30;
- damagefix = 0;
- break;
-
- case BA_DISSONANCE: // 不協和音
- damage =
- (skill_lv) * 20 + pc_checkskill (sd, BA_MUSICALLESSON) * 3;
- break;
-
- case NPC_SELFDESTRUCTION: // 自爆
- damage = battle_get_hp (bl) - (bl == target ? 1 : 0);
- damagefix = 0;
- break;
-
- case NPC_SMOKING: // タバコを吸う
- damage = 3;
+ case SkillID::NPC_SELFDESTRUCTION: // 自爆
+ damage = battle_get_hp(bl) - (bl == target ? 1 : 0);
damagefix = 0;
break;
-
- case NPC_DARKBREATH:
- {
- struct status_change *sc_data = battle_get_sc_data (target);
- int hitrate =
- battle_get_hit (bl) - battle_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)))
- hitrate = 1000000;
- if (MRAND (100) < hitrate)
- {
- damage = 500 + (skill_lv - 1) * 1000 + MRAND (1000);
- if (damage > 9999)
- damage = 9999;
- }
- }
- break;
- case SN_FALCONASSAULT: /* ファルコンアサルト */
- skill = pc_checkskill (sd, HT_BLITZBEAT);
- damage =
- (100 + 50 * skill_lv +
- (dex / 10 + int_ / 2 + skill * 3 + 40) * 2);
- break;
}
- ele = skill_get_pl (skill_num);
- race = battle_get_race (bl);
-
if (damagefix)
{
- if (damage < 1 && skill_num != NPC_DARKBREATH)
+ if (damage < 1)
damage = 1;
-
- if (tsd)
- {
- cardfix = 100;
- cardfix = cardfix * (100 - tsd->subele[ele]) / 100; // 属性によるダメージ耐性
- cardfix = cardfix * (100 - tsd->subrace[race]) / 100; // 種族によるダメージ耐性
- cardfix = cardfix * (100 - tsd->misc_def_rate) / 100;
- damage = damage * cardfix / 100;
- }
- if (damage < 0)
- damage = 0;
- damage = battle_attr_fix (damage, ele, battle_get_element (target)); // 属性修正
}
- div_ = skill_get_num (skill_num, skill_lv);
+ 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)))
+ || (battle_get_def(target) >= 1000000
+ && battle_get_mdef(target) >= 1000000)))
{
damage = div_;
}
- damage = battle_calc_damage (bl, target, damage, div_, skill_num, skill_lv, aflag); // 最終修正
+ 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 = battle_get_amotion(bl);
+ md.dmotion = battle_get_dmotion(target);
md.damage2 = 0;
- md.type = 0;
- md.blewcount = blewcount;
+ md.type = DamageType::NORMAL;
md.flag = aflag;
return md;
@@ -4670,28 +1919,28 @@ struct Damage battle_calc_misc_attack (struct block_list *bl,
* ダメージ計算一括処理用
*------------------------------------------
*/
-struct Damage battle_calc_attack (int attack_type,
+struct Damage battle_calc_attack(BF attack_type,
struct block_list *bl,
- struct block_list *target, int skill_num,
+ struct block_list *target, SkillID skill_num,
int skill_lv, int flag)
{
struct Damage d;
- memset (&d, 0, sizeof (d));
+ memset(&d, 0, sizeof(d));
switch (attack_type)
{
- case BF_WEAPON:
- return battle_calc_weapon_attack (bl, target, skill_num, skill_lv,
+ case BF::WEAPON:
+ return battle_calc_weapon_attack(bl, target, skill_num, skill_lv,
flag);
- case BF_MAGIC:
- return battle_calc_magic_attack (bl, target, skill_num, skill_lv,
+ case BF::MAGIC:
+ return battle_calc_magic_attack(bl, target, skill_num, skill_lv,
flag);
- case BF_MISC:
- return battle_calc_misc_attack (bl, target, skill_num, skill_lv,
+ case BF::MISC:
+ return battle_calc_misc_attack(bl, target, skill_num, skill_lv,
flag);
default:
if (battle_config.error_log)
- printf ("battle_calc_attack: unknwon attack type ! %d\n",
+ PRINTF("battle_calc_attack: unknwon attack type ! %d\n",
attack_type);
break;
}
@@ -4702,550 +1951,220 @@ struct Damage battle_calc_attack (int attack_type,
* 通常攻撃処理まとめ
*------------------------------------------
*/
-int battle_weapon_attack (struct block_list *src, struct block_list *target,
- unsigned int tick, int flag)
+ATK battle_weapon_attack(struct block_list *src, struct block_list *target,
+ tick_t tick)
{
struct map_session_data *sd = NULL;
- struct status_change *sc_data = battle_get_sc_data (src), *t_sc_data =
- battle_get_sc_data (target);
- short *opt1;
- int race = 7, ele = 0;
- int damage, rdamage = 0;
+ eptr<struct status_change, StatusChange> t_sc_data = battle_get_sc_data(target);
struct Damage wd;
- nullpo_retr (0, src);
- nullpo_retr (0, target);
+ nullpo_retr(ATK::ZERO, src);
+ nullpo_retr(ATK::ZERO, target);
- if (src->type == BL_PC)
+ if (src->type == BL::PC)
sd = (struct map_session_data *) src;
if (src->prev == NULL || target->prev == NULL)
- return 0;
- if (src->type == BL_PC && pc_isdead (sd))
- return 0;
- if (target->type == BL_PC
- && pc_isdead ((struct map_session_data *) target))
- return 0;
+ return ATK::ZERO;
+ if (src->type == BL::PC && pc_isdead(sd))
+ return ATK::ZERO;
+ if (target->type == BL::PC
+ && pc_isdead((struct map_session_data *) target))
+ return ATK::ZERO;
- opt1 = battle_get_opt1 (src);
- if (opt1 && *opt1 > 0)
+ Opt1 *opt1 = battle_get_opt1(src);
+ if (opt1 != NULL && bool(*opt1))
{
- battle_stopattack (src);
- return 0;
- }
- if (sc_data && sc_data[SC_BLADESTOP].timer != -1)
- {
- battle_stopattack (src);
- return 0;
+ battle_stopattack(src);
+ return ATK::ZERO;
}
- race = battle_get_race (target);
- ele = battle_get_elem_type (target);
- if (battle_check_target (src, target, BCT_ENEMY) > 0 &&
- battle_check_range (src, target, 0))
+ if (battle_check_target(src, target, BCT_ENEMY) > 0 &&
+ battle_check_range(src, target, 0))
{
// 攻撃対象となりうるので攻撃
- if (sd && sd->status.weapon == 11)
+ if (sd && sd->status.weapon == ItemLook::BOW)
{
- if (sd->equip_index[10] >= 0)
+ if (sd->equip_index[EQUIP::ARROW] >= 0)
{
if (battle_config.arrow_decrement)
- pc_delitem (sd, sd->equip_index[10], 1, 0);
+ pc_delitem(sd, sd->equip_index[EQUIP::ARROW], 1, 0);
}
else
{
- clif_arrow_fail (sd, 0);
- return 0;
+ clif_arrow_fail(sd, 0);
+ return ATK::ZERO;
}
}
- if (flag & 0x8000)
- {
- if (sd && battle_config.pc_attack_direction_change)
- sd->dir = sd->head_dir =
- map_calc_dir (src, target->x, target->y);
- else if (src->type == BL_MOB
- && battle_config.monster_attack_direction_change)
- ((struct mob_data *) src)->dir =
- map_calc_dir (src, target->x, target->y);
- wd = battle_calc_weapon_attack (src, target, KN_AUTOCOUNTER,
- flag & 0xff, 0);
- }
- else
- wd = battle_calc_weapon_attack (src, target, 0, 0, 0);
+ wd = battle_calc_weapon_attack(src, target, SkillID::ZERO, 0, 0);
// significantly increase injuries for hasted characters
- if (wd.damage > 0 && (t_sc_data[SC_HASTE].timer != -1))
+ if (wd.damage > 0 && t_sc_data[StatusChange::SC_HASTE].timer)
{
- wd.damage = (wd.damage * (16 + t_sc_data[SC_HASTE].val1)) >> 4;
+ wd.damage = (wd.damage * (16 + t_sc_data[StatusChange::SC_HASTE].val1)) >> 4;
}
if (wd.damage > 0
- && t_sc_data[SC_PHYS_SHIELD].timer != -1 && target->type == BL_PC)
+ && t_sc_data[StatusChange::SC_PHYS_SHIELD].timer
+ && target->type == BL::PC)
{
- int reduction = t_sc_data[SC_PHYS_SHIELD].val1;
+ int reduction = t_sc_data[StatusChange::SC_PHYS_SHIELD].val1;
if (reduction > wd.damage)
reduction = wd.damage;
wd.damage -= reduction;
- MAP_LOG_PC (((struct map_session_data *) target),
+ MAP_LOG_PC(((struct map_session_data *) target),
"MAGIC-ABSORB-DMG %d", reduction);
}
- if ((damage = wd.damage + wd.damage2) > 0 && src != target)
- {
- if (wd.flag & BF_SHORT)
- {
- if (target->type == BL_PC)
- {
- struct map_session_data *tsd =
- (struct map_session_data *) target;
- if (tsd && tsd->short_weapon_damage_return > 0)
- {
- rdamage +=
- damage * tsd->short_weapon_damage_return / 100;
- if (rdamage < 1)
- rdamage = 1;
- }
- }
- if (t_sc_data && t_sc_data[SC_REFLECTSHIELD].timer != -1)
- {
- rdamage +=
- damage * t_sc_data[SC_REFLECTSHIELD].val2 / 100;
- if (rdamage < 1)
- rdamage = 1;
- }
- }
- else if (wd.flag & BF_LONG)
- {
- if (target->type == BL_PC)
- {
- struct map_session_data *tsd =
- (struct map_session_data *) target;
- if (tsd && tsd->long_weapon_damage_return > 0)
- {
- rdamage +=
- damage * tsd->long_weapon_damage_return / 100;
- if (rdamage < 1)
- rdamage = 1;
- }
- }
- }
-
- if (rdamage > 0)
- clif_damage (src, src, tick, wd.amotion, 0, rdamage, 1, 4, 0);
- }
-
- if (wd.div_ == 255 && sd)
- { //三段掌
- int delay =
- 1000 - 4 * battle_get_agi (src) - 2 * battle_get_dex (src);
- int skilllv;
- if (wd.damage + wd.damage2 < battle_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);
- }
- sd->attackabletime = sd->canmove_tick = tick + delay;
- clif_combo_delay (src, delay);
- clif_skill_damage (src, target, tick, wd.amotion, wd.dmotion,
- wd.damage, 3, MO_TRIPLEATTACK,
- pc_checkskill (sd, MO_TRIPLEATTACK), -1);
- }
- else
{
- clif_damage (src, target, tick, wd.amotion, wd.dmotion,
+ clif_damage(src, target, tick, wd.amotion, wd.dmotion,
wd.damage, wd.div_, wd.type, wd.damage2);
- //二刀流左手とカタール追撃のミス表示(無理やり〜)
- if (sd && sd->status.weapon >= 16 && wd.damage2 == 0)
- clif_damage (src, target, tick + 10, wd.amotion, wd.dmotion,
- 0, 1, 0, 0);
+ if (sd
+ && (sd->status.weapon == ItemLook::_16
+ || sd->status.weapon >= ItemLook::SINGLE_HANDED_COUNT)
+ && wd.damage2 == 0)
+ clif_damage(src, target, tick + std::chrono::milliseconds(10),
+ wd.amotion, wd.dmotion, 0, 1, DamageType::NORMAL, 0);
}
- 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 ();
- if (src->type == BL_PC)
+ map_freeblock_lock();
+
+ if (src->type == BL::PC)
{
- int weapon_index = sd->equip_index[9];
- int weapon = 0;
+ int weapon_index = sd->equip_index[EQUIP::WEAPON];
+ int weapon = 0;
if (sd->inventory_data[weapon_index]
- && sd->status.inventory[weapon_index].equip & 0x2)
+ && bool(sd->status.inventory[weapon_index].equip & EPOS::WEAPON))
weapon = sd->inventory_data[weapon_index]->nameid;
- MAP_LOG ("PC%d %d:%d,%d WPNDMG %s%d %d FOR %d WPN %d",
+ MAP_LOG("PC%d %d:%d,%d WPNDMG %s%d %d FOR %d WPN %d",
sd->status.char_id, src->m, src->x, src->y,
- (target->type == BL_PC) ? "PC" : "MOB",
+ (target->type == BL::PC) ? "PC" : "MOB",
(target->type ==
- BL_PC) ? ((struct map_session_data *) target)->
+ BL::PC) ? ((struct map_session_data *) target)->
status.char_id : target->id,
- (target->type ==
- BL_PC) ? 0 : ((struct mob_data *) target)->mob_class,
+ battle_get_class(target),
wd.damage + wd.damage2, weapon);
}
- if (target->type == BL_PC)
+ if (target->type == BL::PC)
{
struct map_session_data *sd2 = (struct map_session_data *) target;
- MAP_LOG ("PC%d %d:%d,%d WPNINJURY %s%d %d FOR %d",
+ MAP_LOG("PC%d %d:%d,%d WPNINJURY %s%d %d FOR %d",
sd2->status.char_id, target->m, target->x, target->y,
- (src->type == BL_PC) ? "PC" : "MOB",
- (src->type ==
- BL_PC) ? ((struct map_session_data *) src)->
- status.char_id : src->id,
- (src->type ==
- BL_PC) ? 0 : ((struct mob_data *) src)->mob_class,
+ (src->type == BL::PC) ? "PC" : "MOB",
+ (src->type == BL::PC)
+ ? ((struct map_session_data *) src)->status.char_id
+ : src->id,
+ battle_get_class(src),
wd.damage + wd.damage2);
}
- battle_damage (src, target, (wd.damage + wd.damage2), 0);
+ battle_damage(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))))
+ (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
- && MRAND (10000) < sd->weapon_coma_ele[ele])
- battle_damage (src, target,
- battle_get_max_hp (target), 1);
- if (sd->weapon_coma_race[race] > 0
- && MRAND (10000) < sd->weapon_coma_race[race])
- battle_damage (src, target,
- battle_get_max_hp (target), 1);
- if (battle_get_mode (target) & 0x20)
- {
- if (sd->weapon_coma_race[10] > 0
- && MRAND (10000) < sd->weapon_coma_race[10])
- battle_damage (src, target,
- battle_get_max_hp (target), 1);
- }
- else
- {
- if (sd->weapon_coma_race[11] > 0
- && MRAND (10000) < sd->weapon_coma_race[11])
- battle_damage (src, target,
- battle_get_max_hp (target), 1);
- }
- }
- }
- }
- if (sc_data && sc_data[SC_AUTOSPELL].timer != -1
- && MRAND (100) < sc_data[SC_AUTOSPELL].val4)
- {
- int skilllv = sc_data[SC_AUTOSPELL].val3, i, f = 0;
- i = MRAND (100);
- if (i >= 50)
- skilllv -= 2;
- else if (i >= 15)
- skilllv--;
- if (skilllv < 1)
- skilllv = 1;
- if (sd)
- {
- int sp = skill_get_sp (sc_data[SC_AUTOSPELL].val2,
- skilllv) * 2 / 3;
- if (sd->status.sp >= sp)
- {
- if ((i = skill_get_inf (sc_data[SC_AUTOSPELL].val2) == 2)
- || i == 32)
- f = skill_castend_pos2 (src, target->x, target->y,
- sc_data[SC_AUTOSPELL].val2,
- skilllv, tick, flag);
- else
- {
- switch (skill_get_nk (sc_data[SC_AUTOSPELL].val2))
- {
- case 0:
- case 2:
- f = skill_castend_damage_id (src, target,
- sc_data
- [SC_AUTOSPELL].val2,
- skilllv, tick,
- flag);
- break;
- case 1: /* 支援系 */
- if ((sc_data[SC_AUTOSPELL].val2 == AL_HEAL
- || (sc_data[SC_AUTOSPELL].val2 ==
- ALL_RESURRECTION
- && target->type != BL_PC))
- && battle_check_undead (race, ele))
- f = skill_castend_damage_id (src, target,
- sc_data
- [SC_AUTOSPELL].val2,
- skilllv,
- tick, flag);
- else
- f = skill_castend_nodamage_id (src,
- target,
- sc_data
- [SC_AUTOSPELL].val2,
- skilllv,
- tick,
- flag);
- break;
- }
- }
- if (!f)
- pc_heal (sd, 0, -sp);
- }
- }
- else
- {
- if ((i = skill_get_inf (sc_data[SC_AUTOSPELL].val2) == 2)
- || i == 32)
- skill_castend_pos2 (src, target->x, target->y,
- sc_data[SC_AUTOSPELL].val2, skilllv,
- tick, flag);
- else
- {
- switch (skill_get_nk (sc_data[SC_AUTOSPELL].val2))
- {
- case 0:
- case 2:
- skill_castend_damage_id (src, target,
- sc_data
- [SC_AUTOSPELL].val2,
- skilllv, tick, flag);
- break;
- case 1: /* 支援系 */
- if ((sc_data[SC_AUTOSPELL].val2 == AL_HEAL
- || (sc_data[SC_AUTOSPELL].val2 ==
- ALL_RESURRECTION
- && target->type != BL_PC))
- && battle_check_undead (race, ele))
- skill_castend_damage_id (src, target,
- sc_data
- [SC_AUTOSPELL].val2,
- skilllv, tick, flag);
- else
- skill_castend_nodamage_id (src, target,
- sc_data
- [SC_AUTOSPELL].val2,
- skilllv, tick,
- flag);
- break;
- }
- }
+ skill_additional_effect(src, target, SkillID::ZERO, 0);
}
}
if (sd)
{
- if (sd->autospell_id > 0 && sd->autospell_lv > 0
- && MRAND (100) < sd->autospell_rate)
- {
- int skilllv = sd->autospell_lv, i, f = 0, sp;
- i = MRAND (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 (!f)
- pc_heal (sd, 0, -sp);
- }
- }
- if (wd.flag & BF_WEAPON && src != target
+ if (bool(wd.flag & BF::WEAPON)
+ && src != target
&& (wd.damage > 0 || wd.damage2 > 0))
{
- int hp = 0, sp = 0;
+ int hp = 0, sp = 0;
if (sd->hp_drain_rate && wd.damage > 0
- && MRAND (100) < sd->hp_drain_rate)
+ && random_::chance({sd->hp_drain_rate, 100}))
{
hp += (wd.damage * sd->hp_drain_per) / 100;
}
if (sd->hp_drain_rate_ && wd.damage2 > 0
- && MRAND (100) < sd->hp_drain_rate_)
+ && random_::chance({sd->hp_drain_rate_, 100}))
{
hp += (wd.damage2 * sd->hp_drain_per_) / 100;
}
if (sd->sp_drain_rate && wd.damage > 0
- && MRAND (100) < sd->sp_drain_rate)
+ && random_::chance({sd->sp_drain_rate, 100}))
{
sp += (wd.damage * sd->sp_drain_per) / 100;
}
if (sd->sp_drain_rate_ && wd.damage2 > 0
- && MRAND (100) < sd->sp_drain_rate_)
+ && random_::chance({sd->sp_drain_rate_, 100}))
{
sp += (wd.damage2 * sd->sp_drain_per_) / 100;
}
if (hp || sp)
- pc_heal (sd, hp, sp);
+ pc_heal(sd, hp, sp);
}
}
- if (rdamage > 0)
- battle_damage (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);
- }
- if (t_sc_data && t_sc_data[SC_BLADESTOP_WAIT].timer != -1)
- {
- 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);
- }
- if (t_sc_data && t_sc_data[SC_SPLASHER].timer != -1) //殴ったので対象のベナムスプラッシャー状態を解除
- skill_status_change_end (target, SC_SPLASHER, -1);
-
- map_freeblock_unlock ();
+ map_freeblock_unlock();
}
return wd.dmg_lv;
}
-int battle_check_undead (int race, int element)
+bool battle_check_undead(Race race, Element element)
{
if (battle_config.undead_detect_type == 0)
{
- if (element == 9)
- return 1;
+ return element == Element::undead;
}
else if (battle_config.undead_detect_type == 1)
{
- if (race == 1)
- return 1;
+ return race == Race::undead;
}
else
{
- if (element == 9 || race == 1)
- return 1;
+ return element == Element::undead || race == Race::undead;
}
- return 0;
}
/*==========================================
* 敵味方判定(1=肯定,0=否定,-1=エラー)
* flag&0xf0000 = 0x00000:敵じゃないか判定(ret:1=敵ではない)
- * = 0x10000:パーティー判定(ret:1=パーティーメンバ)
- * = 0x20000:全て(ret:1=敵味方両方)
- * = 0x40000:敵か判定(ret:1=敵)
- * = 0x50000:パーティーじゃないか判定(ret:1=パーティでない)
+ * = 0x10000:パーティー判定(ret:1=パーティーメンバ)
+ * = 0x20000:全て(ret:1=敵味方両方)
+ * = 0x40000:敵か判定(ret:1=敵)
+ * = 0x50000:パーティーじゃないか判定(ret:1=パーティでない)
*------------------------------------------
*/
-int battle_check_target (struct block_list *src, struct block_list *target,
- int flag)
+int battle_check_target(struct block_list *src, struct block_list *target,
+ BCT flag)
{
- int s_p, s_g, t_p, t_g;
+ int s_p, t_p;
struct block_list *ss = src;
- nullpo_retr (0, src);
- nullpo_retr (0, target);
+ nullpo_ret(src);
+ nullpo_ret(target);
- if (flag & 0x40000)
+ if (flag & BCT_ENEMY)
{ // 反転フラグ
- int ret = battle_check_target (src, target, flag & 0x30000);
+ int ret = battle_check_target(src, target, flag & (BCT_PARTY | BCT_ALL));
if (ret != -1)
return !ret;
return -1;
}
- if (flag & 0x20000)
+ if (flag & BCT_ALL)
{
- if (target->type == BL_MOB || target->type == BL_PC)
+ if (target->type == BL::MOB || target->type == BL::PC)
return 1;
else
return -1;
}
- if (src->type == BL_SKILL && target->type == BL_SKILL) // 対象がスキルユニットなら無条件肯定
- return -1;
-
- if (target->type == BL_PC
- && ((struct map_session_data *) target)->invincible_timer != -1)
+ if (target->type == BL::PC
+ && ((struct map_session_data *) target)->invincible_timer)
return -1;
- if (target->type == BL_SKILL)
- {
- switch (((struct skill_unit *) target)->group->unit_id)
- {
- case 0x8d:
- case 0x8f:
- case 0x98:
- return 0;
- break;
- }
- }
-
- // スキルユニットの場合、親を求める
- 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)
- 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 (ss == target)
- {
- if (inf2 & 0x100)
- return 0;
- if (inf2 & 0x200)
- return -1;
- }
- }
// Mobでmaster_idがあってspecial_mob_aiなら、召喚主を求める
- if (src->type == BL_MOB)
+ if (src->type == BL::MOB)
{
struct mob_data *md = (struct mob_data *) src;
if (md && md->master_id > 0)
@@ -5254,7 +2173,7 @@ int battle_check_target (struct block_list *src, struct block_list *target,
return 1;
if (md->state.special_mob_ai)
{
- if (target->type == BL_MOB)
+ if (target->type == BL::MOB)
{ //special_mob_aiで対象がMob
struct mob_data *tmd = (struct mob_data *) target;
if (tmd)
@@ -5271,7 +2190,7 @@ int battle_check_target (struct block_list *src, struct block_list *target,
}
}
}
- if ((ss = map_id2bl (md->master_id)) == NULL)
+ if ((ss = map_id2bl(md->master_id)) == NULL)
return -1;
}
}
@@ -5279,25 +2198,23 @@ int battle_check_target (struct block_list *src, struct block_list *target,
if (src == target || ss == target) // 同じなら肯定
return 1;
- if (target->type == BL_PC
- && pc_isinvisible ((struct map_session_data *) target))
+ if (target->type == BL::PC
+ && pc_isinvisible((struct map_session_data *) target))
return -1;
if (src->prev == NULL || // 死んでるならエラー
- (src->type == BL_PC && pc_isdead ((struct map_session_data *) src)))
+ (src->type == BL::PC && pc_isdead((struct map_session_data *) src)))
return -1;
- if ((ss->type == BL_PC && target->type == BL_MOB) ||
- (ss->type == BL_MOB && target->type == BL_PC))
+ if ((ss->type == BL::PC && target->type == BL::MOB) ||
+ (ss->type == BL::MOB && target->type == BL::PC))
return 0; // PCvsMOBなら否定
- s_p = battle_get_party_id (ss);
- s_g = battle_get_guild_id (ss);
+ s_p = battle_get_party_id(ss);
- t_p = battle_get_party_id (target);
- t_g = battle_get_guild_id (target);
+ t_p = battle_get_party_id(target);
- if (flag & 0x10000)
+ if (flag & BCT_PARTY)
{
if (s_p && t_p && s_p == t_p) // 同じパーティなら肯定(味方)
return 1;
@@ -5305,61 +2222,20 @@ int battle_check_target (struct block_list *src, struct block_list *target,
return 0;
}
- if (ss->type == BL_MOB && s_g > 0 && t_g > 0 && s_g == t_g) // 同じギルド/mobクラスなら肯定(味方)
- return 1;
-
-//printf("ss:%d src:%d target:%d flag:0x%x %d %d ",ss->id,src->id,target->id,flag,src->type,target->type);
-//printf("p:%d %d g:%d %d\n",s_p,t_p,s_g,t_g);
+//PRINTF("ss:%d src:%d target:%d flag:0x%x %d %d ",ss->id,src->id,target->id,flag,src->type,target->type);
+//PRINTF("p:%d %d g:%d %d\n",s_p,t_p,s_g,t_g);
- if (ss->type == BL_PC && target->type == BL_PC)
+ if (ss->type == BL::PC && target->type == BL::PC)
{ // 両方PVPモードなら否定(敵)
- struct skill_unit *su = NULL;
- if (src->type == BL_SKILL)
- su = (struct skill_unit *) src;
if (map[ss->m].flag.pvp
- || pc_iskiller ((struct map_session_data *) ss,
+ || pc_iskiller((struct map_session_data *) ss,
(struct map_session_data *) target))
{ // [MouseJstr]
- if (su && su->group->target_flag == BCT_NOENEMY)
- return 1;
- else if (battle_config.pk_mode
- && (((struct map_session_data *) ss)->status.pc_class == 0
- || ((struct map_session_data *) target)->
- status.pc_class == 0))
+ if (battle_config.pk_mode)
return 1; // prevent novice engagement in pk_mode [Valaris]
else if (map[ss->m].flag.pvp_noparty && s_p > 0 && t_p > 0
&& s_p == t_p)
return 1;
- else if (map[ss->m].flag.pvp_noguild && s_g > 0 && t_g > 0
- && s_g == t_g)
- return 1;
- return 0;
- }
- if (map[src->m].flag.gvg)
- {
- struct guild *g = NULL;
- if (su && su->group->target_flag == BCT_NOENEMY)
- return 1;
- if (s_g > 0 && s_g == t_g)
- return 1;
- if (map[src->m].flag.gvg_noparty && s_p > 0 && t_p > 0
- && s_p == t_p)
- return 1;
- if ((g = guild_search (s_g)))
- {
- int i;
- for (i = 0; i < MAX_GUILDALLIANCE; i++)
- {
- if (g->alliance[i].guild_id > 0
- && g->alliance[i].guild_id == t_g)
- {
- if (g->alliance[i].opposition)
- return 0; //敵対ギルドなら無条件に敵
- else
- return 1; //同盟ギルドなら無条件に味方
- }
- }
- }
return 0;
}
}
@@ -5371,19 +2247,19 @@ int battle_check_target (struct block_list *src, struct block_list *target,
* 射程判定
*------------------------------------------
*/
-int battle_check_range (struct block_list *src, struct block_list *bl,
+int battle_check_range(struct block_list *src, struct block_list *bl,
int range)
{
- int dx, dy;
+ int dx, dy;
struct walkpath_data wpd;
- int arange;
+ int arange;
- nullpo_retr (0, src);
- nullpo_retr (0, bl);
+ nullpo_ret(src);
+ nullpo_ret(bl);
- dx = abs (bl->x - src->x);
- dy = abs (bl->y - src->y);
+ dx = abs(bl->x - src->x);
+ dy = abs(bl->y - src->y);
arange = ((dx > dy) ? dx : dy);
if (src->m != bl->m) // 違うマップ
@@ -5402,42 +2278,22 @@ int battle_check_range (struct block_list *src, struct block_list *bl,
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) !=
+ 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,
+ return (path_search(&wpd, src->m, src->x + dx, src->y + dy,
bl->x - dx, bl->y - dy, 0x10001) != -1) ? 1 : 0;
}
/*==========================================
- * Return numerical value of a switch configuration (modified by [Yor])
- * on/off, english, fran軋is, deutsch, espal
- *------------------------------------------
- */
-int battle_config_switch (const char *str)
-{
- if (strcasecmp (str, "on") == 0 || strcasecmp (str, "yes") == 0
- || strcasecmp (str, "oui") == 0 || strcasecmp (str, "ja") == 0
- || strcasecmp (str, "si") == 0)
- return 1;
- if (strcasecmp (str, "off") == 0 || strcasecmp (str, "no") == 0
- || strcasecmp (str, "non") == 0 || strcasecmp (str, "nein") == 0)
- return 0;
- return atoi (str);
-}
-
-/*==========================================
* 設定ファイルを読み込む
*------------------------------------------
*/
-int battle_config_read (const char *cfgName)
+int battle_config_read(const char *cfgName)
{
- int i;
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
static int count = 0;
if ((count++) == 0)
@@ -5456,21 +2312,16 @@ int battle_config_read (const char *cfgName)
battle_config.skill_out_range_consume = 1;
battle_config.mob_skill_add_range = 0;
battle_config.pc_damage_delay = 1;
- battle_config.pc_damage_delay_rate = 100;
battle_config.defnotenemy = 1;
battle_config.random_monster_checklv = 1;
battle_config.attr_recover = 1;
- battle_config.flooritem_lifetime = LIFETIME_FLOORITEM * 1000;
+ battle_config.flooritem_lifetime = (int)std::chrono::duration_cast<std::chrono::milliseconds>(LIFETIME_FLOORITEM).count();
battle_config.item_auto_get = 0;
battle_config.drop_pickup_safety_zone = 20;
battle_config.item_first_get_time = 3000;
battle_config.item_second_get_time = 1000;
battle_config.item_third_get_time = 1000;
- battle_config.mvp_item_first_get_time = 10000;
- battle_config.mvp_item_second_get_time = 10000;
- battle_config.mvp_item_third_get_time = 2000;
- battle_config.drop_rate0item = 0;
battle_config.base_exp_rate = 100;
battle_config.job_exp_rate = 100;
battle_config.pvp_exp = 1;
@@ -5481,30 +2332,23 @@ int battle_config_read (const char *cfgName)
battle_config.zeny_penalty = 0;
battle_config.restart_hp_rate = 0;
battle_config.restart_sp_rate = 0;
- battle_config.mvp_item_rate = 100;
- battle_config.mvp_exp_rate = 100;
- battle_config.mvp_hp_rate = 100;
battle_config.monster_hp_rate = 100;
battle_config.monster_max_aspd = 199;
battle_config.atc_gmonly = 0;
battle_config.gm_allskill = 0;
battle_config.gm_allequip = 0;
battle_config.gm_skilluncond = 0;
- battle_config.guild_max_castles = 0;
battle_config.skillfree = 0;
battle_config.skillup_limit = 0;
battle_config.wp_rate = 100;
battle_config.pp_rate = 100;
battle_config.monster_active_enable = 1;
- battle_config.monster_damage_delay_rate = 100;
battle_config.monster_loot_type = 0;
battle_config.mob_skill_use = 1;
battle_config.mob_count_rate = 100;
battle_config.quest_skill_learn = 0;
battle_config.quest_skill_reset = 1;
battle_config.basic_skill_check = 1;
- battle_config.guild_emperium_check = 1;
- battle_config.guild_exp_limit = 50;
battle_config.pc_invincible_time = 5000;
battle_config.skill_min_damage = 0;
battle_config.finger_offensive_type = 0;
@@ -5540,25 +2384,17 @@ int battle_config_read (const char *cfgName)
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.agi_penaly_count_lv = static_cast<int>(ATK::FLEE); // FIXME
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.player_defense_type = 0;
- battle_config.monster_defense_type = 0;
- battle_config.magic_defense_type = 0;
+ battle_config.vit_penaly_count_lv = static_cast<int>(ATK::DEF); // FIXME
battle_config.pc_skill_reiteration = 0;
battle_config.monster_skill_reiteration = 0;
battle_config.pc_skill_nofootset = 0;
battle_config.monster_skill_nofootset = 0;
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_eliminate_time = 7000;
battle_config.mob_changetarget_byskill = 0;
battle_config.pc_attack_direction_change = 1;
battle_config.monster_attack_direction_change = 1;
@@ -5590,34 +2426,12 @@ int battle_config_read (const char *cfgName)
battle_config.invite_request_check = 1;
battle_config.skill_removetrap_type = 0;
battle_config.disp_experience = 0;
- battle_config.item_rate_common = 100;
- battle_config.item_rate_equip = 100;
- battle_config.item_rate_card = 100;
- battle_config.item_rate_heal = 100; // Added by Valaris
- battle_config.item_rate_use = 100; // End
- battle_config.item_drop_common_min = 1; // Added by TyrNemesis^
- battle_config.item_drop_common_max = 10000;
- battle_config.item_drop_equip_min = 1;
- battle_config.item_drop_equip_max = 10000;
- battle_config.item_drop_card_min = 1;
- battle_config.item_drop_card_max = 10000;
- battle_config.item_drop_mvp_min = 1;
- battle_config.item_drop_mvp_max = 10000; // End Addition
- battle_config.item_drop_heal_min = 1; // Added by Valaris
- battle_config.item_drop_heal_max = 10000;
- battle_config.item_drop_use_min = 1;
- battle_config.item_drop_use_max = 10000; // End
battle_config.prevent_logout = 1; // Added by RoVeRT
battle_config.maximum_level = 255; // Added by Valaris
battle_config.drops_by_luk = 0; // [Valaris]
- battle_config.equipment_breaking = 0; // [Valaris]
- battle_config.equipment_break_rate = 100; // [Valaris]
battle_config.pk_mode = 0; // [Valaris]
battle_config.multi_level_up = 0; // [Valaris]
battle_config.backstab_bow_penalty = 0; // Akaru
- battle_config.night_at_start = 0; // added by [Yor]
- battle_config.day_duration = 2 * 60 * 60 * 1000; // added by [Yor] (2 hours)
- battle_config.night_duration = 30 * 60 * 1000; // added by [Yor] (30 minutes)
battle_config.show_mob_hp = 0; // [Valaris]
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]
@@ -5649,478 +2463,212 @@ int battle_config_read (const char *cfgName)
battle_config.mob_splash_radius = -1;
}
- fp = fopen_ (cfgName, "r");
- if (fp == NULL)
+ std::ifstream in(cfgName);
+ if (!in.is_open())
{
- printf ("file not found: %s\n", cfgName);
+ PRINTF("file not found: %s\n", cfgName);
return 1;
}
- while (fgets (line, 1020, fp))
+
+ std::string line;
+ while (std::getline(in, line))
{
+ // s/{"\([a-zA-Z_0-9]*\)", &battle_config.\1}/BATTLE_CONFIG_VAR(\1)/
const struct
{
- char str[128];
+ const char *str;
int *val;
} data[] =
{
- {
- "warp_point_debug", &battle_config.warp_point_debug},
- {
- "enemy_critical", &battle_config.enemy_critical},
- {
- "enemy_critical_rate", &battle_config.enemy_critical_rate},
- {
- "enemy_str", &battle_config.enemy_str},
- {
- "enemy_perfect_flee", &battle_config.enemy_perfect_flee},
- {
- "casting_rate", &battle_config.cast_rate},
- {
- "delay_rate", &battle_config.delay_rate},
- {
- "delay_dependon_dex", &battle_config.delay_dependon_dex},
- {
- "skill_delay_attack_enable",
- &battle_config.sdelay_attack_enable},
- {
- "left_cardfix_to_right", &battle_config.left_cardfix_to_right},
- {
- "player_skill_add_range", &battle_config.pc_skill_add_range},
- {
- "skill_out_range_consume",
- &battle_config.skill_out_range_consume},
- {
- "monster_skill_add_range", &battle_config.mob_skill_add_range},
- {
- "player_damage_delay", &battle_config.pc_damage_delay},
- {
- "player_damage_delay_rate",
- &battle_config.pc_damage_delay_rate},
- {
- "defunit_not_enemy", &battle_config.defnotenemy},
- {
- "random_monster_checklv",
- &battle_config.random_monster_checklv},
- {
- "attribute_recover", &battle_config.attr_recover},
- {
- "flooritem_lifetime", &battle_config.flooritem_lifetime},
- {
- "item_auto_get", &battle_config.item_auto_get},
- {
- "drop_pickup_safety_zone",
- &battle_config.drop_pickup_safety_zone},
- {
- "item_first_get_time", &battle_config.item_first_get_time},
- {
- "item_second_get_time", &battle_config.item_second_get_time},
- {
- "item_third_get_time", &battle_config.item_third_get_time},
- {
- "mvp_item_first_get_time",
- &battle_config.mvp_item_first_get_time},
- {
- "mvp_item_second_get_time",
- &battle_config.mvp_item_second_get_time},
- {
- "mvp_item_third_get_time",
- &battle_config.mvp_item_third_get_time},
- {
- "item_rate", &battle_config.item_rate},
- {
- "drop_rate0item", &battle_config.drop_rate0item},
- {
- "base_exp_rate", &battle_config.base_exp_rate},
- {
- "job_exp_rate", &battle_config.job_exp_rate},
- {
- "pvp_exp", &battle_config.pvp_exp},
- {
- "gtb_pvp_only", &battle_config.gtb_pvp_only},
- {
- "guild_max_castles", &battle_config.guild_max_castles},
- {
- "death_penalty_type", &battle_config.death_penalty_type},
- {
- "death_penalty_base", &battle_config.death_penalty_base},
- {
- "death_penalty_job", &battle_config.death_penalty_job},
- {
- "zeny_penalty", &battle_config.zeny_penalty},
- {
- "restart_hp_rate", &battle_config.restart_hp_rate},
- {
- "restart_sp_rate", &battle_config.restart_sp_rate},
- {
- "mvp_hp_rate", &battle_config.mvp_hp_rate},
- {
- "mvp_item_rate", &battle_config.mvp_item_rate},
- {
- "mvp_exp_rate", &battle_config.mvp_exp_rate},
- {
- "monster_hp_rate", &battle_config.monster_hp_rate},
- {
- "monster_max_aspd", &battle_config.monster_max_aspd},
- {
- "atcommand_gm_only", &battle_config.atc_gmonly},
- {
- "atcommand_spawn_quantity_limit",
- &battle_config.atc_spawn_quantity_limit},
- {
- "gm_all_skill", &battle_config.gm_allskill},
- {
- "gm_all_skill_add_abra", &battle_config.gm_allskill_addabra},
- {
- "gm_all_equipment", &battle_config.gm_allequip},
- {
- "gm_skill_unconditional", &battle_config.gm_skilluncond},
- {
- "player_skillfree", &battle_config.skillfree},
- {
- "player_skillup_limit", &battle_config.skillup_limit},
- {
- "weapon_produce_rate", &battle_config.wp_rate},
- {
- "potion_produce_rate", &battle_config.pp_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},
- {
- "mob_skill_use", &battle_config.mob_skill_use},
- {
- "mob_count_rate", &battle_config.mob_count_rate},
- {
- "quest_skill_learn", &battle_config.quest_skill_learn},
- {
- "quest_skill_reset", &battle_config.quest_skill_reset},
- {
- "basic_skill_check", &battle_config.basic_skill_check},
- {
- "guild_emperium_check", &battle_config.guild_emperium_check},
- {
- "guild_exp_limit", &battle_config.guild_exp_limit},
- {
- "player_invincible_time", &battle_config.pc_invincible_time},
- {
- "skill_min_damage", &battle_config.skill_min_damage},
- {
- "finger_offensive_type", &battle_config.finger_offensive_type},
- {
- "heal_exp", &battle_config.heal_exp},
- {
- "resurrection_exp", &battle_config.resurrection_exp},
- {
- "shop_exp", &battle_config.shop_exp},
- {
- "combo_delay_rate", &battle_config.combo_delay_rate},
- {
- "item_check", &battle_config.item_check},
- {
- "wedding_modifydisplay", &battle_config.wedding_modifydisplay},
- {
- "natural_healhp_interval",
- &battle_config.natural_healhp_interval},
- {
- "natural_healsp_interval",
- &battle_config.natural_healsp_interval},
- {
- "natural_heal_skill_interval",
- &battle_config.natural_heal_skill_interval},
- {
- "natural_heal_weight_rate",
- &battle_config.natural_heal_weight_rate},
- {
- "itemheal_regeneration_factor",
- &battle_config.itemheal_regeneration_factor},
- {
- "item_name_override_grffile",
- &battle_config.item_name_override_grffile},
- {
- "arrow_decrement", &battle_config.arrow_decrement},
- {
- "max_aspd", &battle_config.max_aspd},
- {
- "max_hp", &battle_config.max_hp},
- {
- "max_sp", &battle_config.max_sp},
- {
- "max_lv", &battle_config.max_lv},
- {
- "max_parameter", &battle_config.max_parameter},
- {
- "max_cart_weight", &battle_config.max_cart_weight},
- {
- "player_skill_log", &battle_config.pc_skill_log},
- {
- "monster_skill_log", &battle_config.mob_skill_log},
- {
- "battle_log", &battle_config.battle_log},
- {
- "save_log", &battle_config.save_log},
- {
- "error_log", &battle_config.error_log},
- {
- "etc_log", &battle_config.etc_log},
- {
- "save_clothcolor", &battle_config.save_clothcolor},
- {
- "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},
- {
- "player_defense_type", &battle_config.player_defense_type},
- {
- "monster_defense_type", &battle_config.monster_defense_type},
- {
- "magic_defense_type", &battle_config.magic_defense_type},
- {
- "player_skill_reiteration",
- &battle_config.pc_skill_reiteration},
- {
- "monster_skill_reiteration",
- &battle_config.monster_skill_reiteration},
- {
- "player_skill_nofootset", &battle_config.pc_skill_nofootset},
- {
- "monster_skill_nofootset",
- &battle_config.monster_skill_nofootset},
- {
- "player_cloak_check_type", &battle_config.pc_cloak_check_type},
- {
- "monster_cloak_check_type",
- &battle_config.monster_cloak_check_type},
- {
- "gvg_short_attack_damage_rate",
- &battle_config.gvg_short_damage_rate},
- {
- "gvg_long_attack_damage_rate",
- &battle_config.gvg_long_damage_rate},
- {
- "gvg_magic_attack_damage_rate",
- &battle_config.gvg_magic_damage_rate},
- {
- "gvg_misc_attack_damage_rate",
- &battle_config.gvg_misc_damage_rate},
- {
- "gvg_eliminate_time", &battle_config.gvg_eliminate_time},
- {
- "mob_changetarget_byskill",
- &battle_config.mob_changetarget_byskill},
- {
- "player_attack_direction_change",
- &battle_config.pc_attack_direction_change},
- {
- "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},
- {
- "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},
- {
- "making_arrow_name_input",
- &battle_config.making_arrow_name_input},
- {
- "holywater_name_input", &battle_config.holywater_name_input},
- {
- "display_delay_skill_fail",
- &battle_config.display_delay_skill_fail},
- {
- "chat_warpportal", &battle_config.chat_warpportal},
- {
- "mob_warpportal", &battle_config.mob_warpportal},
- {
- "dead_branch_active", &battle_config.dead_branch_active},
- {
- "show_steal_in_same_party",
- &battle_config.show_steal_in_same_party},
- {
- "enable_upper_class", &battle_config.enable_upper_class},
- {
- "mob_attack_attr_none", &battle_config.mob_attack_attr_none},
- {
- "mob_ghostring_fix", &battle_config.mob_ghostring_fix},
- {
- "pc_attack_attr_none", &battle_config.pc_attack_attr_none},
- {
- "gx_allhit", &battle_config.gx_allhit},
- {
- "gx_cardfix", &battle_config.gx_cardfix},
- {
- "gx_dupele", &battle_config.gx_dupele},
- {
- "gx_disptype", &battle_config.gx_disptype},
- {
- "player_skill_partner_check",
- &battle_config.player_skill_partner_check},
- {
- "hide_GM_session", &battle_config.hide_GM_session},
- {
- "unit_movement_type", &battle_config.unit_movement_type},
- {
- "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},
- {
- "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
- {
- "item_rate_heal", &battle_config.item_rate_heal}, // Added by Valaris
- {
- "item_rate_use", &battle_config.item_rate_use}, // End
- {
- "item_drop_common_min", &battle_config.item_drop_common_min}, // Added by TyrNemesis^
- {
- "item_drop_common_max", &battle_config.item_drop_common_max},
- {
- "item_drop_equip_min", &battle_config.item_drop_equip_min},
- {
- "item_drop_equip_max", &battle_config.item_drop_equip_max},
- {
- "item_drop_card_min", &battle_config.item_drop_card_min},
- {
- "item_drop_card_max", &battle_config.item_drop_card_max},
- {
- "item_drop_mvp_min", &battle_config.item_drop_mvp_min},
- {
- "item_drop_mvp_max", &battle_config.item_drop_mvp_max}, // End Addition
- {
- "prevent_logout", &battle_config.prevent_logout}, // Added by RoVeRT
- {
- "alchemist_summon_reward", &battle_config.alchemist_summon_reward}, // [Valaris]
- {
- "maximum_level", &battle_config.maximum_level}, // [Valaris]
- {
- "drops_by_luk", &battle_config.drops_by_luk}, // [Valaris]
- {
- "monsters_ignore_gm", &battle_config.monsters_ignore_gm}, // [Valaris]
- {
- "equipment_breaking", &battle_config.equipment_breaking}, // [Valaris]
- {
- "equipment_break_rate", &battle_config.equipment_break_rate}, // [Valaris]
- {
- "pk_mode", &battle_config.pk_mode}, // [Valaris]
- {
- "multi_level_up", &battle_config.multi_level_up}, // [Valaris]
- {
- "backstab_bow_penalty", &battle_config.backstab_bow_penalty},
- {
- "night_at_start", &battle_config.night_at_start}, // added by [Yor]
- {
- "day_duration", &battle_config.day_duration}, // added by [Yor]
- {
- "night_duration", &battle_config.night_duration}, // added by [Yor]
- {
- "show_mob_hp", &battle_config.show_mob_hp}, // [Valaris]
- {
- "hack_info_GM_level", &battle_config.hack_info_GM_level}, // added by [Yor]
- {
- "any_warp_GM_min_level", &battle_config.any_warp_GM_min_level}, // added by [Yor]
- {
- "packet_ver_flag", &battle_config.packet_ver_flag}, // added by [Yor]
- {
- "min_hair_style", &battle_config.min_hair_style}, // added by [MouseJstr]
- {
- "max_hair_style", &battle_config.max_hair_style}, // added by [MouseJstr]
- {
- "min_hair_color", &battle_config.min_hair_color}, // added by [MouseJstr]
- {
- "max_hair_color", &battle_config.max_hair_color}, // added by [MouseJstr]
- {
- "min_cloth_color", &battle_config.min_cloth_color}, // added by [MouseJstr]
- {
- "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]
- {
- "chat_lame_penalty", &battle_config.chat_lame_penalty},
- {
- "chat_spam_threshold", &battle_config.chat_spam_threshold},
- {
- "chat_spam_flood", &battle_config.chat_spam_flood},
- {
- "chat_spam_ban", &battle_config.chat_spam_ban},
- {
- "chat_spam_warn", &battle_config.chat_spam_warn},
- {
- "chat_maxline", &battle_config.chat_maxline},
- {
- "packet_spam_threshold", &battle_config.packet_spam_threshold},
- {
- "packet_spam_flood", &battle_config.packet_spam_flood},
- {
- "packet_spam_kick", &battle_config.packet_spam_kick},
- {
- "mask_ip_gms", &battle_config.mask_ip_gms},
- {
- "mob_splash_radius", &battle_config.mob_splash_radius},
+ {"warp_point_debug", &battle_config.warp_point_debug},
+ {"enemy_critical", &battle_config.enemy_critical},
+ {"enemy_critical_rate", &battle_config.enemy_critical_rate},
+ {"enemy_str", &battle_config.enemy_str},
+ {"enemy_perfect_flee", &battle_config.enemy_perfect_flee},
+ {"casting_rate", &battle_config.cast_rate},
+ {"delay_rate", &battle_config.delay_rate},
+ {"delay_dependon_dex", &battle_config.delay_dependon_dex},
+ {"skill_delay_attack_enable", &battle_config.sdelay_attack_enable},
+ {"left_cardfix_to_right", &battle_config.left_cardfix_to_right},
+ {"player_skill_add_range", &battle_config.pc_skill_add_range},
+ {"skill_out_range_consume", &battle_config.skill_out_range_consume},
+ {"monster_skill_add_range", &battle_config.mob_skill_add_range},
+ {"player_damage_delay", &battle_config.pc_damage_delay},
+ {"defunit_not_enemy", &battle_config.defnotenemy},
+ {"random_monster_checklv", &battle_config.random_monster_checklv},
+ {"attribute_recover", &battle_config.attr_recover},
+ {"flooritem_lifetime", &battle_config.flooritem_lifetime},
+ {"item_auto_get", &battle_config.item_auto_get},
+ {"drop_pickup_safety_zone", &battle_config.drop_pickup_safety_zone},
+ {"item_first_get_time", &battle_config.item_first_get_time},
+ {"item_second_get_time", &battle_config.item_second_get_time},
+ {"item_third_get_time", &battle_config.item_third_get_time},
+ {"base_exp_rate", &battle_config.base_exp_rate},
+ {"job_exp_rate", &battle_config.job_exp_rate},
+ {"pvp_exp", &battle_config.pvp_exp},
+ {"gtb_pvp_only", &battle_config.gtb_pvp_only},
+ {"death_penalty_type", &battle_config.death_penalty_type},
+ {"death_penalty_base", &battle_config.death_penalty_base},
+ {"death_penalty_job", &battle_config.death_penalty_job},
+ {"zeny_penalty", &battle_config.zeny_penalty},
+ {"restart_hp_rate", &battle_config.restart_hp_rate},
+ {"restart_sp_rate", &battle_config.restart_sp_rate},
+ {"monster_hp_rate", &battle_config.monster_hp_rate},
+ {"monster_max_aspd", &battle_config.monster_max_aspd},
+ {"atcommand_gm_only", &battle_config.atc_gmonly},
+ {"atcommand_spawn_quantity_limit", &battle_config.atc_spawn_quantity_limit},
+ {"gm_all_skill", &battle_config.gm_allskill},
+ {"gm_all_skill_add_abra", &battle_config.gm_allskill_addabra},
+ {"gm_all_equipment", &battle_config.gm_allequip},
+ {"gm_skill_unconditional", &battle_config.gm_skilluncond},
+ {"player_skillfree", &battle_config.skillfree},
+ {"player_skillup_limit", &battle_config.skillup_limit},
+ {"weapon_produce_rate", &battle_config.wp_rate},
+ {"potion_produce_rate", &battle_config.pp_rate},
+ {"monster_active_enable", &battle_config.monster_active_enable},
+ {"monster_loot_type", &battle_config.monster_loot_type},
+ {"mob_skill_use", &battle_config.mob_skill_use},
+ {"mob_count_rate", &battle_config.mob_count_rate},
+ {"quest_skill_learn", &battle_config.quest_skill_learn},
+ {"quest_skill_reset", &battle_config.quest_skill_reset},
+ {"basic_skill_check", &battle_config.basic_skill_check},
+ {"player_invincible_time", &battle_config.pc_invincible_time},
+ {"skill_min_damage", &battle_config.skill_min_damage},
+ {"finger_offensive_type", &battle_config.finger_offensive_type},
+ {"heal_exp", &battle_config.heal_exp},
+ {"resurrection_exp", &battle_config.resurrection_exp},
+ {"shop_exp", &battle_config.shop_exp},
+ {"combo_delay_rate", &battle_config.combo_delay_rate},
+ {"item_check", &battle_config.item_check},
+ {"wedding_modifydisplay", &battle_config.wedding_modifydisplay},
+ {"natural_healhp_interval", &battle_config.natural_healhp_interval},
+ {"natural_healsp_interval", &battle_config.natural_healsp_interval},
+ {"natural_heal_skill_interval", &battle_config.natural_heal_skill_interval},
+ {"natural_heal_weight_rate", &battle_config.natural_heal_weight_rate},
+ {"itemheal_regeneration_factor", &battle_config.itemheal_regeneration_factor},
+ {"item_name_override_grffile", &battle_config.item_name_override_grffile},
+ {"arrow_decrement", &battle_config.arrow_decrement},
+ {"max_aspd", &battle_config.max_aspd},
+ {"max_hp", &battle_config.max_hp},
+ {"max_sp", &battle_config.max_sp},
+ {"max_lv", &battle_config.max_lv},
+ {"max_parameter", &battle_config.max_parameter},
+ {"max_cart_weight", &battle_config.max_cart_weight},
+ {"player_skill_log", &battle_config.pc_skill_log},
+ {"monster_skill_log", &battle_config.mob_skill_log},
+ {"battle_log", &battle_config.battle_log},
+ {"save_log", &battle_config.save_log},
+ {"error_log", &battle_config.error_log},
+ {"etc_log", &battle_config.etc_log},
+ {"save_clothcolor", &battle_config.save_clothcolor},
+ {"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},
+ {"player_skill_reiteration", &battle_config.pc_skill_reiteration},
+ {"monster_skill_reiteration", &battle_config.monster_skill_reiteration},
+ {"player_skill_nofootset", &battle_config.pc_skill_nofootset},
+ {"monster_skill_nofootset", &battle_config.monster_skill_nofootset},
+ {"player_cloak_check_type", &battle_config.pc_cloak_check_type},
+ {"monster_cloak_check_type", &battle_config.monster_cloak_check_type},
+ {"mob_changetarget_byskill", &battle_config.mob_changetarget_byskill},
+ {"player_attack_direction_change", &battle_config.pc_attack_direction_change},
+ {"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},
+ {"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},
+ {"making_arrow_name_input", &battle_config.making_arrow_name_input},
+ {"holywater_name_input", &battle_config.holywater_name_input},
+ {"display_delay_skill_fail", &battle_config.display_delay_skill_fail},
+ {"chat_warpportal", &battle_config.chat_warpportal},
+ {"mob_warpportal", &battle_config.mob_warpportal},
+ {"dead_branch_active", &battle_config.dead_branch_active},
+ {"show_steal_in_same_party", &battle_config.show_steal_in_same_party},
+ {"enable_upper_class", &battle_config.enable_upper_class},
+ {"mob_attack_attr_none", &battle_config.mob_attack_attr_none},
+ {"mob_ghostring_fix", &battle_config.mob_ghostring_fix},
+ {"pc_attack_attr_none", &battle_config.pc_attack_attr_none},
+ {"gx_allhit", &battle_config.gx_allhit},
+ {"gx_cardfix", &battle_config.gx_cardfix},
+ {"gx_dupele", &battle_config.gx_dupele},
+ {"gx_disptype", &battle_config.gx_disptype},
+ {"player_skill_partner_check", &battle_config.player_skill_partner_check},
+ {"hide_GM_session", &battle_config.hide_GM_session},
+ {"unit_movement_type", &battle_config.unit_movement_type},
+ {"invite_request_check", &battle_config.invite_request_check},
+ {"skill_removetrap_type", &battle_config.skill_removetrap_type},
+ {"disp_experience", &battle_config.disp_experience},
+ {"riding_weight", &battle_config.riding_weight},
+ {"prevent_logout", &battle_config.prevent_logout}, // Added by RoVeRT
+ {"alchemist_summon_reward", &battle_config.alchemist_summon_reward}, // [Valaris]
+ {"maximum_level", &battle_config.maximum_level}, // [Valaris]
+ {"drops_by_luk", &battle_config.drops_by_luk}, // [Valaris]
+ {"monsters_ignore_gm", &battle_config.monsters_ignore_gm}, // [Valaris]
+ {"pk_mode", &battle_config.pk_mode}, // [Valaris]
+ {"multi_level_up", &battle_config.multi_level_up}, // [Valaris]
+ {"backstab_bow_penalty", &battle_config.backstab_bow_penalty},
+ {"show_mob_hp", &battle_config.show_mob_hp}, // [Valaris]
+ {"hack_info_GM_level", &battle_config.hack_info_GM_level}, // added by [Yor]
+ {"any_warp_GM_min_level", &battle_config.any_warp_GM_min_level}, // added by [Yor]
+ {"packet_ver_flag", &battle_config.packet_ver_flag}, // added by [Yor]
+ {"min_hair_style", &battle_config.min_hair_style}, // added by [MouseJstr]
+ {"max_hair_style", &battle_config.max_hair_style}, // added by [MouseJstr]
+ {"min_hair_color", &battle_config.min_hair_color}, // added by [MouseJstr]
+ {"max_hair_color", &battle_config.max_hair_color}, // added by [MouseJstr]
+ {"min_cloth_color", &battle_config.min_cloth_color}, // added by [MouseJstr]
+ {"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]
+ {"chat_lame_penalty", &battle_config.chat_lame_penalty},
+ {"chat_spam_threshold", &battle_config.chat_spam_threshold},
+ {"chat_spam_flood", &battle_config.chat_spam_flood},
+ {"chat_spam_ban", &battle_config.chat_spam_ban},
+ {"chat_spam_warn", &battle_config.chat_spam_warn},
+ {"chat_maxline", &battle_config.chat_maxline},
+ {"packet_spam_threshold", &battle_config.packet_spam_threshold},
+ {"packet_spam_flood", &battle_config.packet_spam_flood},
+ {"packet_spam_kick", &battle_config.packet_spam_kick},
+ {"mask_ip_gms", &battle_config.mask_ip_gms},
+ {"mob_splash_radius", &battle_config.mob_splash_radius},
};
- if (line[0] == '/' && line[1] == '/')
+ std::string w1, w2;
+ if (!split_key_value(line, &w1, &w2))
continue;
- if (sscanf (line, "%[^:]:%s", w1, w2) != 2)
+
+ if (w1 == "import")
+ {
+ battle_config_read(w2.c_str());
continue;
- for (i = 0; i < sizeof (data) / (sizeof (data[0])); i++)
- if (strcasecmp (w1, data[i].str) == 0)
- *data[i].val = battle_config_switch (w2);
+ }
+
+ for (auto datum : data)
+ if (w1 == datum.str)
+ {
+ *datum.val = config_switch(w2.c_str());
+ goto continue_outer;
+ }
- if (strcasecmp (w1, "import") == 0)
- battle_config_read (w2);
+ PRINTF("WARNING: unknown battle conf key: %s\n", w1);
+
+ continue_outer:
+ ;
}
- fclose_ (fp);
if (--count == 0)
{
- if (battle_config.flooritem_lifetime < 1000)
- battle_config.flooritem_lifetime = LIFETIME_FLOORITEM * 1000;
+ if (static_cast<interval_t>(battle_config.flooritem_lifetime) < std::chrono::seconds(1))
+ battle_config.flooritem_lifetime = (int)std::chrono::duration_cast<std::chrono::milliseconds>(LIFETIME_FLOORITEM).count();
if (battle_config.restart_hp_rate < 0)
battle_config.restart_hp_rate = 0;
else if (battle_config.restart_hp_rate > 100)
@@ -6129,12 +2677,12 @@ int battle_config_read (const char *cfgName)
battle_config.restart_sp_rate = 0;
else if (battle_config.restart_sp_rate > 100)
battle_config.restart_sp_rate = 100;
- if (battle_config.natural_healhp_interval < NATURAL_HEAL_INTERVAL)
- battle_config.natural_healhp_interval = NATURAL_HEAL_INTERVAL;
- if (battle_config.natural_healsp_interval < NATURAL_HEAL_INTERVAL)
- battle_config.natural_healsp_interval = NATURAL_HEAL_INTERVAL;
- if (battle_config.natural_heal_skill_interval < NATURAL_HEAL_INTERVAL)
- battle_config.natural_heal_skill_interval = NATURAL_HEAL_INTERVAL;
+ if (battle_config.natural_healhp_interval < NATURAL_HEAL_INTERVAL.count())
+ battle_config.natural_healhp_interval = NATURAL_HEAL_INTERVAL.count();
+ if (battle_config.natural_healsp_interval < NATURAL_HEAL_INTERVAL.count())
+ battle_config.natural_healsp_interval = NATURAL_HEAL_INTERVAL.count();
+ if (battle_config.natural_heal_skill_interval < NATURAL_HEAL_INTERVAL.count())
+ battle_config.natural_heal_skill_interval = NATURAL_HEAL_INTERVAL.count();
if (battle_config.natural_heal_weight_rate < 50)
battle_config.natural_heal_weight_rate = 50;
if (battle_config.natural_heal_weight_rate > 101)
@@ -6173,41 +2721,6 @@ int battle_config_read (const char *cfgName)
if (battle_config.vit_penaly_count < 2)
battle_config.vit_penaly_count = 2;
- if (battle_config.guild_exp_limit > 99)
- battle_config.guild_exp_limit = 99;
- if (battle_config.guild_exp_limit < 0)
- battle_config.guild_exp_limit = 0;
-
- if (battle_config.castle_defense_rate < 0)
- battle_config.castle_defense_rate = 0;
- if (battle_config.castle_defense_rate > 100)
- battle_config.castle_defense_rate = 100;
- if (battle_config.item_drop_common_min < 1) // Added by TyrNemesis^
- battle_config.item_drop_common_min = 1;
- if (battle_config.item_drop_common_max > 10000)
- battle_config.item_drop_common_max = 10000;
- if (battle_config.item_drop_equip_min < 1)
- battle_config.item_drop_equip_min = 1;
- if (battle_config.item_drop_equip_max > 10000)
- battle_config.item_drop_equip_max = 10000;
- if (battle_config.item_drop_card_min < 1)
- battle_config.item_drop_card_min = 1;
- if (battle_config.item_drop_card_max > 10000)
- battle_config.item_drop_card_max = 10000;
- if (battle_config.item_drop_mvp_min < 1)
- battle_config.item_drop_mvp_min = 1;
- if (battle_config.item_drop_mvp_max > 10000)
- battle_config.item_drop_mvp_max = 10000; // End Addition
-
- if (battle_config.night_at_start < 0) // added by [Yor]
- 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.hack_info_GM_level < 0) // added by [Yor]
battle_config.hack_info_GM_level = 0;
else if (battle_config.hack_info_GM_level > 100)