-
Notifications
You must be signed in to change notification settings - Fork 762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Multi Critical Damage #2673
base: stable
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4351,8 +4351,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl | |
int i, nk; | ||
bool n_ele = false; // non-elemental | ||
|
||
struct map_session_data *sd, *tsd; | ||
struct Damage wd; | ||
struct map_session_data *sd = BL_CAST(BL_PC, src); | ||
struct map_session_data *tsd = BL_CAST(BL_PC, target); | ||
struct status_change *sc = status->get_sc(src); | ||
struct status_change *tsc = status->get_sc(target); | ||
struct status_data *sstatus = status->get_status_data(src); | ||
|
@@ -4419,9 +4420,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl | |
if (tsc && !tsc->count) | ||
tsc = NULL; //Skip checking as there are no status changes active. | ||
|
||
sd = BL_CAST(BL_PC, src); | ||
tsd = BL_CAST(BL_PC, target); | ||
|
||
if(sd) | ||
wd.blewcount += battle->blewcount_bonus(sd, skill_id); | ||
|
||
|
@@ -4432,7 +4430,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl | |
) | ||
flag.arrow = 1; | ||
|
||
if(skill_id) { | ||
if(skill_id || (skill->get_nk(skill_id) & NK_CRITICAL) == 0) { | ||
wd.flag |= battle->range_type(src, target, skill_id, skill_lv); | ||
switch(skill_id) { | ||
case MO_FINGEROFFENSIVE: | ||
|
@@ -4463,7 +4461,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl | |
|
||
case TF_DOUBLE: //For NPC used skill. | ||
case GS_CHAINACTION: | ||
wd.type = BDT_MULTIHIT; | ||
wd.type = BDT_CRIT | BDT_MULTICRIT; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BDT_* is not a bitmask, is this intended? also this will break pre-re compatibility please add it under #ifdef. |
||
break; | ||
|
||
case GS_GROUNDDRIFT: | ||
|
@@ -4476,7 +4474,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl | |
break; | ||
|
||
case KN_AUTOCOUNTER: | ||
wd.flag=(wd.flag&~BF_SKILLMASK)|BF_NORMAL; | ||
wd.flag = (wd.flag & ~BF_SKILLMASK) | BF_NORMAL; | ||
break; | ||
|
||
case NPC_CRITICALSLASH: | ||
|
@@ -4591,21 +4589,21 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl | |
|
||
if (sd && !skill_id) { | ||
//Check for double attack. | ||
if (( (skill_lv=pc->checkskill(sd,TF_DOUBLE)) > 0 && sd->weapontype1 == W_DAGGER ) | ||
|| ( sd->bonus.double_rate > 0 && sd->weapontype1 != W_FIST ) //Will fail bare-handed | ||
|| ( sc && sc->data[SC_KAGEMUSYA] && sd->weapontype1 != W_FIST ) // Need confirmation | ||
if (sd->bonus.double_rate > 0 | ||
|| (skill_lv = pc->checkskill(sd, TF_DOUBLE)) > 0 | ||
|| (sc != NULL && sc->data[SC_KAGEMUSYA] != NULL) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all of this changes should be put under |
||
) { | ||
//Success chance is not added, the higher one is used [Skotlex] | ||
if( rnd()%100 < ( 5*skill_lv > sd->bonus.double_rate ? 5*skill_lv : sc && sc->data[SC_KAGEMUSYA]?sc->data[SC_KAGEMUSYA]->val1*3:sd->bonus.double_rate ) ) | ||
{ | ||
wd.div_ = skill->get_num(TF_DOUBLE,skill_lv?skill_lv:1); | ||
wd.type = BDT_MULTIHIT; | ||
wd.type = BDT_CRIT | BDT_MULTICRIT; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all of this changes should be put under |
||
} | ||
} | ||
else if( sd->weapontype1 == W_REVOLVER && (skill_lv = pc->checkskill(sd,GS_CHAINACTION)) > 0 && rnd()%100 < 5*skill_lv ) | ||
{ | ||
wd.div_ = skill->get_num(GS_CHAINACTION,skill_lv); | ||
wd.type = BDT_MULTIHIT; | ||
wd.type = BDT_CRIT | BDT_MULTICRIT; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all of this changes should be put under |
||
} | ||
else if(sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW | ||
&& (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->status.inventory[i].amount > 1){ | ||
|
@@ -4639,17 +4637,13 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl | |
if ( wd.div_ > 1 ) { | ||
wd.div_ = min(wd.div_, sd->status.inventory[i].amount); | ||
sc->data[SC_FEARBREEZE]->val4 = wd.div_ - 1; | ||
wd.type = BDT_MULTIHIT; | ||
wd.type = BDT_CRIT | BDT_MULTICRIT; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all of this changes should be put under |
||
} | ||
} | ||
} | ||
|
||
//Check for critical | ||
if( !flag.cri && wd.type != BDT_MULTIHIT && sstatus->cri && | ||
(!skill_id || | ||
skill_id == KN_AUTOCOUNTER || | ||
skill_id == SN_SHARPSHOOTING || skill_id == MA_SHARPSHOOTING || | ||
skill_id == NJ_KIRIKAGE)) | ||
if (sstatus->cri != 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all of this changes should be put under |
||
{ | ||
short cri = sstatus->cri; | ||
if (sd != NULL) { | ||
|
@@ -4709,6 +4703,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl | |
} | ||
if (flag.cri) { | ||
wd.type = BDT_CRIT; | ||
#ifdef RENEWAL | ||
if (battle_config.feature_enable_multi_crit == 1 && (wd.type & BDT_MULTIHIT) != 0) | ||
wd.type = BDT_MULTICRIT; | ||
#endif | ||
#ifndef RENEWAL | ||
flag.idef = flag.idef2 = | ||
#endif | ||
|
@@ -7449,6 +7447,7 @@ static const struct battle_data { | |
{ "hit_max_limit", &battle_config.hit_max, SHRT_MAX, 1, INT_MAX, }, | ||
{ "autoloot_adjust", &battle_config.autoloot_adjust, 0, 0, 1, }, | ||
{ "hom_bonus_exp_from_master", &battle_config.hom_bonus_exp_from_master, 10, 0, 100, }, | ||
{ "features/enable_multi_critical", &battle_config.feature_enable_multi_crit, 1, 0, 1, }, | ||
}; | ||
|
||
static bool battle_set_value_sub(int index, int value) | ||
|
@@ -7586,6 +7585,13 @@ static void battle_adjust_conf(void) | |
} | ||
#endif | ||
|
||
#if PACKETVER < 20161207 | ||
if (battle_config.feature_enable_multi_crit) { | ||
ShowWarning("conf/map/battle/feature.conf feature_enable_multi_crit is enabled but it requires PACKETVER 2016-12-07 or newer, disabling...\n"); | ||
battle_config.feature_enable_multi_crit = 0; | ||
} | ||
#endif | ||
|
||
#ifndef CELL_NOSTACK | ||
if (battle_config.custom_cell_stack_limit != 1) | ||
ShowWarning("Battle setting 'custom_cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n"); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4872,7 +4872,8 @@ static int clif_damage(struct block_list *src, struct block_list *dst, int sdela | |
damage2 = (int)min(in_damage2,INT_MAX); | ||
#endif | ||
|
||
type = clif_calc_delay(type,div,damage+damage2,ddelay); | ||
if (type != BDT_MULTICRIT) | ||
type = clif_calc_delay(type, div, damage + damage2, ddelay); | ||
|
||
p.PacketType = damageType; | ||
p.GID = src->id; | ||
|
@@ -4917,8 +4918,10 @@ static int clif_damage(struct block_list *src, struct block_list *dst, int sdela | |
unit->set_dir(src, unit->getdir(src)); | ||
} | ||
|
||
// In case this assignment is bypassed by BDT_MULTICRIT | ||
type = clif_calc_delay(type, div, damage + damage2, ddelay); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is designed to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's design to call twice |
||
//Return adjusted can't walk delay for further processing. | ||
return clif->calc_walkdelay(dst,ddelay,type,damage+damage2,div); | ||
return clif->calc_walkdelay(dst, ddelay, type, damage + damage2, div); | ||
} | ||
|
||
/*========================================== | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3366,7 +3366,10 @@ static int skill_attack(int attack_type, struct block_list *src, struct block_li | |
case NPC_CRITICALSLASH: | ||
case TF_DOUBLE: | ||
case GS_CHAINACTION: | ||
dmg.dmotion = clif->damage(src,bl,dmg.amotion,dmg.dmotion,damage,dmg.div_,dmg.type,dmg.damage2); | ||
case SN_SHARPSHOOTING: | ||
case MA_SHARPSHOOTING: | ||
case NJ_KIRIKAGE: | ||
dmg.dmotion = clif->damage(src, bl, dmg.amotion, dmg.dmotion, damage, dmg.div_, dmg.type, dmg.damage2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all of this changes should be put under |
||
break; | ||
|
||
case AS_SPLASHER: | ||
|
@@ -20602,6 +20605,23 @@ static void skill_validate_id(struct config_setting_t *conf, struct s_skill_db * | |
nullpo_retv(conf); | ||
nullpo_retv(sk); | ||
|
||
if (libconfig->setting_lookup_string(conf, "Hit", &type)) { | ||
if (strcmpi(type, "BDT_SKILL") == 0) { | ||
sk->hit = BDT_SKILL; | ||
} else if (strcmpi(type, "BDT_MULTIHIT") == 0) { | ||
sk->hit = BDT_MULTIHIT; | ||
} else if (strcmpi(type, "BDT_NORMAL") == 0) { | ||
sk->hit = BDT_NORMAL; | ||
} else if (strcmpi(type, "BDT_MULTICRIT") == 0) { | ||
sk->hit = BDT_MULTICRIT; | ||
} else if (strcmpi(type, "BDT_CRIT") == 0) { | ||
sk->hit = BDT_CRIT; | ||
} else { | ||
skilldb_invalid_error(type, "Hit", sk->nameid); | ||
return; | ||
} | ||
} | ||
|
||
sk->nameid = 0; | ||
|
||
int id; | ||
|
@@ -21202,6 +21222,13 @@ static void skill_validate_damagetype(struct config_setting_t *conf, struct s_sk | |
sk->nk |= NK_NO_CARDFIX_DEF; | ||
else | ||
sk->nk &= ~NK_NO_CARDFIX_DEF; | ||
} | ||
} else if (strcmpi(type, "CritDamage") == 0) { | ||
if (on != 0) { | ||
sk->nk |= NK_CRITICAL; | ||
} else { | ||
sk->nk &= ~NK_CRITICAL; | ||
} | ||
} else { | ||
ShowWarning("%s: Invalid damage type %s specified for skill ID %d in %s! Skipping damage type...\n", | ||
__func__, damage_type, sk->nameid, conf->file); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please set this to false otherwise the CI that checks different client types would fail