Renewal Monster Updates (#3541)
* Renewal Monster's ATK & MATK Calculation Updates * Renewal Monster database updates * ATK1 is *base* ATK, the range 80%~120% is calculated in src * ATK2 is *base* MATK, the range 70%~130% is calculated in src * Adjusted ATK range min~max in mobinfo atcommand * Nothing was changed in pre-renewal system! * Thanks to @aleos89, @slyx88 and Divine-Pride.net
This commit is contained in:
parent
8e7b9a57c0
commit
fe197bfa12
@ -10,7 +10,7 @@
|
||||
//--------------------------------------------------------------
|
||||
|
||||
// Who should have a baseatk value (makes str affect damage)? (Note 3)
|
||||
enable_baseatk: 9
|
||||
enable_baseatk: 0x29F
|
||||
|
||||
// Who can have perfect flee? (Note 3)
|
||||
enable_perfect_flee: 1
|
||||
|
4610
db/re/mob_db.txt
4610
db/re/mob_db.txt
File diff suppressed because it is too large
Load Diff
@ -7228,7 +7228,7 @@ ACMD_FUNC(mobinfo)
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
|
||||
sprintf(atcmd_output, msg_txt(sd,1244), // ATK:%d~%d Range:%d~%d~%d Size:%s Race: %s Element: %s (Lv:%d)
|
||||
mob->status.rhw.atk, mob->status.rhw.atk2, mob->status.rhw.range,
|
||||
mob->status.batk + mob->status.rhw.atk, mob->status.batk + mob->status.rhw.atk2, mob->status.rhw.range,
|
||||
mob->range2 , mob->range3, msize[mob->status.size],
|
||||
mrace[mob->status.race], melement[mob->status.def_ele], mob->status.ele_lv);
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
|
@ -8012,7 +8012,7 @@ static const struct _battle_data {
|
||||
{ "enable_critical", &battle_config.enable_critical, BL_PC, BL_NUL, BL_ALL, },
|
||||
{ "mob_critical_rate", &battle_config.mob_critical_rate, 100, 0, INT_MAX, },
|
||||
{ "critical_rate", &battle_config.critical_rate, 100, 0, INT_MAX, },
|
||||
{ "enable_baseatk", &battle_config.enable_baseatk, BL_PC|BL_HOM, BL_NUL, BL_ALL, },
|
||||
{ "enable_baseatk", &battle_config.enable_baseatk, BL_CHAR|BL_NPC, BL_NUL, BL_ALL, },
|
||||
{ "enable_perfect_flee", &battle_config.enable_perfect_flee, BL_PC|BL_PET, BL_NUL, BL_ALL, },
|
||||
{ "casting_rate", &battle_config.cast_rate, 100, 0, INT_MAX, },
|
||||
{ "delay_rate", &battle_config.delay_rate, 100, 0, INT_MAX, },
|
||||
|
@ -1515,11 +1515,7 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
|
||||
WBUFW(buf,29) = hd->homunculus.hunger;
|
||||
WBUFW(buf,31) = (unsigned short) (hd->homunculus.intimacy / 100) ;
|
||||
WBUFW(buf,33) = 0; // equip id
|
||||
#ifdef RENEWAL
|
||||
WBUFW(buf,35) = cap_value(status->rhw.atk2, 0, INT16_MAX);
|
||||
#else
|
||||
WBUFW(buf,35) = cap_value(status->rhw.atk2+status->batk, 0, INT16_MAX);
|
||||
#endif
|
||||
WBUFW(buf,35) = cap_value(status->rhw.atk2 + status->batk, 0, INT16_MAX);
|
||||
WBUFW(buf,37)=i16min(status->matk_max, INT16_MAX); //FIXME capping to INT16 here is too late
|
||||
WBUFW(buf,39)=status->hit;
|
||||
if (battle_config.hom_setting&HOMSET_DISPLAY_LUK)
|
||||
@ -17004,7 +17000,7 @@ void clif_mercenary_updatestatus(struct map_session_data *sd, int type)
|
||||
switch( type ) {
|
||||
case SP_ATK1:
|
||||
{
|
||||
int atk = rnd()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
|
||||
int atk = rnd()%(status->rhw.atk2 - status->rhw.atk + 1) + status->batk + status->rhw.atk;
|
||||
WFIFOL(fd,4) = cap_value(atk, 0, INT16_MAX);
|
||||
}
|
||||
break;
|
||||
@ -17074,7 +17070,7 @@ void clif_mercenary_info(struct map_session_data *sd)
|
||||
WFIFOL(fd,2) = md->bl.id;
|
||||
|
||||
// Mercenary shows ATK as a random value between ATK ~ ATK2
|
||||
atk = rnd()%(status->rhw.atk2 - status->rhw.atk + 1) + status->rhw.atk;
|
||||
atk = rnd()%(status->rhw.atk2 - status->rhw.atk + 1) + status->batk + status->rhw.atk;
|
||||
WFIFOW(fd,6) = cap_value(atk, 0, INT16_MAX);
|
||||
WFIFOW(fd,8) = min(status->matk_max, UINT16_MAX);
|
||||
WFIFOW(fd,10) = status->hit;
|
||||
|
@ -783,8 +783,13 @@ static bool read_elementaldb_sub(char* str[], int columns, int current) {
|
||||
status->max_hp = atoi(str[4]);
|
||||
status->max_sp = atoi(str[5]);
|
||||
status->rhw.range = atoi(str[6]);
|
||||
status->rhw.atk = atoi(str[7]);
|
||||
status->rhw.atk2 = atoi(str[8]);
|
||||
#ifdef RENEWAL
|
||||
status->rhw.atk = atoi(str[7]); // BaseATK
|
||||
status->rhw.matk = atoi(str[8]); // BaseMATK
|
||||
#else
|
||||
status->rhw.atk = atoi(str[7]); // MinATK
|
||||
status->rhw.atk2 = atoi(str[8]); // MaxATK
|
||||
#endif
|
||||
status->def = atoi(str[9]);
|
||||
status->mdef = atoi(str[10]);
|
||||
status->str = atoi(str[11]);
|
||||
|
@ -4118,8 +4118,13 @@ static bool mob_parse_dbrow(char** str)
|
||||
entry.job_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
|
||||
|
||||
status->rhw.range = atoi(str[9]);
|
||||
status->rhw.atk = atoi(str[10]);
|
||||
status->rhw.atk2 = atoi(str[11]);
|
||||
#ifdef RENEWAL
|
||||
status->rhw.atk = atoi(str[10]); // BaseATK
|
||||
status->rhw.matk = atoi(str[11]); // BaseMATK
|
||||
#else
|
||||
status->rhw.atk = atoi(str[10]); // MinATK
|
||||
status->rhw.atk2 = atoi(str[11]); // MaxATK
|
||||
#endif
|
||||
status->def = atoi(str[12]);
|
||||
status->mdef = atoi(str[13]);
|
||||
status->str = atoi(str[14]);
|
||||
|
@ -970,7 +970,7 @@ short pc_maxaspd(struct map_session_data *sd);
|
||||
#define pc_rightside_def(sd) ((sd)->battle_status.def)
|
||||
#define pc_leftside_mdef(sd) ((sd)->battle_status.mdef2)
|
||||
#define pc_rightside_mdef(sd) ((sd)->battle_status.mdef)
|
||||
#define pc_leftside_matk(sd) (status_base_matk(&(sd)->bl, status_get_status_data(&(sd)->bl), (sd)->status.base_level))
|
||||
#define pc_leftside_matk(sd) (status_base_matk_min(&(sd)->bl, status_get_status_data(&(sd)->bl), (sd)->status.base_level))
|
||||
#define pc_rightside_matk(sd) ((sd)->battle_status.rhw.matk+(sd)->battle_status.lhw.matk+(sd)->bonus.ematk)
|
||||
#else
|
||||
#define pc_leftside_atk(sd) ((sd)->battle_status.batk + (sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk)
|
||||
|
@ -550,7 +550,8 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
|
||||
struct status_data *status = status_get_status_data(src);
|
||||
int min, max;
|
||||
|
||||
min = max = status_base_matk(src, status, status_get_lv(src));
|
||||
min = status_base_matk_min(src, status, status_get_lv(src));
|
||||
max = status_base_matk_max(src, status, status_get_lv(src));
|
||||
if( status->rhw.matk > 0 ){
|
||||
int wMatk, variance;
|
||||
wMatk = status->rhw.matk;
|
||||
@ -10725,7 +10726,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
{
|
||||
int heal = 5 * status_get_lv(&hd->bl) +
|
||||
#ifdef RENEWAL
|
||||
status_base_matk(bl, &hd->battle_status, status_get_lv(&hd->bl));
|
||||
status_base_matk_min(bl, &hd->battle_status, status_get_lv(&hd->bl));
|
||||
#else
|
||||
status_base_matk_min(&hd->battle_status);
|
||||
#endif
|
||||
|
@ -2420,12 +2420,11 @@ int status_base_amotion_pc(struct map_session_data* sd, struct status_data* stat
|
||||
|
||||
/**
|
||||
* Base attack value calculated for units
|
||||
* @param bl: Object to get attack for [PC|HOM]
|
||||
* @param bl: Object to get attack for [BL_CHAR|BL_NPC]
|
||||
* @param status: Object status
|
||||
* @return base attack
|
||||
* Note: Function only calculates Homunculus bATK in RENEWAL
|
||||
*/
|
||||
unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status)
|
||||
unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status, int level)
|
||||
{
|
||||
int flag = 0, str, dex, dstr;
|
||||
|
||||
@ -2457,25 +2456,36 @@ unsigned short status_base_atk(const struct block_list *bl, const struct status_
|
||||
str = status->str;
|
||||
dex = status->dex;
|
||||
}
|
||||
|
||||
/** [Skotlex]
|
||||
* Normally only players have base-atk, but homunc have a different batk
|
||||
* equation, hinting that perhaps non-players should use this for batk.
|
||||
**/
|
||||
switch (bl->type) {
|
||||
case BL_HOM:
|
||||
#ifdef RENEWAL
|
||||
if (bl->type == BL_HOM)
|
||||
str = 2 * ((((TBL_HOM*)bl)->homunculus.level) + status_get_homstr(bl));
|
||||
str = 2 * level + status_get_homstr(bl);
|
||||
#else
|
||||
dstr = str/10;
|
||||
str += dstr*dstr;
|
||||
dstr = str / 10;
|
||||
str += dstr*dstr;
|
||||
#endif
|
||||
if (bl->type == BL_PC)
|
||||
break;
|
||||
case BL_PC:
|
||||
#ifdef RENEWAL
|
||||
str = (dstr*10 + dex*10/5 + status->luk*10/3 + ((TBL_PC*)bl)->status.base_level*10/4)/10;
|
||||
else if (bl->type == BL_MOB || bl->type == BL_MER)
|
||||
str = dstr + ((TBL_MOB*)bl)->level;
|
||||
str = (dstr * 10 + dex * 10 / 5 + status->luk * 10 / 3 + level * 10 / 4) / 10;
|
||||
#else
|
||||
str+= dex/5 + status->luk/5;
|
||||
str += dex / 5 + status->luk / 5;
|
||||
#endif
|
||||
break;
|
||||
default:// Others
|
||||
#ifdef RENEWAL
|
||||
str = dstr + level;
|
||||
#else
|
||||
str += dex / 5 + status->luk / 5;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return cap_value(str, 0, USHRT_MAX);
|
||||
}
|
||||
|
||||
@ -2501,22 +2511,79 @@ unsigned int status_weapon_atk(struct weapon_atk wa, struct map_session_data *sd
|
||||
#endif
|
||||
|
||||
#ifndef RENEWAL
|
||||
unsigned short status_base_matk_min(const struct status_data* status) { return status->int_ + (status->int_ / 7) * (status->int_ / 7); }
|
||||
unsigned short status_base_matk_max(const struct status_data* status) { return status->int_ + (status->int_ / 5) * (status->int_ / 5); }
|
||||
#endif
|
||||
|
||||
#ifdef RENEWAL
|
||||
unsigned short status_base_matk(struct block_list *bl, const struct status_data* status, int level)
|
||||
unsigned short status_base_matk_min(const struct status_data* status) { return status->int_ + (status->int_ / 7) * (status->int_ / 7); }
|
||||
unsigned short status_base_matk_max(const struct status_data* status) { return status->int_ + (status->int_ / 5) * (status->int_ / 5); }
|
||||
#else
|
||||
/*
|
||||
* Calculates minimum attack variance 80% from db's ATK1 for non BL_PC
|
||||
* status->batk (base attack) will be added in battle_calc_base_damage
|
||||
*/
|
||||
unsigned short status_base_atk_min(struct block_list *bl, const struct status_data* status, int level)
|
||||
{
|
||||
switch (bl->type) {
|
||||
case BL_PET:
|
||||
case BL_MOB:
|
||||
///! TODO: Confirm these RENEWAL calculations. Currently is using previous calculation before 083cf5d9 (issue: #321) and until re/mob_db.txt is updated.
|
||||
//return status->int_ + level;
|
||||
return status->int_ + (status->int_ / 2) + (status->dex / 5) + (status->luk / 3) + (level / 4);
|
||||
case BL_HOM:
|
||||
return status_get_homint(bl) + level;
|
||||
case BL_MER:
|
||||
return status->int_ + status->int_ / 5 * status->int_ / 5;
|
||||
case BL_ELEM:
|
||||
return status->rhw.atk * 80 / 100;
|
||||
case BL_HOM:
|
||||
return (status_get_homstr(bl) + status_get_homdex(bl)) / 5;
|
||||
default:
|
||||
return status->rhw.atk;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates maximum attack variance 120% from db's ATK1 for non BL_PC
|
||||
* status->batk (base attack) will be added in battle_calc_base_damage
|
||||
*/
|
||||
unsigned short status_base_atk_max(struct block_list *bl, const struct status_data* status, int level)
|
||||
{
|
||||
switch (bl->type) {
|
||||
case BL_PET:
|
||||
case BL_MOB:
|
||||
case BL_MER:
|
||||
case BL_ELEM:
|
||||
return status->rhw.atk * 120 / 100;
|
||||
case BL_HOM:
|
||||
return (status_get_homluk(bl) + status_get_homstr(bl) + status_get_homdex(bl)) / 3;
|
||||
default:
|
||||
return status->rhw.atk2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates minimum magic attack
|
||||
*/
|
||||
unsigned short status_base_matk_min(struct block_list *bl, const struct status_data* status, int level)
|
||||
{
|
||||
switch (bl->type) {
|
||||
case BL_PET:
|
||||
case BL_MOB:
|
||||
case BL_MER:
|
||||
case BL_ELEM:
|
||||
return status->int_ + level + status->rhw.matk * 70 / 100;
|
||||
case BL_HOM:
|
||||
return status_get_homint(bl) + level + (status_get_homint(bl) + status_get_homdex(bl)) / 5;
|
||||
case BL_PC:
|
||||
default:
|
||||
return status->int_ + (status->int_ / 2) + (status->dex / 5) + (status->luk / 3) + (level / 4);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates maximum magic attack
|
||||
*/
|
||||
unsigned short status_base_matk_max(struct block_list *bl, const struct status_data* status, int level)
|
||||
{
|
||||
switch (bl->type) {
|
||||
case BL_PET:
|
||||
case BL_MOB:
|
||||
case BL_MER:
|
||||
case BL_ELEM:
|
||||
return status->int_ + level + status->rhw.matk * 130 / 100;
|
||||
case BL_HOM:
|
||||
return status_get_homint(bl) + level + (status_get_homluk(bl) + status_get_homint(bl) + status_get_homdex(bl)) / 3;
|
||||
case BL_PC:
|
||||
default:
|
||||
return status->int_ + (status->int_ / 2) + (status->dex / 5) + (status->luk / 3) + (level / 4);
|
||||
@ -2561,12 +2628,6 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
|
||||
// Flee
|
||||
stat = level + status_get_homagi(bl);
|
||||
status->flee = cap_value(stat, 1, SHRT_MAX);
|
||||
// Atk
|
||||
stat = (status_get_homstr(bl) + status_get_homdex(bl)) / 5;
|
||||
status->rhw.atk = cap_value(stat, 0, SHRT_MAX);
|
||||
// Atk2
|
||||
stat = (status_get_homluk(bl) + status_get_homstr(bl) + status_get_homdex(bl)) / 3;
|
||||
status->rhw.atk2 = cap_value(stat, 0, SHRT_MAX);
|
||||
} else {
|
||||
// Hit
|
||||
stat = status->hit;
|
||||
@ -2594,20 +2655,15 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
|
||||
status->mdef2 = cap_value(stat, 0, SHRT_MAX);
|
||||
}
|
||||
|
||||
// MAtk
|
||||
status->matk_min = status->matk_max = status_base_matk(bl, status, level);
|
||||
// ATK
|
||||
if (bl->type != BL_PC) {
|
||||
status->rhw.atk2 = status_base_atk_max(bl, status, level);
|
||||
status->rhw.atk = status_base_atk_min(bl, status, level);
|
||||
}
|
||||
|
||||
///! TODO: Confirm these RENEWAL calculations. Currently is using previous calculation before 083cf5d9 (issue: #321) and until re/mob_db.txt is updated.
|
||||
//switch (bl->type) {
|
||||
// case BL_MOB:
|
||||
// status->matk_min += 70 * ((TBL_MOB*)bl)->status.rhw.atk2 / 100;
|
||||
// status->matk_max += 130 * ((TBL_MOB*)bl)->status.rhw.atk2 / 100;
|
||||
// break;
|
||||
// case BL_MER:
|
||||
// status->matk_min += 70 * ((TBL_MER*)bl)->battle_status.rhw.atk2 / 100;
|
||||
// status->matk_max += 130 * ((TBL_MER*)bl)->battle_status.rhw.atk2 / 100;
|
||||
// break;
|
||||
//}
|
||||
// MAtk
|
||||
status->matk_min = status_base_matk_min(bl, status, level);
|
||||
status->matk_max = status_base_matk_max(bl, status, level);
|
||||
#else
|
||||
// Matk
|
||||
status->matk_min = status_base_matk_min(status);
|
||||
@ -2646,10 +2702,10 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
|
||||
status->flee2 = 0;
|
||||
|
||||
if (status->batk) {
|
||||
int temp = status->batk + status_base_atk(bl, status);
|
||||
int temp = status->batk + status_base_atk(bl, status, level);
|
||||
status->batk = cap_value(temp, 0, USHRT_MAX);
|
||||
} else
|
||||
status->batk = status_base_atk(bl, status);
|
||||
status->batk = status_base_atk(bl, status, level);
|
||||
|
||||
if (status->cri) {
|
||||
switch (bl->type) {
|
||||
@ -4401,7 +4457,6 @@ int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt
|
||||
status->sp = ele->sp;
|
||||
status->rhw.atk = ele->atk;
|
||||
status->rhw.atk2 = ele->atk2;
|
||||
|
||||
status->matk_min += ele->matk;
|
||||
status->def += ele->def;
|
||||
status->mdef += ele->mdef;
|
||||
@ -4864,8 +4919,9 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
|
||||
}
|
||||
|
||||
if(flag&SCB_BATK && b_status->batk) {
|
||||
status->batk = status_base_atk(bl,status);
|
||||
temp = b_status->batk - status_base_atk(bl,b_status);
|
||||
int lv = status_get_lv(bl);
|
||||
status->batk = status_base_atk(bl, status, lv);
|
||||
temp = b_status->batk - status_base_atk(bl, b_status, lv);
|
||||
if (temp) {
|
||||
temp += status->batk;
|
||||
status->batk = cap_value(temp, 0, USHRT_MAX);
|
||||
@ -5090,7 +5146,9 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
|
||||
* RE MATK Formula (from irowiki:http:// irowiki.org/wiki/MATK)
|
||||
* MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers
|
||||
**/
|
||||
status->matk_min = status->matk_max = status_base_matk(bl, status, status_get_lv(bl));
|
||||
int lv = status_get_lv(bl);
|
||||
status->matk_min = status_base_matk_min(bl, status, lv);
|
||||
status->matk_max = status_base_matk_max(bl, status, lv);
|
||||
|
||||
switch( bl->type ) {
|
||||
case BL_PC: {
|
||||
@ -5140,10 +5198,6 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
|
||||
status->matk_max += wMatk + variance;
|
||||
}
|
||||
break;
|
||||
case BL_HOM:
|
||||
status->matk_min += (status_get_homint(bl) + status_get_homdex(bl)) / 5;
|
||||
status->matk_max += (status_get_homluk(bl) + status_get_homint(bl) + status_get_homdex(bl)) / 3;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -11086,7 +11140,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
int min = 0, max = 0;
|
||||
|
||||
#ifdef RENEWAL
|
||||
min = max = status_base_matk(src, status, status_get_lv(src));
|
||||
min = status_base_matk_min(src, status, status_get_lv(src));
|
||||
max = status_base_matk_max(src, status, status_get_lv(src));
|
||||
if (status->rhw.matk > 0) {
|
||||
int wMatk, variance;
|
||||
|
||||
|
@ -3437,14 +3437,17 @@ int status_check_visibility(struct block_list *src, struct block_list *target);
|
||||
int status_change_spread(struct block_list *src, struct block_list *bl, bool type);
|
||||
|
||||
#ifndef RENEWAL
|
||||
unsigned short status_base_matk_min(const struct status_data* status);
|
||||
unsigned short status_base_matk_max(const struct status_data* status);
|
||||
unsigned short status_base_matk_min(const struct status_data* status);
|
||||
unsigned short status_base_matk_max(const struct status_data* status);
|
||||
#else
|
||||
unsigned int status_weapon_atk(struct weapon_atk wa, struct map_session_data *sd);
|
||||
unsigned short status_base_matk(struct block_list *bl, const struct status_data* status, int level);
|
||||
unsigned int status_weapon_atk(struct weapon_atk wa, struct map_session_data *sd);
|
||||
unsigned short status_base_atk_min(struct block_list *bl, const struct status_data* status, int level);
|
||||
unsigned short status_base_atk_max(struct block_list *bl, const struct status_data* status, int level);
|
||||
unsigned short status_base_matk_min(struct block_list *bl, const struct status_data* status, int level);
|
||||
unsigned short status_base_matk_max(struct block_list *bl, const struct status_data* status, int level);
|
||||
#endif
|
||||
|
||||
unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status);
|
||||
unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status, int level);
|
||||
|
||||
void initChangeTables(void);
|
||||
int status_readdb(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user