Improved bonus-adding processes by no longer having to add it to the zero'd memset bullshit, replaced it by moving the first set of bonus into its own struct and simply zeroing the struct prior to recalc.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16272 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
shennetsind 2012-06-12 01:08:05 +00:00
parent 7332a89352
commit e2fd3350e5
7 changed files with 224 additions and 295 deletions

View File

@ -792,8 +792,8 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
short element = skill_get_ele(skill_num, skill_lv);
if( !skill_num || element == -1 ) { //Take weapon's element
struct status_data *sstatus = NULL;
if( src->type == BL_PC && ((TBL_PC*)src)->arrow_ele )
element = ((TBL_PC*)src)->arrow_ele;
if( src->type == BL_PC && ((TBL_PC*)src)->bonus.arrow_ele )
element = ((TBL_PC*)src)->bonus.arrow_ele;
else if( (sstatus = status_get_status_data(src)) ) {
element = sstatus->rhw.ele;
}
@ -1109,8 +1109,8 @@ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk
if (sd)
{
//rodatazone says the range is 0~arrow_atk-1 for non crit
if (flag&2 && sd->arrow_atk)
damage += ((flag&1)?sd->arrow_atk:rnd()%sd->arrow_atk);
if (flag&2 && sd->bonus.arrow_atk)
damage += ( (flag&1) ? sd->bonus.arrow_atk : rnd()%sd->bonus.arrow_atk );
//SizeFix only for players
if (!(sd->special_state.no_sizefix || (flag&8)))
@ -1351,8 +1351,8 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
{ //Take weapon's element
s_ele = sstatus->rhw.ele;
s_ele_ = sstatus->lhw.ele;
if( flag.arrow && sd && sd->arrow_ele )
s_ele = sd->arrow_ele;
if( flag.arrow && sd && sd->bonus.arrow_ele )
s_ele = sd->bonus.arrow_ele;
if( battle_config.attack_attr_none&src->type )
n_ele = true; //Weapon's element is "not elemental"
}
@ -1383,9 +1383,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if( sd && !skill_num ) { //Check for double attack.
if( ( ( skill_lv = pc_checkskill(sd,TF_DOUBLE) ) > 0 && sd->weapontype1 == W_DAGGER )
|| ( sd->double_rate > 0 && sd->weapontype1 != W_FIST ) ) //Will fail bare-handed
|| ( sd->bonus.double_rate > 0 && sd->weapontype1 != W_FIST ) ) //Will fail bare-handed
{ //Success chance is not added, the higher one is used [Skotlex]
if( rnd()%100 < ( 5*skill_lv > sd->double_rate ? 5*skill_lv : sd->double_rate ) )
if( rnd()%100 < ( 5*skill_lv > sd->bonus.double_rate ? 5*skill_lv : sd->bonus.double_rate ) )
{
wd.div_ = skill_get_num(TF_DOUBLE,skill_lv?skill_lv:1);
wd.type = 0x08;
@ -1424,19 +1424,16 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
{
cri+= sd->critaddrace[tstatus->race];
if(flag.arrow)
cri += sd->arrow_cri;
cri += sd->bonus.arrow_cri;
}
//The official equation is *2, but that only applies when sd's do critical.
//Therefore, we use the old value 3 on cases when an sd gets attacked by a mob
cri -= tstatus->luk*(!sd&&tsd?3:2);
if(tsc)
{
if (tsc->data[SC_SLEEP])
if( tsc && tsc->data[SC_SLEEP] ) {
cri <<= 1;
}
switch (skill_num)
{
switch (skill_num) {
case KN_AUTOCOUNTER:
if(battle_config.auto_counter_type &&
(battle_config.auto_counter_type&src->type))
@ -1452,8 +1449,8 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
cri += 250 + 50*skill_lv;
break;
}
if(tsd && tsd->critical_def)
cri = cri*(100-tsd->critical_def)/100;
if(tsd && tsd->bonus.critical_def)
cri = cri * ( 100 - tsd->bonus.critical_def ) / 100;
if (rnd()%1000 < cri)
flag.cri = 1;
}
@ -1462,7 +1459,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
wd.type = 0x0a;
flag.idef = flag.idef2 = flag.hit = 1;
} else { //Check for Perfect Hit
if(sd && sd->perfect_hit > 0 && rnd()%100 < sd->perfect_hit)
if(sd && sd->bonus.perfect_hit > 0 && rnd()%100 < sd->bonus.perfect_hit)
flag.hit = 1;
if (sc && sc->data[SC_FUSION]) {
flag.hit = 1; //SG_FUSION always hit [Komurka]
@ -1513,7 +1510,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
hitrate -= 50;
if(sd && flag.arrow)
hitrate += sd->arrow_hit;
hitrate += sd->bonus.arrow_hit;
if(skill_num)
switch(skill_num)
{ //Hit skill modifiers
@ -1681,13 +1678,12 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
}
//Add any bonuses that modify the base baseatk+watk (pre-skills)
if(sd)
{
if (sd->atk_rate)
ATK_ADDRATE(sd->atk_rate);
if(sd) {
if (sd->bonus.atk_rate)
ATK_ADDRATE(sd->bonus.atk_rate);
if(flag.cri && sd->crit_atk_rate)
ATK_ADDRATE(sd->crit_atk_rate);
if(flag.cri && sd->bonus.crit_atk_rate)
ATK_ADDRATE(sd->bonus.crit_atk_rate);
if(sd->status.party_id && (skill=pc_checkskill(sd,TK_POWER)) > 0){
if( (i = party_foreachsamemap(party_sub_count, sd, 0)) > 1 ) // exclude the player himself [Inkfish]
@ -2872,7 +2868,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
}
if( wd.flag&BF_LONG )
cardfix=cardfix*(100+sd->long_attack_atk_rate)/100;
cardfix = cardfix * ( 100 + sd->bonus.long_attack_atk_rate ) / 100;
if( cardfix != 1000 || cardfix_ != 1000 )
ATK_RATE2(cardfix/10, cardfix_/10); //What happens if you use right-to-left and there's no right weapon, only left?
@ -2930,19 +2926,17 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if( sstatus->race != RC_DEMIHUMAN )
cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ )
{
if( tsd->add_def[i].class_ == s_class )
{
for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ ) {
if( tsd->add_def[i].class_ == s_class ) {
cardfix=cardfix*(100-tsd->add_def[i].rate)/100;
break;
}
}
if( wd.flag&BF_SHORT )
cardfix=cardfix*(100-tsd->near_attack_def_rate)/100;
cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
else // BF_LONG (there's no other choice)
cardfix=cardfix*(100-tsd->long_attack_def_rate)/100;
cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
if( tsd->sc.data[SC_DEF_RATE] )
cardfix = cardfix * ( 100 - tsd->sc.data[SC_DEF_RATE]->val1 ) / 100;
@ -3495,7 +3489,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
break;
case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield MDEF x 100) + (Casters INT x 2)] %
if( sd ) {
skillratio = status_get_lv(src) * 4 + sd->shieldmdef * 100 + status_get_int(src) * 2;
skillratio = status_get_lv(src) * 4 + sd->bonus.shieldmdef * 100 + status_get_int(src) * 2;
} else
skillratio += 1900; //2000%
break;
@ -3627,9 +3621,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
//Ignore Defense?
if (!flag.imdef && (
sd->ignore_mdef_ele & (1<<tstatus->def_ele) ||
sd->ignore_mdef_race & (1<<tstatus->race) ||
sd->ignore_mdef_race & (is_boss(target)?1<<RC_BOSS:1<<RC_NONBOSS)
sd->bonus.ignore_mdef_ele & ( 1 << tstatus->def_ele ) ||
sd->bonus.ignore_mdef_race & ( 1 << tstatus->race ) ||
sd->bonus.ignore_mdef_race & ( is_boss(target) ? 1 << RC_BOSS : 1 << RC_NONBOSS )
))
flag.imdef = 1;
}
@ -3745,11 +3739,11 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
//It was discovered that ranged defense also counts vs magic! [Skotlex]
if ( ad.flag&BF_SHORT )
cardfix=cardfix*(100-tsd->near_attack_def_rate)/100;
cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
else
cardfix=cardfix*(100-tsd->long_attack_def_rate)/100;
cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
cardfix=cardfix*(100-tsd->magic_def_rate)/100;
cardfix = cardfix * ( 100 - tsd->bonus.magic_def_rate ) / 100;
if( tsd->sc.data[SC_MDEF_RATE] )
cardfix = cardfix * ( 100 - tsd->sc.data[SC_MDEF_RATE]->val1 ) / 100;
@ -4044,11 +4038,11 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
if( sstatus->race != RC_DEMIHUMAN )
cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
cardfix=cardfix*(100-tsd->misc_def_rate)/100;
cardfix = cardfix * ( 100 - tsd->bonus.misc_def_rate ) / 100;
if( md.flag&BF_SHORT )
cardfix=cardfix*(100-tsd->near_attack_def_rate)/100;
cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
else // BF_LONG (there's no other choice)
cardfix=cardfix*(100-tsd->long_attack_def_rate)/100;
cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
if (cardfix != 10000)
md.damage= (int)( (int64)md.damage * cardfix / 10000 );
@ -4133,8 +4127,8 @@ int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int
rdamage = (*dmg) * sc->data[SC_REFLECTDAMAGE]->val2 / 100;
if( rdamage > max_damage ) rdamage = max_damage;
} else if (flag & BF_SHORT) {//Bounces back part of the damage.
if (sd && sd->short_weapon_damage_return){
rdamage += damage * sd->short_weapon_damage_return / 100;
if ( sd && sd->bonus.short_weapon_damage_return ) {
rdamage += damage * sd->bonus.short_weapon_damage_return / 100;
if(rdamage < 1) rdamage = 1;
}
if( sc && sc->count ) {
@ -4162,8 +4156,8 @@ int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int
}
}
} else {
if (sd && sd->long_weapon_damage_return) {
rdamage += damage * sd->long_weapon_damage_return / 100;
if (sd && sd->bonus.long_weapon_damage_return) {
rdamage += damage * sd->bonus.long_weapon_damage_return / 100;
if (rdamage < 1) rdamage = 1;
}
}
@ -4205,8 +4199,8 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int rdamage, int ldamage,
}
}
if (sd->sp_vanish_rate && rnd()%1000 < sd->sp_vanish_rate)
status_percent_damage(&sd->bl, tbl, 0, (unsigned char)sd->sp_vanish_per, false);
if (sd->bonus.sp_vanish_rate && rnd()%1000 < sd->bonus.sp_vanish_rate)
status_percent_damage(&sd->bl, tbl, 0, (unsigned char)sd->bonus.sp_vanish_per, false);
if( sd->sp_gain_race_attack[race] )
tsp += sd->sp_gain_race_attack[race];
@ -4464,7 +4458,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
wd.dmotion = clif_damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2);
if (sd && sd->splash_range > 0 && damage > 0)
if (sd && sd->bonus.splash_range > 0 && damage > 0)
skill_castend_damage_id(src, target, 0, 1, tick, 0);
map_freeblock_lock();

View File

@ -2427,9 +2427,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
}
// process script-granted zeny bonus (get_zeny_num) [Skotlex]
if(sd->get_zeny_num && rnd()%100 < sd->get_zeny_rate)
{
i = sd->get_zeny_num > 0?sd->get_zeny_num:-md->level*sd->get_zeny_num;
if( sd->bonus.get_zeny_num && rnd()%100 < sd->bonus.get_zeny_rate ) {
i = sd->bonus.get_zeny_num > 0 ? sd->bonus.get_zeny_num : -md->level * sd->bonus.get_zeny_num;
if (!i) i = 1;
pc_getzeny(sd, 1+rnd()%i);
}

View File

@ -2072,7 +2072,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
status->mdef = cap_value(bonus, CHAR_MIN, CHAR_MAX);
#endif
if( sd->state.lr_flag == 3 ) {//Shield, used for royal guard
sd->shieldmdef += bonus;
sd->bonus.shieldmdef += bonus;
}
}
break;
@ -2087,7 +2087,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
bonus = status->hit + val;
status->hit = cap_value(bonus, SHRT_MIN, SHRT_MAX);
} else
sd->arrow_hit+=val;
sd->bonus.arrow_hit+=val;
break;
case SP_FLEE1:
if(sd->state.lr_flag != 2) {
@ -2106,7 +2106,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
bonus = status->cri + val*10;
status->cri = cap_value(bonus, SHRT_MIN, SHRT_MAX);
} else
sd->arrow_cri += val*10;
sd->bonus.arrow_cri += val*10;
break;
case SP_ATKELE:
if(val >= ELE_MAX) {
@ -2127,7 +2127,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
status->rhw.ele=val;
break;
default: //Become arrow element.
sd->arrow_ele=val;
sd->bonus.arrow_ele=val;
break;
}
break;
@ -2200,15 +2200,15 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
case SP_SPEED_RATE: //Non stackable increase
if(sd->state.lr_flag != 2)
sd->speed_rate = min(sd->speed_rate, -val);
sd->bonus.speed_rate = min(sd->bonus.speed_rate, -val);
break;
case SP_SPEED_ADDRATE: //Stackable increase
if(sd->state.lr_flag != 2)
sd->speed_add_rate -= val;
sd->bonus.speed_add_rate -= val;
break;
case SP_ASPD: //Raw increase
if(sd->state.lr_flag != 2)
sd->aspd_add -= 10*val;
sd->bonus.aspd_add -= 10*val;
break;
case SP_ASPD_RATE: //Stackable increase - Made it linear as per rodatazone
if(sd->state.lr_flag != 2)
@ -2224,23 +2224,23 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
case SP_CRITICAL_DEF:
if(sd->state.lr_flag != 2)
sd->critical_def += val;
sd->bonus.critical_def += val;
break;
case SP_NEAR_ATK_DEF:
if(sd->state.lr_flag != 2)
sd->near_attack_def_rate += val;
sd->bonus.near_attack_def_rate += val;
break;
case SP_LONG_ATK_DEF:
if(sd->state.lr_flag != 2)
sd->long_attack_def_rate += val;
sd->bonus.long_attack_def_rate += val;
break;
case SP_DOUBLE_RATE:
if(sd->state.lr_flag == 0 && sd->double_rate < val)
sd->double_rate = val;
if(sd->state.lr_flag == 0 && sd->bonus.double_rate < val)
sd->bonus.double_rate = val;
break;
case SP_DOUBLE_ADD_RATE:
if(sd->state.lr_flag == 0)
sd->double_add_rate += val;
sd->bonus.double_add_rate += val;
break;
case SP_MATK_RATE:
if(sd->state.lr_flag != 2)
@ -2264,15 +2264,15 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
case SP_ATK_RATE:
if(sd->state.lr_flag != 2)
sd->atk_rate += val;
sd->bonus.atk_rate += val;
break;
case SP_MAGIC_ATK_DEF:
if(sd->state.lr_flag != 2)
sd->magic_def_rate += val;
sd->bonus.magic_def_rate += val;
break;
case SP_MISC_ATK_DEF:
if(sd->state.lr_flag != 2)
sd->misc_def_rate += val;
sd->bonus.misc_def_rate += val;
break;
case SP_IGNORE_MDEF_RATE:
if(sd->state.lr_flag != 2) {
@ -2286,19 +2286,19 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
}
if(sd->state.lr_flag != 2)
sd->ignore_mdef_ele |= 1<<val;
sd->bonus.ignore_mdef_ele |= 1<<val;
break;
case SP_IGNORE_MDEF_RACE:
if(sd->state.lr_flag != 2)
sd->ignore_mdef_race |= 1<<val;
sd->bonus.ignore_mdef_race |= 1<<val;
break;
case SP_PERFECT_HIT_RATE:
if(sd->state.lr_flag != 2 && sd->perfect_hit < val)
sd->perfect_hit = val;
if(sd->state.lr_flag != 2 && sd->bonus.perfect_hit < val)
sd->bonus.perfect_hit = val;
break;
case SP_PERFECT_HIT_ADD_RATE:
if(sd->state.lr_flag != 2)
sd->perfect_hit_add += val;
sd->bonus.perfect_hit_add += val;
break;
case SP_CRITICAL_RATE:
if(sd->state.lr_flag != 2)
@ -2401,23 +2401,23 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
sd->special_state.no_knockback = 1;
break;
case SP_SPLASH_RANGE:
if(sd->splash_range < val)
sd->splash_range = val;
if(sd->bonus.splash_range < val)
sd->bonus.splash_range = val;
break;
case SP_SPLASH_ADD_RANGE:
sd->splash_add_range += val;
sd->bonus.splash_add_range += val;
break;
case SP_SHORT_WEAPON_DAMAGE_RETURN:
if(sd->state.lr_flag != 2)
sd->short_weapon_damage_return += val;
sd->bonus.short_weapon_damage_return += val;
break;
case SP_LONG_WEAPON_DAMAGE_RETURN:
if(sd->state.lr_flag != 2)
sd->long_weapon_damage_return += val;
sd->bonus.long_weapon_damage_return += val;
break;
case SP_MAGIC_DAMAGE_RETURN: //AppleGirl Was Here
if(sd->state.lr_flag != 2)
sd->magic_damage_return += val;
sd->bonus.magic_damage_return += val;
break;
case SP_ALL_STATS: // [Valaris]
if(sd->state.lr_flag!=2) {
@ -2448,51 +2448,51 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
case SP_UNBREAKABLE:
if(sd->state.lr_flag!=2)
sd->unbreakable += val;
sd->bonus.unbreakable += val;
break;
case SP_UNBREAKABLE_WEAPON:
if(sd->state.lr_flag != 2)
sd->unbreakable_equip |= EQP_WEAPON;
sd->bonus.unbreakable_equip |= EQP_WEAPON;
break;
case SP_UNBREAKABLE_ARMOR:
if(sd->state.lr_flag != 2)
sd->unbreakable_equip |= EQP_ARMOR;
sd->bonus.unbreakable_equip |= EQP_ARMOR;
break;
case SP_UNBREAKABLE_HELM:
if(sd->state.lr_flag != 2)
sd->unbreakable_equip |= EQP_HELM;
sd->bonus.unbreakable_equip |= EQP_HELM;
break;
case SP_UNBREAKABLE_SHIELD:
if(sd->state.lr_flag != 2)
sd->unbreakable_equip |= EQP_SHIELD;
sd->bonus.unbreakable_equip |= EQP_SHIELD;
break;
case SP_UNBREAKABLE_GARMENT:
if(sd->state.lr_flag != 2)
sd->unbreakable_equip |= EQP_GARMENT;
sd->bonus.unbreakable_equip |= EQP_GARMENT;
break;
case SP_UNBREAKABLE_SHOES:
if(sd->state.lr_flag != 2)
sd->unbreakable_equip |= EQP_SHOES;
sd->bonus.unbreakable_equip |= EQP_SHOES;
break;
case SP_CLASSCHANGE: // [Valaris]
if(sd->state.lr_flag !=2)
sd->classchange=val;
sd->bonus.classchange=val;
break;
case SP_LONG_ATK_RATE:
if(sd->state.lr_flag != 2) //[Lupus] it should stack, too. As any other cards rate bonuses
sd->long_attack_atk_rate+=val;
sd->bonus.long_attack_atk_rate+=val;
break;
case SP_BREAK_WEAPON_RATE:
if(sd->state.lr_flag != 2)
sd->break_weapon_rate+=val;
sd->bonus.break_weapon_rate+=val;
break;
case SP_BREAK_ARMOR_RATE:
if(sd->state.lr_flag != 2)
sd->break_armor_rate+=val;
sd->bonus.break_armor_rate+=val;
break;
case SP_ADD_STEAL_RATE:
if(sd->state.lr_flag != 2)
sd->add_steal_rate+=val;
sd->bonus.add_steal_rate+=val;
break;
case SP_DELAYRATE:
if(sd->state.lr_flag != 2)
@ -2500,7 +2500,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
case SP_CRIT_ATK_RATE:
if(sd->state.lr_flag != 2)
sd->crit_atk_rate += val;
sd->bonus.crit_atk_rate += val;
break;
case SP_NO_REGEN:
if(sd->state.lr_flag != 2)
@ -2508,20 +2508,20 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
case SP_UNSTRIPABLE_WEAPON:
if(sd->state.lr_flag != 2)
sd->unstripable_equip |= EQP_WEAPON;
sd->bonus.unstripable_equip |= EQP_WEAPON;
break;
case SP_UNSTRIPABLE:
case SP_UNSTRIPABLE_ARMOR:
if(sd->state.lr_flag != 2)
sd->unstripable_equip |= EQP_ARMOR;
sd->bonus.unstripable_equip |= EQP_ARMOR;
break;
case SP_UNSTRIPABLE_HELM:
if(sd->state.lr_flag != 2)
sd->unstripable_equip |= EQP_HELM;
sd->bonus.unstripable_equip |= EQP_HELM;
break;
case SP_UNSTRIPABLE_SHIELD:
if(sd->state.lr_flag != 2)
sd->unstripable_equip |= EQP_SHIELD;
sd->bonus.unstripable_equip |= EQP_SHIELD;
break;
case SP_HP_DRAIN_VALUE:
if(!sd->state.lr_flag) {
@ -2545,39 +2545,39 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
case SP_SP_GAIN_VALUE:
if(!sd->state.lr_flag)
sd->sp_gain_value += val;
sd->bonus.sp_gain_value += val;
break;
case SP_HP_GAIN_VALUE:
if(!sd->state.lr_flag)
sd->hp_gain_value += val;
sd->bonus.hp_gain_value += val;
break;
case SP_MAGIC_SP_GAIN_VALUE:
if(!sd->state.lr_flag)
sd->magic_sp_gain_value += val;
sd->bonus.magic_sp_gain_value += val;
break;
case SP_MAGIC_HP_GAIN_VALUE:
if(!sd->state.lr_flag)
sd->magic_hp_gain_value += val;
sd->bonus.magic_hp_gain_value += val;
break;
case SP_ADD_HEAL_RATE:
if(sd->state.lr_flag != 2)
sd->add_heal_rate += val;
sd->bonus.add_heal_rate += val;
break;
case SP_ADD_HEAL2_RATE:
if(sd->state.lr_flag != 2)
sd->add_heal2_rate += val;
sd->bonus.add_heal2_rate += val;
break;
case SP_ADD_ITEM_HEAL_RATE:
if(sd->state.lr_flag != 2)
sd->itemhealrate2 += val;
sd->bonus.itemhealrate2 += val;
break;
case SP_WEAPON_MATK:
if(sd->state.lr_flag != 2)
sd->sp_weapon_matk += val;
sd->bonus.sp_weapon_matk += val;
break;
case SP_BASE_MATK:
if(sd->state.lr_flag != 2)
sd->sp_base_matk += val;
sd->bonus.sp_base_matk += val;
break;
default:
ShowWarning("pc_bonus: unknown type %d %d !\n",type,val);
@ -2806,22 +2806,20 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
case SP_SP_VANISH_RATE:
if(sd->state.lr_flag != 2) {
sd->sp_vanish_rate += type2;
sd->sp_vanish_per += val;
sd->bonus.sp_vanish_rate += type2;
sd->bonus.sp_vanish_per += val;
}
break;
case SP_GET_ZENY_NUM:
if(sd->state.lr_flag != 2 && sd->get_zeny_rate < val)
{
sd->get_zeny_rate = val;
sd->get_zeny_num = type2;
if(sd->state.lr_flag != 2 && sd->bonus.get_zeny_rate < val) {
sd->bonus.get_zeny_rate = val;
sd->bonus.get_zeny_num = type2;
}
break;
case SP_ADD_GET_ZENY_NUM:
if(sd->state.lr_flag != 2)
{
sd->get_zeny_rate += val;
sd->get_zeny_num += type2;
if(sd->state.lr_flag != 2) {
sd->bonus.get_zeny_rate += val;
sd->bonus.get_zeny_num += type2;
}
break;
case SP_WEAPON_COMA_ELE:
@ -4301,7 +4299,7 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, int lv)
// base skill success chance (percentual)
rate = (sd_status->dex - md_status->dex)/2 + lv*6 + 4;
rate += sd->add_steal_rate;
rate += sd->bonus.add_steal_rate;
if( rate < 1 )
return 0;
@ -6085,14 +6083,11 @@ int pc_skillatk_bonus(struct map_session_data *sd, int skill_num)
return bonus;
}
int pc_skillheal_bonus(struct map_session_data *sd, int skill_num)
{
int i, bonus = sd->add_heal_rate;
int pc_skillheal_bonus(struct map_session_data *sd, int skill_num) {
int i, bonus = sd->bonus.add_heal_rate;
if( bonus )
{
switch( skill_num )
{
if( bonus ) {
switch( skill_num ) {
case AL_HEAL: if( !(battle_config.skill_add_heal_rate&1) ) bonus = 0; break;
case PR_SANCTUARY: if( !(battle_config.skill_add_heal_rate&2) ) bonus = 0; break;
case AM_POTIONPITCHER: if( !(battle_config.skill_add_heal_rate&4) ) bonus = 0; break;
@ -6102,17 +6097,20 @@ int pc_skillheal_bonus(struct map_session_data *sd, int skill_num)
}
ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == skill_num);
if( i < ARRAYLENGTH(sd->skillheal) ) bonus += sd->skillheal[i].val;
if( i < ARRAYLENGTH(sd->skillheal) )
bonus += sd->skillheal[i].val;
return bonus;
}
int pc_skillheal2_bonus(struct map_session_data *sd, int skill_num)
{
int i, bonus = sd->add_heal2_rate;
int pc_skillheal2_bonus(struct map_session_data *sd, int skill_num) {
int i, bonus = sd->bonus.add_heal2_rate;
ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == skill_num);
if( i < ARRAYLENGTH(sd->skillheal2) ) bonus += sd->skillheal2[i].val;
if( i < ARRAYLENGTH(sd->skillheal2) )
bonus += sd->skillheal2[i].val;
return bonus;
}
@ -6725,7 +6723,7 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
if (potion_flag > 1)
bonus += bonus*(potion_flag-1)*50/100;
//All item bonuses.
bonus += sd->itemhealrate2;
bonus += sd->bonus.itemhealrate2;
//Item Group bonuses
bonus += bonus*itemdb_group_bonus(sd, itemid)/100;
//Individual item bonuses.

View File

@ -284,6 +284,7 @@ struct map_session_data {
struct s_autobonus autobonus[MAX_PC_BONUS], autobonus2[MAX_PC_BONUS], autobonus3[MAX_PC_BONUS]; //Auto script on attack, when attacked, on skill usage
// manually zeroed structures end here.
// zeroed vars start here.
struct {
int atk_rate;
int arrow_atk,arrow_ele,arrow_cri,arrow_hit;
int nsshealhp,nsshealsp;
@ -317,6 +318,7 @@ struct map_session_data {
unsigned short unbreakable; // chance to prevent ANY equipment breaking [celest]
unsigned short unbreakable_equip; //100% break resistance on certain equipment
unsigned short unstripable_equip;
} bonus;
// zeroed vars end here.

View File

@ -12611,16 +12611,14 @@ BUILDIN_FUNC(isequipped)
return 0;
}
setitem_hash = sd->setitem_hash;
setitem_hash2 = sd->setitem_hash2;
for (i=0; id!=0; i++)
{
setitem_hash = sd->bonus.setitem_hash;
setitem_hash2 = sd->bonus.setitem_hash2;
for (i=0; id!=0; i++) {
FETCH (i+2, id) else id = 0;
if (id <= 0)
continue;
flag = 0;
for (j=0; j<EQI_MAX; j++)
{
for (j=0; j<EQI_MAX; j++) {
index = sd->equip_index[j];
if(index < 0) continue;
if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue;
@ -12648,16 +12646,16 @@ BUILDIN_FUNC(isequipped)
hash = 1<<((j<5?j:j-5)*4 + k);
// check if card is already used by another set
if ((j<5?sd->setitem_hash:sd->setitem_hash2) & hash)
if ( ( j < 5 ? sd->bonus.setitem_hash : sd->bonus.setitem_hash2 ) & hash)
continue;
// We have found a match
flag = 1;
// Set hash so this card cannot be used by another
if (j<5)
sd->setitem_hash |= hash;
sd->bonus.setitem_hash |= hash;
else
sd->setitem_hash2 |= hash;
sd->bonus.setitem_hash2 |= hash;
break;
}
}
@ -12669,10 +12667,9 @@ BUILDIN_FUNC(isequipped)
ret &= flag;
if (!ret) break;
}
if (!ret)
{ //When check fails, restore original hash values. [Skotlex]
sd->setitem_hash = setitem_hash;
sd->setitem_hash2 = setitem_hash2;
if (!ret) {//When check fails, restore original hash values. [Skotlex]
sd->bonus.setitem_hash = setitem_hash;
sd->bonus.setitem_hash2 = setitem_hash2;
}
script_pushint(st,ret);
return 0;

View File

@ -1391,7 +1391,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
// Target weapon breaking
rate = 0;
if( sd )
rate += sd->break_weapon_rate;
rate += sd->bonus.break_weapon_rate;
if( sc && sc->data[SC_MELTDOWN] )
rate += sc->data[SC_MELTDOWN]->val2;
if( rate )
@ -1400,7 +1400,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
// Target armor breaking
rate = 0;
if( sd )
rate += sd->break_armor_rate;
rate += sd->bonus.break_armor_rate;
if( sc && sc->data[SC_MELTDOWN] )
rate += sc->data[SC_MELTDOWN]->val3;
if( rate )
@ -1522,9 +1522,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
}
//Polymorph
if(sd && sd->classchange && attack_type&BF_WEAPON &&
if(sd && sd->bonus.classchange && attack_type&BF_WEAPON &&
dstmd && !(tstatus->mode&MD_BOSS) &&
(rnd()%10000 < sd->classchange))
(rnd()%10000 < sd->bonus.classchange))
{
struct mob_db *mob;
int class_;
@ -1726,19 +1726,17 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
status_heal(src, 0, status_get_lv(bl)*(95+15*rate)/100, 2);
}
if( sd && status_isdead(bl) )
{
if( sd && status_isdead(bl) ) {
int sp = 0, hp = 0;
if( attack_type&BF_WEAPON )
{
sp += sd->sp_gain_value;
if( attack_type&BF_WEAPON ) {
sp += sd->bonus.sp_gain_value;
sp += sd->sp_gain_race[status_get_race(bl)];
sp += sd->sp_gain_race[is_boss(bl)?RC_BOSS:RC_NONBOSS];
hp += sd->hp_gain_value;
hp += sd->bonus.hp_gain_value;
}
if( attack_type&BF_MAGIC ) {
sp += sd->magic_sp_gain_value;
hp += sd->magic_hp_gain_value;
sp += sd->bonus.magic_sp_gain_value;
hp += sd->bonus.magic_hp_gain_value;
if( skillid == WZ_WATERBALL ) {//(bugreport:5303)
struct status_change *sc = NULL;
if( ( sc = status_get_sc(src) ) ) {
@ -1749,8 +1747,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
}
}
}
if( hp || sp )
{// updated to force healing to allow healing through berserk
if( hp || sp ) { // updated to force healing to allow healing through berserk
status_heal(src, hp, sp, battle_config.show_hp_sp_gain ? 3 : 1);
}
}
@ -1887,10 +1884,10 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in
sc = NULL;
if (sd) {
if (sd->unbreakable_equip)
where &= ~sd->unbreakable_equip;
if (sd->unbreakable)
rate -= rate*sd->unbreakable/100;
if (sd->bonus.unbreakable_equip)
where &= ~sd->bonus.unbreakable_equip;
if (sd->bonus.unbreakable)
rate -= rate*sd->bonus.unbreakable/100;
if (where&EQP_WEAPON) {
switch (sd->status.weapon) {
case W_FIST: //Bare fists should not break :P
@ -2059,7 +2056,7 @@ static int skill_magic_reflect(struct block_list* src, struct block_list* bl, in
struct map_session_data* sd = BL_CAST(BL_PC, bl);
// item-based reflection
if( sd && sd->magic_damage_return && type && rnd()%100 < sd->magic_damage_return )
if( sd && sd->bonus.magic_damage_return && type && rnd()%100 < sd->bonus.magic_damage_return )
return 1;
if( is_boss(src) )
@ -4484,7 +4481,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
} else {
skill_area_temp[1] = bl->id;
map_foreachinrange(skill_area_sub, bl,
sd->splash_range, BL_CHAR,
sd->bonus.splash_range, BL_CHAR,
src, skillid, skilllv, tick, flag | BCT_ENEMY | 1,
skill_castend_damage_id);
flag|=1; //Set flag to 1 so ammo is not double-consumed. [Skotlex]
@ -7926,7 +7923,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case LG_SHIELDSPELL:
if( flag&1 ) {
int duration = (sd) ? sd->shieldmdef * 2000 : 10000;
int duration = (sd) ? sd->bonus.shieldmdef * 2000 : 10000;
sc_start(bl,SC_SILENCE,100,skilllv,duration);
} else if( sd ) {
int opt = skilllv;
@ -7969,7 +7966,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case 2:
brate = sd->shieldmdef * 20;
brate = sd->bonus.shieldmdef * 20;
if( rate < 30 )
opt = 1;
else if( rate < 60 )
@ -7991,9 +7988,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
map_foreachinrange(skill_area_sub,src,skill_get_splash(skillid,skilllv),BL_CHAR,src,skillid,skilllv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id);
break;
case 3:
if( sc_start(bl,SC_SHIELDSPELL_MDEF,brate,opt,sd->shieldmdef * 30000) )
if( sc_start(bl,SC_SHIELDSPELL_MDEF,brate,opt,sd->bonus.shieldmdef * 30000) )
clif_skill_nodamage(src,bl,PR_MAGNIFICAT,skilllv,
sc_start(bl,SC_MAGNIFICAT,100,1,sd->shieldmdef * 30000));
sc_start(bl,SC_MAGNIFICAT,100,1,sd->bonus.shieldmdef * 30000));
break;
}
break;

View File

@ -1753,7 +1753,7 @@ int status_base_amotion_pc(struct map_session_data* sd, struct status_data* stat
amotion -= amotion * (4*status->agi + status->dex)/1000;
// raw delay adjustment from bAspd bonus
amotion+= sd->aspd_add;
amotion += sd->bonus.aspd_add;
#ifdef RENEWAL
if( sd->status.shield ) {// bearing a shield decreases your ASPD by a fixed value depending on your class
@ -2353,60 +2353,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
+ sizeof(sd->subele2)
);
// vars zeroing. ints, shorts, chars. in that order.
memset (&sd->atk_rate, 0,sizeof(sd->atk_rate)
+ sizeof(sd->arrow_atk)
+ sizeof(sd->arrow_ele)
+ sizeof(sd->arrow_cri)
+ sizeof(sd->arrow_hit)
+ sizeof(sd->nsshealhp)
+ sizeof(sd->nsshealsp)
+ sizeof(sd->critical_def)
+ sizeof(sd->double_rate)
+ sizeof(sd->long_attack_atk_rate)
+ sizeof(sd->near_attack_def_rate)
+ sizeof(sd->long_attack_def_rate)
+ sizeof(sd->magic_def_rate)
+ sizeof(sd->misc_def_rate)
+ sizeof(sd->ignore_mdef_ele)
+ sizeof(sd->ignore_mdef_race)
+ sizeof(sd->perfect_hit)
+ sizeof(sd->perfect_hit_add)
+ sizeof(sd->get_zeny_rate)
+ sizeof(sd->get_zeny_num)
+ sizeof(sd->double_add_rate)
+ sizeof(sd->short_weapon_damage_return)
+ sizeof(sd->long_weapon_damage_return)
+ sizeof(sd->magic_damage_return)
+ sizeof(sd->break_weapon_rate)
+ sizeof(sd->break_armor_rate)
+ sizeof(sd->crit_atk_rate)
+ sizeof(sd->classchange)
+ sizeof(sd->speed_rate)
+ sizeof(sd->speed_add_rate)
+ sizeof(sd->aspd_add)
+ sizeof(sd->setitem_hash)
+ sizeof(sd->setitem_hash2)
+ sizeof(sd->itemhealrate2)
+ sizeof(sd->shieldmdef)
// shorts
+ sizeof(sd->splash_range)
+ sizeof(sd->splash_add_range)
+ sizeof(sd->add_steal_rate)
+ sizeof(sd->add_heal_rate)
+ sizeof(sd->add_heal2_rate)
+ sizeof(sd->hp_gain_value)
+ sizeof(sd->sp_gain_value)
+ sizeof(sd->magic_hp_gain_value)
+ sizeof(sd->magic_sp_gain_value)
+ sizeof(sd->sp_vanish_rate)
+ sizeof(sd->sp_vanish_per)
+ sizeof(sd->sp_weapon_matk)
+ sizeof(sd->sp_base_matk)
+ sizeof(sd->unbreakable)
+ sizeof(sd->unbreakable_equip)
+ sizeof(sd->unstripable_equip)
);
memset (&sd->bonus, 0,sizeof(sd->bonus));
// Autobonus
pc_delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true);
@ -2520,7 +2467,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
if(sd->equip_index[EQI_AMMO] >= 0){
index = sd->equip_index[EQI_AMMO];
if(sd->inventory_data[index]){ // Arrows
sd->arrow_atk += sd->inventory_data[index]->atk;
sd->bonus.arrow_atk += sd->inventory_data[index]->atk;
sd->state.lr_flag = 2;
if( !itemdb_is_GNthrowable(sd->inventory_data[index]->nameid) ) //don't run scripts on throwable items
run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
@ -2538,7 +2485,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
#ifdef RENEWAL
// increment the weapon ATK using the MATK max value
status->matk_max += sd->sp_weapon_matk;
status->matk_max += sd->bonus.sp_weapon_matk;
#endif
//Parse Cards
@ -2622,9 +2569,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
if(status->rhw.range < status->lhw.range)
status->rhw.range = status->lhw.range;
sd->double_rate += sd->double_add_rate;
sd->perfect_hit += sd->perfect_hit_add;
sd->splash_range += sd->splash_add_range;
sd->bonus.double_rate += sd->bonus.double_add_rate;
sd->bonus.perfect_hit += sd->bonus.perfect_hit_add;
sd->bonus.splash_range += sd->bonus.splash_add_range;
// Damage modifiers from weapon type
sd->right_weapon.atkmods[0] = atkmods[0][sd->weapontype1];
@ -3724,7 +3671,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
#ifdef RENEWAL
status->matk_min = status_base_matk_min(status,status_get_lv(bl));
if( sd )
status->matk_min += sd->sp_base_matk;
status->matk_min += sd->bonus.sp_base_matk;
#else
status->matk_min = status_base_matk_min(status);
#endif
@ -4922,8 +4869,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
if( sc->data[SC_MELON_BOMB] )
val = max( val, sc->data[SC_MELON_BOMB]->val1 );
if( sd && sd->speed_rate + sd->speed_add_rate > 0 ) // permanent item-based speedup
val = max( val, sd->speed_rate + sd->speed_add_rate );
if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0 ) // permanent item-based speedup
val = max( val, sd->bonus.speed_rate + sd->bonus.speed_add_rate );
}
speed_rate += val;
@ -4971,8 +4918,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
//FIXME: official items use a single bonus for this [ultramage]
if( sc->data[SC_SPEEDUP0] ) // temporary item-based speedup
val = max( val, 25 );
if( sd && sd->speed_rate + sd->speed_add_rate < 0 ) // permanent item-based speedup
val = max( val, -(sd->speed_rate + sd->speed_add_rate) );
if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate < 0 ) // permanent item-based speedup
val = max( val, -(sd->bonus.speed_rate + sd->bonus.speed_add_rate) );
speed_rate -= val;
}
@ -6207,20 +6154,16 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data
int i;
opt_flag = 0; //Reuse to check success condition.
if(sd->unstripable_equip&EQP_WEAPON)
if(sd->bonus.unstripable_equip&EQP_WEAPON)
return 0;
i = sd->equip_index[EQI_HAND_L];
if (i>=0 && sd->inventory_data[i] &&
sd->inventory_data[i]->type == IT_WEAPON)
{
if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
opt_flag|=1;
pc_unequipitem(sd,i,3); //L-hand weapon
}
i = sd->equip_index[EQI_HAND_R];
if (i>=0 && sd->inventory_data[i] &&
sd->inventory_data[i]->type == IT_WEAPON)
{
if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
opt_flag|=2;
pc_unequipitem(sd,i,3);
}
@ -6233,11 +6176,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
else
if (sd && !(flag&4)) {
int i;
if(sd->unstripable_equip&EQP_SHIELD)
if(sd->bonus.unstripable_equip&EQP_SHIELD)
return 0;
i = sd->equip_index[EQI_HAND_L];
if (i<0 || !sd->inventory_data[i] ||
sd->inventory_data[i]->type != IT_ARMOR)
if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR )
return 0;
pc_unequipitem(sd,i,3);
}
@ -6246,7 +6188,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_STRIPARMOR:
if (sd && !(flag&4)) {
int i;
if(sd->unstripable_equip&EQP_ARMOR)
if(sd->bonus.unstripable_equip&EQP_ARMOR)
return 0;
i = sd->equip_index[EQI_ARMOR];
if ( i < 0 || !sd->inventory_data[i] )
@ -6258,7 +6200,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_STRIPHELM:
if (sd && !(flag&4)) {
int i;
if(sd->unstripable_equip&EQP_HELM)
if(sd->bonus.unstripable_equip&EQP_HELM)
return 0;
i = sd->equip_index[EQI_HEAD_TOP];
if ( i < 0 || !sd->inventory_data[i] )
@ -6330,11 +6272,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC__STRIPACCESSORY:
if( sd ) {
int i = -1;
if( !(sd->unstripable_equip&EQI_ACC_L) ) {
if( !(sd->bonus.unstripable_equip&EQI_ACC_L) ) {
i = sd->equip_index[EQI_ACC_L];
if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
pc_unequipitem(sd,i,3); //L-Accessory
} if( !(sd->unstripable_equip&EQI_ACC_R) ) {
} if( !(sd->bonus.unstripable_equip&EQI_ACC_R) ) {
i = sd->equip_index[EQI_ACC_R];
if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
pc_unequipitem(sd,i,3); //R-Accessory