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:
Cydh Ramdh 2018-10-13 19:00:14 +07:00 committed by GitHub
parent 8e7b9a57c0
commit fe197bfa12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 2446 additions and 2381 deletions

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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, },

View File

@ -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;

View File

@ -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]);

View File

@ -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]);

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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);