Merge pull request #136 from rathena/cleanup/renewal_cast
Clean up something RENEWAL_CAST * Moved additive bonuses (reducing/increasing) to first calculation before the rate adjustment * Corrected `bonus(2) bFixedCastrate` shouldn't be stacked. Example between Puente_Robe (15012) is -3% and +10 Rafini_Staff (1649) is -10%, only -10% will be used not -13%. * Reversed some value assignment, `-=` to `+=` and other part that affected by this change. * Also as follow up c3e488e & 4f4d8fe, fixed `bonus2 bFixedCastrate,"sk",rate;` algorithm * Corrected `bFixedCastrate` for Krieger_Knuckle2 (1827) only for skill `MO_EXTREMITYFIST` * Moved default the 20% of fixed cast rate to conf/battle/skill.conf `default_fixed_castrate`
This commit is contained in:
commit
d3704d50dd
@ -330,3 +330,9 @@ arrow_shower_knockback: yes
|
||||
// punch a hole into SG it will for example create a "suck in" effect.
|
||||
// If you disable this setting, the knockback direction will be completely random (eAthena style).
|
||||
stormgust_knockback: yes
|
||||
|
||||
// For RENEWAL_CAST (Note 2)
|
||||
// By default skill that has '0' value for Fixed Casting Time will use 20% of cast time
|
||||
// as Fixed Casting Time, and the rest (80%) as Variable Casting Time.
|
||||
// Put it 0 to disable default Fixed Casting Time (just like -1 is the skill_cast_db.txt).
|
||||
default_fixed_castrate: 20
|
||||
|
@ -1078,7 +1078,7 @@
|
||||
1824,BF_Knuckle2,Brave Battle Fist,5,20,,0,30,,1,0,0x00008100,63,2,2,3,80,1,12,{ bonus bStr,2; bonus bInt,1; bonus2 bAddRace,RC_DemiHuman,95; bonus2 bAddRace,RC_Player,95; bonus2 bVariableCastrate,"MO_EXTREMITYFIST",-25; autobonus "{ bonus2 bVariableCastrate,\"MO_EXTREMITYFIST\",-100; }",50,6000,BF_WEAPON,"{ specialeffect2 EF_SUFFRAGIUM; }"; bonus bUnbreakableWeapon,0; },{},{}
|
||||
1825,Horn_Of_Hilthrion,Horn of Hillslion,5,20,,600,95,,1,3,0x00008000,18,2,2,3,60,1,12,{ bonus3 bAutoSpell,"NPC_CRITICALWOUND",1,100; bonus4 bAutoSpellOnSkill,"CH_PALMSTRIKE","MO_INVESTIGATE",1,100; bonus3 bAutoSpell,"MO_CALLSPIRITS",5,100; },{},{}
|
||||
1826,Krieger_Knuckle1,Glorious Claw,5,20,,0,30,,1,0,0x00008100,63,2,2,4,80,1,12,{ bonus2 bAddRace,RC_DemiHuman,95; bonus2 bAddRace,RC_Player,95; bonus2 bIgnoreDefRaceRate,RC_DemiHuman,20; bonus2 bIgnoreDefRaceRate,RC_Player,20; bonus bUnbreakableWeapon,0; if(getrefine()>5) { bonus2 bAddRace,RC_DemiHuman,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bAddRace,RC_Player,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bIgnoreDefRaceRate,RC_DemiHuman,5; bonus2 bIgnoreDefRaceRate,RC_Player,5; } if(getrefine()>8) { bonus3 bAutoSpell,"MO_INVESTIGATE",5,(getrefine()*10-50); bonus3 bAutoSpell,"AL_DECAGI",1,(getrefine()*10-50); } },{},{}
|
||||
1827,Krieger_Knuckle2,Glorious Fist,5,20,,0,30,,1,0,0x00008100,63,2,2,4,80,1,12,{ bonus2 bAddRace,RC_DemiHuman,95; bonus2 bAddRace,RC_Player,95; bonus2 bIgnoreDefRaceRate,RC_DemiHuman,20; bonus2 bIgnoreDefRaceRate,RC_Player,20; bonus bUnbreakableWeapon,0; if(getrefine()>5) { bonus2 bAddRace,RC_DemiHuman,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bAddRace,RC_Player,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bIgnoreDefRaceRate,RC_DemiHuman,5; bonus2 bIgnoreDefRaceRate,RC_Player,5; } if(getrefine()>8) { bonus2 bVariableCastrate,"MO_EXTREMITYFIST",-100; bonus4 bautospellonskill,"MO_EXPLOSIONSPIRITS","CH_SOULCOLLECT",1,1000; bonus bFixedCastrate,-100; } },{},{}
|
||||
1827,Krieger_Knuckle2,Glorious Fist,5,20,,0,30,,1,0,0x00008100,63,2,2,4,80,1,12,{ bonus2 bAddRace,RC_DemiHuman,95; bonus2 bAddRace,RC_Player,95; bonus2 bIgnoreDefRaceRate,RC_DemiHuman,20; bonus2 bIgnoreDefRaceRate,RC_Player,20; bonus bUnbreakableWeapon,0; if(getrefine()>5) { bonus2 bAddRace,RC_DemiHuman,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bAddRace,RC_Player,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bIgnoreDefRaceRate,RC_DemiHuman,5; bonus2 bIgnoreDefRaceRate,RC_Player,5; } if(getrefine()>8) { bonus2 bVariableCastrate,"MO_EXTREMITYFIST",-100; bonus2 bFixedCastrate,"MO_EXTREMITYFIST",-100; bonus4 bautospellonskill,"MO_EXPLOSIONSPIRITS","CH_SOULCOLLECT",1,1000; } },{},{}
|
||||
1828,Monk_Knuckle,Monk Knuckle,5,20,,0,150,,1,0,0x00008100,63,2,2,4,0,0,12,{ bonus bInt,2; bonus2 bSkillAtk,"MO_FINGEROFFENSIVE",25; },{},{}
|
||||
1829,Fist_C,Fist,5,0,,0,150,,1,0,0x00008100,63,2,2,3,1,0,12,{ bonus2 bAddSize,Size_All,40; },{},{}
|
||||
1830,Sura_Rampage,Sura Rampage,5,20,,500,142,,1,1,0x00008100,63,2,2,3,102,1,12,{ bonus2 bSkillAtk,"SR_EARTHSHAKER",20; bonus2 bSkillAtk,"SR_SKYNETBLOW",20; bonus bUseSPrate,5; if(getrefine()>6) { bonus bUseSPrate,-1*(getrefine()-6); } },{},{}
|
||||
|
@ -174,16 +174,18 @@ bonus2 bAddItemGroupHealRate,ig,n; Increases HP recovered by n% for items of ite
|
||||
|
||||
Cast time/delay
|
||||
---------------
|
||||
bonus bCastrate,n; Skill cast time rate + n%
|
||||
bonus2 bCastrate,sk,n; Adjust casting time of skill sk by n%
|
||||
bonus bFixedCastrate,n; Increases fixed cast time of all skills by n%
|
||||
bonus2 bFixedCastrate,sk,n; Increases fixed cast time of skill sk by n%
|
||||
bonus bVariableCastrate,n; Increases variable cast time of all skills by n%
|
||||
bonus2 bVariableCastrate,sk,n; Increases variable cast time of skill sk by n%
|
||||
bonus bFixedCast,t; Increases fixed cast time of all skills by t milliseconds
|
||||
bonus2 bSkillFixedCast,sk,t; Increases fixed cast time of skill sk by t milliseconds
|
||||
bonus bVariableCast,t; Increases variable cast time of all skills by t milliseconds
|
||||
bonus2 bSkillVariableCast,sk,t; Increases variable cast time of skill sk by t milliseconds
|
||||
bonus bCastrate,n; Skill cast time rate + n%. (If RENEWAL_CAST is defined, this bonus is equal to bVariableCastrate)
|
||||
bonus2 bCastrate,sk,n; Adjust casting time of skill sk by n%.(If RENEWAL_CAST is defined, this bonus is equal to bVariableCastrate)
|
||||
|
||||
bonus bFixedCastrate,n; Increases fixed cast time of all skills by n% (has effect in RENEWAL_CAST only)
|
||||
bonus2 bFixedCastrate,sk,n; Increases fixed cast time of skill sk by n% (has effect in RENEWAL_CAST only)
|
||||
bonus bVariableCastrate,n; Increases variable cast time of all skills by n%. (If RENEWAL_CAST is NOT defined, this bonus is equal to bCastrate)
|
||||
bonus2 bVariableCastrate,sk,n; Increases variable cast time of skill sk by n% (If RENEWAL_CAST is NOT defined, this bonus is equal to bCastrate)
|
||||
|
||||
bonus bFixedCast,t; Increases fixed cast time of all skills by t milliseconds (has effect in RENEWAL_CAST only)
|
||||
bonus2 bSkillFixedCast,sk,t; Increases fixed cast time of skill sk by t milliseconds (has effect in RENEWAL_CAST only)
|
||||
bonus bVariableCast,t; Increases variable cast time of all skills by t milliseconds (has effect in RENEWAL_CAST only)
|
||||
bonus2 bSkillVariableCast,sk,t; Increases variable cast time of skill sk by t milliseconds (has effect in RENEWAL_CAST only)
|
||||
|
||||
bonus bNoCastCancel,n; Prevents casting from being interrupted when hit (does not work in GvG | n is meaningless)
|
||||
bonus bNoCastCancel2,n; Prevents casting from being interrupted when hit (works even in GvG | n is meaningless)
|
||||
|
@ -1109,7 +1109,7 @@ REPLACE INTO `item_db_re` VALUES (1823,'BF_Knuckle1','Valorous Battle Fist',5,20
|
||||
REPLACE INTO `item_db_re` VALUES (1824,'BF_Knuckle2','Brave Battle Fist',5,20,NULL,0,'30',NULL,1,0,0x00008100,63,2,2,3,'80',1,12,'bonus bStr,2; bonus bInt,1; bonus2 bAddRace,RC_DemiHuman,95; bonus2 bAddRace,RC_Player,95; bonus2 bVariableCastrate,"MO_EXTREMITYFIST",-25; autobonus "{ bonus2 bVariableCastrate,\\\"MO_EXTREMITYFIST\\\",-100; }",50,6000,BF_WEAPON,"{ specialeffect2 EF_SUFFRAGIUM; }"; bonus bUnbreakableWeapon,0;',NULL,NULL);
|
||||
REPLACE INTO `item_db_re` VALUES (1825,'Horn_Of_Hilthrion','Horn of Hillslion',5,20,NULL,600,'95',NULL,1,3,0x00008000,18,2,2,3,'60',1,12,'bonus3 bAutoSpell,"NPC_CRITICALWOUND",1,100; bonus4 bAutoSpellOnSkill,"CH_PALMSTRIKE","MO_INVESTIGATE",1,100; bonus3 bAutoSpell,"MO_CALLSPIRITS",5,100;',NULL,NULL);
|
||||
REPLACE INTO `item_db_re` VALUES (1826,'Krieger_Knuckle1','Glorious Claw',5,20,NULL,0,'30',NULL,1,0,0x00008100,63,2,2,4,'80',1,12,'bonus2 bAddRace,RC_DemiHuman,95; bonus2 bAddRace,RC_Player,95; bonus2 bIgnoreDefRaceRate,RC_DemiHuman,20; bonus2 bIgnoreDefRaceRate,RC_Player,20; bonus bUnbreakableWeapon,0; if(getrefine()>5) { bonus2 bAddRace,RC_DemiHuman,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bAddRace,RC_Player,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bIgnoreDefRaceRate,RC_DemiHuman,5; bonus2 bIgnoreDefRaceRate,RC_Player,5; } if(getrefine()>8) { bonus3 bAutoSpell,"MO_INVESTIGATE",5,(getrefine()*10-50); bonus3 bAutoSpell,"AL_DECAGI",1,(getrefine()*10-50); }',NULL,NULL);
|
||||
REPLACE INTO `item_db_re` VALUES (1827,'Krieger_Knuckle2','Glorious Fist',5,20,NULL,0,'30',NULL,1,0,0x00008100,63,2,2,4,'80',1,12,'bonus2 bAddRace,RC_DemiHuman,95; bonus2 bAddRace,RC_Player,95; bonus2 bIgnoreDefRaceRate,RC_DemiHuman,20; bonus2 bIgnoreDefRaceRate,RC_Player,20; bonus bUnbreakableWeapon,0; if(getrefine()>5) { bonus2 bAddRace,RC_DemiHuman,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bAddRace,RC_Player,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bIgnoreDefRaceRate,RC_DemiHuman,5; bonus2 bIgnoreDefRaceRate,RC_Player,5; } if(getrefine()>8) { bonus2 bVariableCastrate,"MO_EXTREMITYFIST",-100; bonus4 bautospellonskill,"MO_EXPLOSIONSPIRITS","CH_SOULCOLLECT",1,1000; bonus bFixedCastrate,-100; }',NULL,NULL);
|
||||
REPLACE INTO `item_db_re` VALUES (1827,'Krieger_Knuckle2','Glorious Fist',5,20,NULL,0,'30',NULL,1,0,0x00008100,63,2,2,4,'80',1,12,'bonus2 bAddRace,RC_DemiHuman,95; bonus2 bAddRace,RC_Player,95; bonus2 bIgnoreDefRaceRate,RC_DemiHuman,20; bonus2 bIgnoreDefRaceRate,RC_Player,20; bonus bUnbreakableWeapon,0; if(getrefine()>5) { bonus2 bAddRace,RC_DemiHuman,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bAddRace,RC_Player,pow(((getrefine()>14)?14:getrefine())-4,2); bonus2 bIgnoreDefRaceRate,RC_DemiHuman,5; bonus2 bIgnoreDefRaceRate,RC_Player,5; } if(getrefine()>8) { bonus2 bVariableCastrate,"MO_EXTREMITYFIST",-100; bonus2 bFixedCastrate,"MO_EXTREMITYFIST",-100; bonus4 bautospellonskill,"MO_EXPLOSIONSPIRITS","CH_SOULCOLLECT",1,1000; }',NULL,NULL);
|
||||
REPLACE INTO `item_db_re` VALUES (1828,'Monk_Knuckle','Monk Knuckle',5,20,NULL,0,'150',NULL,1,0,0x00008100,63,2,2,4,'0',0,12,'bonus bInt,2; bonus2 bSkillAtk,"MO_FINGEROFFENSIVE",25;',NULL,NULL);
|
||||
REPLACE INTO `item_db_re` VALUES (1829,'Fist_C','Fist',5,0,NULL,0,'150',NULL,1,0,0x00008100,63,2,2,3,'1',0,12,'bonus2 bAddSize,Size_All,40;',NULL,NULL);
|
||||
REPLACE INTO `item_db_re` VALUES (1830,'Sura_Rampage','Sura Rampage',5,20,NULL,500,'142',NULL,1,1,0x00008100,63,2,2,3,'102',1,12,'bonus2 bSkillAtk,"SR_EARTHSHAKER",20; bonus2 bSkillAtk,"SR_SKYNETBLOW",20; bonus bUseSPrate,5; if(getrefine()>6) { bonus bUseSPrate,-1*(getrefine()-6); }',NULL,NULL);
|
||||
|
@ -99,10 +99,12 @@
|
||||
|
||||
// Renewal variable cast time reduction
|
||||
#ifdef RENEWAL_CAST
|
||||
#define VARCAST_REDUCTION(val){ \
|
||||
if( (varcast_r += (val)) != 0 && varcast_r >= 0 ) \
|
||||
time = time * (1 - (float)min((val), 100) / 100); \
|
||||
}
|
||||
// Multiply the Variable CastTime
|
||||
#define VARCAST_REDUCTION(val) ( time = time * (1 + (val) * 0.01) )
|
||||
|
||||
// Get the highest rate TO REDUCE Fixed CastTime
|
||||
// -100 is "the highest" rate than 100.
|
||||
#define FIXEDCASTRATE(fcast,val) ( ((fcast) == 0) ? ((fcast) = (val)) : ((fcast) = min((fcast),(val))) )
|
||||
#endif
|
||||
/**
|
||||
* End of File
|
||||
|
@ -16,57 +16,60 @@
|
||||
* @INFO: This file holds general-purpose renewal settings, for class-specific ones check /src/config/classes folder
|
||||
**/
|
||||
|
||||
/// game renewal server mode
|
||||
/// Game renewal server mode
|
||||
/// (disable by commenting the line)
|
||||
///
|
||||
/// leave this line to enable renewal specific support such as renewal formulas
|
||||
/// Leave this line to enable renewal specific support such as renewal formulas
|
||||
#define RENEWAL
|
||||
|
||||
/// renewal cast time
|
||||
/// Renewal cast time
|
||||
/// (disable by commenting the line)
|
||||
///
|
||||
/// leave this line to enable renewal casting time algorithms
|
||||
/// cast time is decreased by DEX * 2 + INT while 20% of the cast time is not reduced by stats.
|
||||
/// example:
|
||||
/// on a skill whos cast time is 10s, only 8s may be reduced. the other 2s are part of a
|
||||
/// "fixed cast time" which can only be reduced by specialist items and skills
|
||||
/// Leave this line to enable renewal casting time algorithms and enable fixed cast bonuses.
|
||||
/// See also default_fixed_castrate in conf/battle/skill.conf for default fixed cast time (default is 20%).
|
||||
/// Cast time is altered be 2 portion, Variable Cast Time (VCT) and Fixed Cast Time (FCT).
|
||||
/// By default FCT is 20% of VCT (some skills aren't)
|
||||
/// - VCT is decreased by DEX * 2 + INT.
|
||||
/// - FCT is NOT reduced by stats, reduced by equips or buffs.
|
||||
/// Example:
|
||||
/// On a skill whos cast time is 10s, only 8s may be reduced. the other 2s are part of a FCT
|
||||
#define RENEWAL_CAST
|
||||
|
||||
/// renewal drop rate algorithms
|
||||
/// Renewal drop rate algorithms
|
||||
/// (disable by commenting the line)
|
||||
///
|
||||
/// leave this line to enable renewal item drop rate algorithms
|
||||
/// while enabled a special modified based on the difference between the player and monster level is applied
|
||||
/// based on the http://irowiki.org/wiki/Drop_System#Level_Factor table
|
||||
/// Leave this line to enable renewal item drop rate algorithms
|
||||
/// While enabled a special modified based on the difference between the player and monster level is applied
|
||||
/// Based on the http://irowiki.org/wiki/Drop_System#Level_Factor table
|
||||
#define RENEWAL_DROP
|
||||
|
||||
/// renewal exp rate algorithms
|
||||
/// Renewal exp rate algorithms
|
||||
/// (disable by commenting the line)
|
||||
///
|
||||
/// leave this line to enable renewal item exp rate algorithms
|
||||
/// while enabled a special modified based on the difference between the player and monster level is applied
|
||||
/// Leave this line to enable renewal item exp rate algorithms
|
||||
/// While enabled a special modified based on the difference between the player and monster level is applied
|
||||
#define RENEWAL_EXP
|
||||
|
||||
/// renewal level modifier on damage
|
||||
/// Renewal level modifier on damage
|
||||
/// (disable by commenting the line)
|
||||
///
|
||||
// leave this line to enable renewal base level modifier on skill damage (selected skills only)
|
||||
// Leave this line to enable renewal base level modifier on skill damage (selected skills only)
|
||||
#define RENEWAL_LVDMG
|
||||
|
||||
/// renewal ASPD [malufett]
|
||||
/// Renewal ASPD [malufett]
|
||||
/// (disable by commenting the line)
|
||||
///
|
||||
/// leave this line to enable renewal ASPD
|
||||
/// Leave this line to enable renewal ASPD
|
||||
/// - shield penalty is applied
|
||||
/// - AGI has a greater factor in ASPD increase
|
||||
/// - there is a change in how skills/items give ASPD
|
||||
/// - some skill/item ASPD bonuses won't stack
|
||||
#define RENEWAL_ASPD
|
||||
|
||||
/// renewal stat calculations
|
||||
/// Renewal stat calculations
|
||||
/// (disable by commenting the line)
|
||||
///
|
||||
/// leave this line to enable renewal calculation for increasing status/parameter points
|
||||
/// Leave this line to enable renewal calculation for increasing status/parameter points
|
||||
#define RENEWAL_STAT
|
||||
|
||||
#endif
|
||||
|
@ -7945,6 +7945,7 @@ static const struct _battle_data {
|
||||
{ "boss_icewall_walk_block", &battle_config.boss_icewall_walk_block, 0, 0, 255, },
|
||||
{ "snap_dodge", &battle_config.snap_dodge, 0, 0, 1, },
|
||||
{ "stormgust_knockback", &battle_config.stormgust_knockback, 1, 0, 1, },
|
||||
{ "default_fixed_castrate", &battle_config.default_fixed_castrate, 20, 0, 100, },
|
||||
};
|
||||
|
||||
#ifndef STATS_OPT_OUT
|
||||
|
@ -579,6 +579,7 @@ extern struct Battle_Config
|
||||
int boss_icewall_walk_block; //How a boss monster should be trapped in icewall [Playtester]
|
||||
int snap_dodge; // Enable or disable dodging damage snapping away [csnv]
|
||||
int stormgust_knockback;
|
||||
int default_fixed_castrate;
|
||||
} battle_config;
|
||||
|
||||
void do_init_battle(void);
|
||||
|
155
src/map/pc.c
155
src/map/pc.c
@ -2497,13 +2497,6 @@ void pc_bonus(struct map_session_data *sd,int type,int val)
|
||||
break;
|
||||
sd->bonus.sp += val;
|
||||
break;
|
||||
#ifndef RENEWAL_CAST
|
||||
case SP_VARCASTRATE:
|
||||
#endif
|
||||
case SP_CASTRATE:
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->castrate+=val;
|
||||
break;
|
||||
case SP_MAXHPRATE:
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->hprate+=val;
|
||||
@ -2911,26 +2904,38 @@ void pc_bonus(struct map_session_data *sd,int type,int val)
|
||||
sd->bonus.itemhealrate2 += val;
|
||||
break;
|
||||
case SP_EMATK:
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->bonus.ematk += val;
|
||||
break;
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->bonus.ematk += val;
|
||||
break;
|
||||
#ifdef RENEWAL_CAST
|
||||
case SP_FIXCASTRATE:
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->bonus.fixcastrate -= val;
|
||||
FIXEDCASTRATE(sd->bonus.fixcastrate,val);
|
||||
break;
|
||||
case SP_ADD_FIXEDCAST:
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->bonus.add_fixcast += val;
|
||||
break;
|
||||
#ifdef RENEWAL_CAST
|
||||
case SP_CASTRATE:
|
||||
case SP_VARCASTRATE:
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->bonus.varcastrate -= val;
|
||||
sd->bonus.varcastrate += val;
|
||||
break;
|
||||
case SP_ADD_VARIABLECAST:
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->bonus.add_varcast += val;
|
||||
break;
|
||||
#else
|
||||
case SP_ADD_FIXEDCAST:
|
||||
case SP_FIXCASTRATE:
|
||||
case SP_ADD_VARIABLECAST:
|
||||
//ShowWarning("pc_bonus: non-RENEWAL_CAST doesn't support this bonus %d.\n", type);
|
||||
break;
|
||||
case SP_VARCASTRATE:
|
||||
case SP_CASTRATE:
|
||||
if(sd->state.lr_flag != 2)
|
||||
sd->castrate += val;
|
||||
break;
|
||||
#endif
|
||||
case SP_ADDMAXWEIGHT:
|
||||
if (sd->state.lr_flag != 2)
|
||||
@ -3305,7 +3310,7 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillblown), i, sd->skillblown[i].id == 0 || sd->skillblown[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillblown))
|
||||
{ //Better mention this so the array length can be updated. [Skotlex]
|
||||
ShowError("pc_bonus2: SP_ADD_SKILL_BLOW: Reached max (%d) number of skills per character, bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillblown), type2, val);
|
||||
ShowError("pc_bonus2: SP_ADD_SKILL_BLOW: Reached max (%d) number of skills per character, bonus skill %d (%d) lost.\n", ARRAYLENGTH(sd->skillblown), type2, val);
|
||||
break;
|
||||
}
|
||||
if(sd->skillblown[i].id == type2)
|
||||
@ -3315,49 +3320,6 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
|
||||
sd->skillblown[i].val = val;
|
||||
}
|
||||
break;
|
||||
#ifndef RENEWAL_CAST
|
||||
case SP_VARCASTRATE: // bonus2 bVariableCastrate,sk,n;
|
||||
#endif
|
||||
case SP_CASTRATE: // bonus2 bCastrate,sk,n;
|
||||
if(sd->state.lr_flag == 2)
|
||||
break;
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillcast))
|
||||
{ //Better mention this so the array length can be updated. [Skotlex]
|
||||
ShowError("run_script: %s: Reached max (%d) number of skills per character, bonus skill %d (+%d%%) lost.\n",
|
||||
|
||||
#ifndef RENEWAL_CAST
|
||||
"SP_VARCASTRATE",
|
||||
#else
|
||||
"SP_CASTRATE",
|
||||
#endif
|
||||
|
||||
ARRAYLENGTH(sd->skillcast), type2, val);
|
||||
break;
|
||||
}
|
||||
if(sd->skillcast[i].id == type2)
|
||||
sd->skillcast[i].val += val;
|
||||
else {
|
||||
sd->skillcast[i].id = type2;
|
||||
sd->skillcast[i].val = val;
|
||||
}
|
||||
break;
|
||||
case SP_FIXCASTRATE: // bonus2 bFixedCastrate,sk,n;
|
||||
if(sd->state.lr_flag == 2)
|
||||
break;
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillfixcastrate), i, sd->skillfixcastrate[i].id == 0 || sd->skillfixcastrate[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillfixcastrate))
|
||||
{
|
||||
ShowError("run_script: SP_FIXCASTRATE: Reached max (%d) number of skills per character, bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcastrate), type2, val);
|
||||
break;
|
||||
}
|
||||
if(sd->skillfixcastrate[i].id == type2)
|
||||
sd->skillfixcastrate[i].val -= val;
|
||||
else {
|
||||
sd->skillfixcastrate[i].id = type2;
|
||||
sd->skillfixcastrate[i].val -= val;
|
||||
}
|
||||
break;
|
||||
case SP_HP_LOSS_RATE: // bonus2 bHPLossRate,n,t;
|
||||
if(sd->state.lr_flag != 2) {
|
||||
sd->hp_loss.value = type2;
|
||||
@ -3528,7 +3490,7 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillcooldown), i, sd->skillcooldown[i].id == 0 || sd->skillcooldown[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillcooldown))
|
||||
{
|
||||
ShowError("pc_bonus2: SP_SKILL_COOLDOWN: Reached max (%d) number of skills per character, bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcooldown), type2, val);
|
||||
ShowError("pc_bonus2: SP_SKILL_COOLDOWN: Reached max (%d) number of skills per character, bonus skill %d (%d) lost.\n", ARRAYLENGTH(sd->skillcooldown), type2, val);
|
||||
break;
|
||||
}
|
||||
if (sd->skillcooldown[i].id == type2)
|
||||
@ -3538,13 +3500,14 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
|
||||
sd->skillcooldown[i].val = val;
|
||||
}
|
||||
break;
|
||||
#ifdef RENEWAL_CAST
|
||||
case SP_SKILL_FIXEDCAST: // bonus2 bSkillFixedCast,sk,t;
|
||||
if(sd->state.lr_flag == 2)
|
||||
break;
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillfixcast), i, sd->skillfixcast[i].id == 0 || sd->skillfixcast[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillfixcast))
|
||||
{
|
||||
ShowError("pc_bonus2: SP_SKILL_FIXEDCAST: Reached max (%d) number of skills per character, bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcast), type2, val);
|
||||
ShowError("pc_bonus2: SP_SKILL_FIXEDCAST: Reached max (%d) number of skills per character, bonus skill %d (%d) lost.\n", ARRAYLENGTH(sd->skillfixcast), type2, val);
|
||||
break;
|
||||
}
|
||||
if (sd->skillfixcast[i].id == type2)
|
||||
@ -3560,7 +3523,7 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillvarcast), i, sd->skillvarcast[i].id == 0 || sd->skillvarcast[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillvarcast))
|
||||
{
|
||||
ShowError("pc_bonus2: SP_SKILL_VARIABLECAST: Reached max (%d) number of skills per character, bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillvarcast), type2, val);
|
||||
ShowError("pc_bonus2: SP_SKILL_VARIABLECAST: Reached max (%d) number of skills per character, bonus skill %d (%d) lost.\n", ARRAYLENGTH(sd->skillvarcast), type2, val);
|
||||
break;
|
||||
}
|
||||
if (sd->skillvarcast[i].id == type2)
|
||||
@ -3570,21 +3533,61 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
|
||||
sd->skillvarcast[i].val = val;
|
||||
}
|
||||
break;
|
||||
#ifdef RENEWAL_CAST
|
||||
case SP_CASTRATE: // bonus2 bCastrate,sk,n;
|
||||
case SP_VARCASTRATE: // bonus2 bVariableCastrate,sk,n;
|
||||
if(sd->state.lr_flag == 2)
|
||||
break;
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillcast))
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillcastrate), i, sd->skillcastrate[i].id == 0 || sd->skillcastrate[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillcastrate))
|
||||
{
|
||||
ShowError("pc_bonus2: SP_VARCASTRATE: Reached max (%d) number of skills per character, bonus skill %d (+%d%%) lost.\n",ARRAYLENGTH(sd->skillcast), type2, val);
|
||||
ShowError("pc_bonus2: SP_VARCASTRATE: Reached max (%d) number of skills per character, bonus skill %d (%d%%) lost.\n",ARRAYLENGTH(sd->skillcastrate), type2, val);
|
||||
break;
|
||||
}
|
||||
if(sd->skillcast[i].id == type2)
|
||||
sd->skillcast[i].val -= val;
|
||||
if(sd->skillcastrate[i].id == type2)
|
||||
sd->skillcastrate[i].val += val;
|
||||
else {
|
||||
sd->skillcast[i].id = type2;
|
||||
sd->skillcast[i].val -= val;
|
||||
sd->skillcastrate[i].id = type2;
|
||||
sd->skillcastrate[i].val += val;
|
||||
}
|
||||
break;
|
||||
case SP_FIXCASTRATE: // bonus2 bFixedCastrate,sk,n;
|
||||
if(sd->state.lr_flag == 2)
|
||||
break;
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillfixcastrate), i, sd->skillfixcastrate[i].id == 0 || sd->skillfixcastrate[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillfixcastrate))
|
||||
{
|
||||
ShowError("pc_bonus2: SP_FIXCASTRATE: Reached max (%d) number of skills per character, bonus skill %d (%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcastrate), type2, val);
|
||||
break;
|
||||
}
|
||||
if(sd->skillfixcastrate[i].id == type2)
|
||||
FIXEDCASTRATE(sd->skillfixcastrate[i].val,val);
|
||||
else {
|
||||
sd->skillfixcastrate[i].id = type2;
|
||||
sd->skillfixcastrate[i].val = val;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case SP_SKILL_FIXEDCAST: // bonus2 bSkillFixedCast,sk,t;
|
||||
case SP_SKILL_VARIABLECAST: // bonus2 bSkillVariableCast,sk,t;
|
||||
case SP_FIXCASTRATE: // bonus2 bFixedCastrate,sk,n;
|
||||
//ShowWarning("pc_bonus2: Non-RENEWAL_CAST doesn't support this bonus %d.\n", type);
|
||||
break;
|
||||
case SP_VARCASTRATE: // bonus2 bVariableCastrate,sk,n;
|
||||
case SP_CASTRATE: // bonus2 bCastrate,sk,n;
|
||||
if(sd->state.lr_flag == 2)
|
||||
break;
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillcastrate), i, sd->skillcastrate[i].id == 0 || sd->skillcastrate[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillcastrate))
|
||||
{ //Better mention this so the array length can be updated. [Skotlex]
|
||||
ShowError("pc_bonus2: %s: Reached max (%d) number of skills per character, bonus skill %d (%d%%) lost.\n",
|
||||
(type == SP_CASTRATE) ? "SP_CASTRATE" : "SP_VARCASTRATE", ARRAYLENGTH(sd->skillcastrate), type2, val);
|
||||
break;
|
||||
}
|
||||
if(sd->skillcastrate[i].id == type2)
|
||||
sd->skillcastrate[i].val += val;
|
||||
else {
|
||||
sd->skillcastrate[i].id = type2;
|
||||
sd->skillcastrate[i].val = val;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@ -3593,7 +3596,7 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
|
||||
break;
|
||||
ARR_FIND(0, ARRAYLENGTH(sd->skillusesp), i, sd->skillusesp[i].id == 0 || sd->skillusesp[i].id == type2);
|
||||
if (i == ARRAYLENGTH(sd->skillusesp)) {
|
||||
ShowError("pc_bonus2: SP_SKILL_USE_SP: Reached max (%d) number of skills per character, bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillusesp), type2, val);
|
||||
ShowError("pc_bonus2: SP_SKILL_USE_SP: Reached max (%d) number of skills per character, bonus skill %d (%d) lost.\n", ARRAYLENGTH(sd->skillusesp), type2, val);
|
||||
break;
|
||||
}
|
||||
if (sd->skillusesp[i].id == type2)
|
||||
@ -7572,12 +7575,6 @@ int pc_readparam(struct map_session_data* sd,int type)
|
||||
case SP_FLEE1: val = sd->battle_status.flee; break;
|
||||
case SP_FLEE2: val = sd->battle_status.flee2; break;
|
||||
case SP_DEFELE: val = sd->battle_status.def_ele; break;
|
||||
#ifndef RENEWAL_CAST
|
||||
case SP_VARCASTRATE:
|
||||
#endif
|
||||
case SP_CASTRATE:
|
||||
val = sd->castrate+=val;
|
||||
break;
|
||||
case SP_MAXHPRATE: val = sd->hprate; break;
|
||||
case SP_MAXSPRATE: val = sd->sprate; break;
|
||||
case SP_SPRATE: val = sd->dsprate; break;
|
||||
@ -7658,9 +7655,13 @@ int pc_readparam(struct map_session_data* sd,int type)
|
||||
case SP_EMATK: val = sd->bonus.ematk; break;
|
||||
case SP_FIXCASTRATE: val = sd->bonus.fixcastrate; break;
|
||||
case SP_ADD_FIXEDCAST: val = sd->bonus.add_fixcast; break;
|
||||
case SP_ADD_VARIABLECAST: val = sd->bonus.add_varcast; break;
|
||||
case SP_CASTRATE:
|
||||
case SP_VARCASTRATE:
|
||||
#ifdef RENEWAL_CAST
|
||||
case SP_VARCASTRATE: val = sd->bonus.varcastrate; break;
|
||||
case SP_ADD_VARIABLECAST:val = sd->bonus.add_varcast; break;
|
||||
val = sd->bonus.varcastrate; break;
|
||||
#else
|
||||
val = sd->castrate; break;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -355,7 +355,7 @@ struct map_session_data {
|
||||
struct s_skill_bonus { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills.
|
||||
unsigned short id;
|
||||
short val;
|
||||
} skillatk[MAX_PC_BONUS], skillusesprate[MAX_PC_BONUS], skillusesp[MAX_PC_BONUS], skillheal[MAX_PC_BONUS], skillheal2[MAX_PC_BONUS], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS], skillcooldown[MAX_PC_BONUS], skillfixcast[MAX_PC_BONUS], skillvarcast[MAX_PC_BONUS], skillfixcastrate[MAX_PC_BONUS];
|
||||
} skillatk[MAX_PC_BONUS], skillusesprate[MAX_PC_BONUS], skillusesp[MAX_PC_BONUS], skillheal[MAX_PC_BONUS], skillheal2[MAX_PC_BONUS], skillblown[MAX_PC_BONUS], skillcastrate[MAX_PC_BONUS], skillcooldown[MAX_PC_BONUS], skillfixcast[MAX_PC_BONUS], skillvarcast[MAX_PC_BONUS], skillfixcastrate[MAX_PC_BONUS];
|
||||
struct s_regen {
|
||||
short value;
|
||||
int rate;
|
||||
@ -419,8 +419,8 @@ 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;
|
||||
int fixcastrate,varcastrate;
|
||||
int add_fixcast,add_varcast;
|
||||
int fixcastrate, varcastrate; // n/100
|
||||
int add_fixcast, add_varcast; // in milliseconds
|
||||
int ematk; // matk bonus from equipment
|
||||
int eatk; // atk bonus from equipment
|
||||
} bonus;
|
||||
|
160
src/map/skill.c
160
src/map/skill.c
@ -15449,11 +15449,11 @@ int skill_castfix(struct block_list *bl, uint16 skill_id, uint16 skill_lv) {
|
||||
int i;
|
||||
if( sd->castrate != 100 )
|
||||
time = time * sd->castrate / 100;
|
||||
for( i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++ )
|
||||
for( i = 0; i < ARRAYLENGTH(sd->skillcastrate) && sd->skillcastrate[i].id; i++ )
|
||||
{
|
||||
if( sd->skillcast[i].id == skill_id )
|
||||
if( sd->skillcastrate[i].id == skill_id )
|
||||
{
|
||||
time+= time * sd->skillcast[i].val / 100;
|
||||
time += time * sd->skillcastrate[i].val / 100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -15488,8 +15488,8 @@ int skill_castfix_sc(struct block_list *bl, int time)
|
||||
if (sc && sc->count) {
|
||||
if (sc->data[SC_SLOWCAST])
|
||||
time += time * sc->data[SC_SLOWCAST]->val2 / 100;
|
||||
if (sc->data[SC_PARALYSIS])
|
||||
time += sc->data[SC_PARALYSIS]->val3;
|
||||
if (sc->data[SC_PARALYSIS])
|
||||
time += sc->data[SC_PARALYSIS]->val3;
|
||||
if (sc->data[SC_SUFFRAGIUM]) {
|
||||
time -= time * sc->data[SC_SUFFRAGIUM]->val2 / 100;
|
||||
status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER);
|
||||
@ -15511,7 +15511,14 @@ int skill_castfix_sc(struct block_list *bl, int time)
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* Get the skill cast time for RENEWAL_CAST
|
||||
* Get the skill cast time for RENEWAL_CAST.
|
||||
* FixedRate reduction never be stacked, always get the HIGHEST VALUE TO REDUCE (-20% vs 10%, -20% wins!)
|
||||
* Additive value:
|
||||
* Variable CastTime : time += value
|
||||
* Fixed CastTime : fixed += value
|
||||
* Multipicative value
|
||||
* Variable CastTime : VARCAST_REDUCTION(value)
|
||||
* Fixed CastTime : FIXEDCASTRATE2(value)
|
||||
* @param bl: The caster
|
||||
* @param time: Cast time without reduction
|
||||
* @param skill_id: Skill ID of the casted skill
|
||||
@ -15522,7 +15529,13 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
|
||||
{
|
||||
struct status_change *sc = status_get_sc(bl);
|
||||
struct map_session_data *sd = BL_CAST(BL_PC,bl);
|
||||
int fixed = skill_get_fixed_cast(skill_id, skill_lv), fixcast_r = 0, varcast_r = 0, i = 0;
|
||||
int fixed = skill_get_fixed_cast(skill_id, skill_lv);
|
||||
short fixcast_r = 0;
|
||||
uint8 i = 0, flag = skill_get_castnodex(skill_id, skill_lv);
|
||||
|
||||
#define FIXEDCASTRATE2(val) ( FIXEDCASTRATE(fixcast_r,(val)) )
|
||||
|
||||
nullpo_ret(bl);
|
||||
|
||||
if( time < 0 )
|
||||
return 0;
|
||||
@ -15530,97 +15543,116 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
|
||||
if( bl->type == BL_MOB )
|
||||
return (int)time;
|
||||
|
||||
if( fixed == 0 ){
|
||||
fixed = (int)time * 20 / 100; // fixed time
|
||||
time = time * 80 / 100; // variable time
|
||||
}else if( fixed < 0 ) // no fixed cast time
|
||||
if( fixed < 0 || battle_config.default_fixed_castrate == 0 ) // no fixed cast time
|
||||
fixed = 0;
|
||||
else if( fixed == 0 ) {
|
||||
fixed = (int)time * battle_config.default_fixed_castrate / 100; // fixed time
|
||||
time = time * (100 - battle_config.default_fixed_castrate) / 100; // variable time
|
||||
}
|
||||
|
||||
// Additive Variable Cast bonus first
|
||||
if (sd && !(flag&4)) { // item bonus
|
||||
time += sd->bonus.add_varcast; // bonus bVariableCast
|
||||
|
||||
for (i = 0; i < ARRAYLENGTH(sd->skillvarcast) && sd->skillvarcast[i].id; i++)
|
||||
if( sd->skillvarcast[i].id == skill_id ){ // bonus2 bSkillVariableCast
|
||||
time += sd->skillvarcast[i].val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*if (sc && sc->count && !(flag&2)) { // status change
|
||||
// -NONE YET-
|
||||
// if (sc->data[????])
|
||||
// bonus += sc->data[????]->val?;
|
||||
}*/
|
||||
|
||||
// Adjusted by item bonuses
|
||||
if (sd && !(flag&4)) {
|
||||
// Additive values
|
||||
fixed += sd->bonus.add_fixcast; // bonus bFixedCast
|
||||
|
||||
if(sd && !(skill_get_castnodex(skill_id, skill_lv)&4) ){ // Increases/Decreases fixed/variable cast time of a skill by item/card bonuses.
|
||||
if( sd->bonus.varcastrate < 0 )
|
||||
VARCAST_REDUCTION(sd->bonus.varcastrate);
|
||||
if( sd->bonus.add_varcast != 0 ) // bonus bVariableCast
|
||||
time += sd->bonus.add_varcast;
|
||||
if( sd->bonus.add_fixcast != 0 ) // bonus bFixedCast
|
||||
fixed += sd->bonus.add_fixcast;
|
||||
for (i = 0; i < ARRAYLENGTH(sd->skillfixcast) && sd->skillfixcast[i].id; i++)
|
||||
if (sd->skillfixcast[i].id == skill_id){ // bonus2 bSkillFixedCast
|
||||
fixed += sd->skillfixcast[i].val;
|
||||
break;
|
||||
}
|
||||
for( i = 0; i < ARRAYLENGTH(sd->skillvarcast) && sd->skillvarcast[i].id; i++ )
|
||||
if( sd->skillvarcast[i].id == skill_id ){ // bonus2 bSkillVariableCast
|
||||
time += sd->skillvarcast[i].val;
|
||||
break;
|
||||
}
|
||||
for( i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++ )
|
||||
if( sd->skillcast[i].id == skill_id ){ // bonus2 bVariableCastrate
|
||||
VARCAST_REDUCTION(sd->skillcast[i].val);
|
||||
|
||||
// Multipicative values
|
||||
if (sd->bonus.varcastrate != 0)
|
||||
VARCAST_REDUCTION(sd->bonus.varcastrate); // bonus bVariableCastrate
|
||||
|
||||
if (sd->bonus.fixcastrate != 0)
|
||||
FIXEDCASTRATE2(sd->bonus.fixcastrate); // bonus bFixedCastrate
|
||||
|
||||
for( i = 0; i < ARRAYLENGTH(sd->skillcastrate) && sd->skillcastrate[i].id; i++ )
|
||||
if( sd->skillcastrate[i].id == skill_id ){ // bonus2 bVariableCastrate
|
||||
VARCAST_REDUCTION(sd->skillcastrate[i].val);
|
||||
break;
|
||||
}
|
||||
for( i = 0; i < ARRAYLENGTH(sd->skillfixcastrate) && sd->skillfixcastrate[i].id; i++ )
|
||||
if( sd->skillfixcastrate[i].id == skill_id ){ // bonus2 bFixedCastrate
|
||||
fixcast_r = sd->skillfixcastrate[i].val;
|
||||
FIXEDCASTRATE2(sd->skillfixcastrate[i].val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc && sc->count && !(skill_get_castnodex(skill_id, skill_lv)&2) ) {
|
||||
// All variable cast additive bonuses must come first
|
||||
// Adjusted by active statuses
|
||||
if (sc && sc->count && !(flag&2) ) {
|
||||
// Multiplicative Variable CastTime values
|
||||
if (sc->data[SC_SLOWCAST])
|
||||
VARCAST_REDUCTION(-sc->data[SC_SLOWCAST]->val2);
|
||||
if( sc->data[SC__LAZINESS] )
|
||||
VARCAST_REDUCTION(-sc->data[SC__LAZINESS]->val2);
|
||||
VARCAST_REDUCTION(sc->data[SC_SLOWCAST]->val2);
|
||||
if (sc->data[SC__LAZINESS])
|
||||
VARCAST_REDUCTION(sc->data[SC__LAZINESS]->val2);
|
||||
|
||||
// Variable cast reduction bonuses
|
||||
if (sc->data[SC_SUFFRAGIUM]) {
|
||||
VARCAST_REDUCTION(sc->data[SC_SUFFRAGIUM]->val2);
|
||||
VARCAST_REDUCTION(-sc->data[SC_SUFFRAGIUM]->val2);
|
||||
status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER);
|
||||
}
|
||||
if (sc->data[SC_MEMORIZE]) {
|
||||
VARCAST_REDUCTION(50);
|
||||
VARCAST_REDUCTION(-50);
|
||||
if ((--sc->data[SC_MEMORIZE]->val2) <= 0)
|
||||
status_change_end(bl, SC_MEMORIZE, INVALID_TIMER);
|
||||
}
|
||||
if (sc->data[SC_POEMBRAGI])
|
||||
VARCAST_REDUCTION(sc->data[SC_POEMBRAGI]->val2);
|
||||
VARCAST_REDUCTION(-sc->data[SC_POEMBRAGI]->val2);
|
||||
if (sc->data[SC_IZAYOI])
|
||||
VARCAST_REDUCTION(50);
|
||||
VARCAST_REDUCTION(-50);
|
||||
if (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3 && (skill_get_ele(skill_id, skill_lv) == ELE_WATER))
|
||||
VARCAST_REDUCTION(30); //Reduces 30% Variable Cast Time of Water spells.
|
||||
if( sc->data[SC_TELEKINESIS_INTENSE] )
|
||||
VARCAST_REDUCTION(sc->data[SC_TELEKINESIS_INTENSE]->val2);
|
||||
// Fixed cast reduction bonuses
|
||||
if( sc->data[SC_SECRAMENT] )
|
||||
fixcast_r = max(fixcast_r, sc->data[SC_SECRAMENT]->val2);
|
||||
if( sd && ( skill_lv = pc_checkskill(sd, WL_RADIUS) ) && skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP )
|
||||
fixcast_r = max(fixcast_r, 5 + skill_lv * 5);
|
||||
// Fixed cast non percentage bonuses
|
||||
if( sc->data[SC_MANDRAGORA] )
|
||||
fixed += sc->data[SC_MANDRAGORA]->val1 * 1000 / 2;
|
||||
if( sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION] || sc->data[SC_WILD_STORM_OPTION] )
|
||||
fixed -= 1000;
|
||||
VARCAST_REDUCTION(-30); //Reduces 30% Variable Cast Time of Water spells.
|
||||
if (sc->data[SC_TELEKINESIS_INTENSE])
|
||||
VARCAST_REDUCTION(-sc->data[SC_TELEKINESIS_INTENSE]->val2);
|
||||
|
||||
// Multiplicative Fixed CastTime values
|
||||
if (sc->data[SC_SECRAMENT])
|
||||
FIXEDCASTRATE2(-sc->data[SC_SECRAMENT]->val2);
|
||||
if (sd && (skill_lv = pc_checkskill(sd, WL_RADIUS) ) && skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP)
|
||||
FIXEDCASTRATE2(-(5 + skill_lv * 5));
|
||||
if (sc->data[SC_DANCEWITHWUG])
|
||||
fixed -= fixed * sc->data[SC_DANCEWITHWUG]->val4 / 100;
|
||||
if( sc->data[SC_HEAT_BARREL] )
|
||||
fixcast_r = max(fixcast_r, sc->data[SC_HEAT_BARREL]->val2);
|
||||
FIXEDCASTRATE2(-sc->data[SC_DANCEWITHWUG]->val4);
|
||||
if (sc->data[SC_HEAT_BARREL])
|
||||
FIXEDCASTRATE2(-sc->data[SC_HEAT_BARREL]->val2);
|
||||
|
||||
// Additive Fixed CastTime values
|
||||
if (sc->data[SC_MANDRAGORA])
|
||||
fixed += sc->data[SC_MANDRAGORA]->val1 * 1000 / 2;
|
||||
|
||||
if (sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION] || sc->data[SC_WILD_STORM_OPTION])
|
||||
fixed -= 1000;
|
||||
if (sc->data[SC_IZAYOI])
|
||||
fixed = 0;
|
||||
}
|
||||
|
||||
if( sd && !(skill_get_castnodex(skill_id, skill_lv)&4) ){
|
||||
VARCAST_REDUCTION( max(sd->bonus.varcastrate, 0) + max(i, 0) );
|
||||
fixcast_r = max(fixcast_r, sd->bonus.fixcastrate) + min(sd->bonus.fixcastrate,0);
|
||||
}
|
||||
// Apply Variable CastTime calculation by INT & DEX
|
||||
if (!(flag&1))
|
||||
time = time * (1 - sqrt(((float)(status_get_dex(bl)*2 + status_get_int(bl)) / battle_config.vcast_stat_scale)));
|
||||
|
||||
if( varcast_r < 0 ) // now compute overall factors
|
||||
time = time * (1 - (float)varcast_r / 100);
|
||||
if( !(skill_get_castnodex(skill_id, skill_lv)&1) )// reduction from status point
|
||||
time = (1 - sqrt( ((float)(status_get_dex(bl)*2 + status_get_int(bl)) / battle_config.vcast_stat_scale) )) * time;
|
||||
// underflow checking/capping
|
||||
time = max(time, 0) + (1 - (float)min(fixcast_r, 100) / 100) * max(fixed,0);
|
||||
// Apply Fixed CastTime rate
|
||||
if (fixed != 0 && fixcast_r != 0)
|
||||
fixed = (int)(fixed * (1 + fixcast_r * 0.01));
|
||||
|
||||
return (int)time;
|
||||
#undef FIXEDCASTRATE2
|
||||
|
||||
return (int)max(time + fixed, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2939,7 +2939,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
|
||||
+ sizeof(sd->skillheal)
|
||||
+ sizeof(sd->skillheal2)
|
||||
+ sizeof(sd->skillblown)
|
||||
+ sizeof(sd->skillcast)
|
||||
+ sizeof(sd->skillcastrate)
|
||||
+ sizeof(sd->skillcooldown)
|
||||
+ sizeof(sd->skillfixcast)
|
||||
+ sizeof(sd->skillvarcast)
|
||||
|
Loading…
x
Reference in New Issue
Block a user